mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-06-04 14:10:01 +00:00
arm: update Android common kernel
Update ACK to 5.10 and remove the 5.4 recipe Change-Id: I7a0cc0bc95d02bed965530d36aedaf544045fee4 Signed-off-by: Anders Dellien <anders.dellien@arm.com> Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com> Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
committed by
Jon Mason
parent
2f5216c45f
commit
7612faf780
@@ -30,7 +30,7 @@ PREFERRED_PROVIDER_virtual/trusted-firmware-a ?= "trusted-firmware-a"
|
||||
PREFERRED_VERSION_trusted-firmware-a ?= "2.5%"
|
||||
|
||||
PREFERRED_PROVIDER_virtual/kernel ?= "linux-arm64-ack"
|
||||
PREFERRED_VERSION_linux-arm64-ack ?= "5.4"
|
||||
PREFERRED_VERSION_linux-arm64-ack ?= "5.10"
|
||||
|
||||
# Cannot use the default zImage on arm64
|
||||
KERNEL_IMAGETYPE = "Image"
|
||||
|
||||
@@ -79,19 +79,12 @@ SRC_URI_append_tc0 = " \
|
||||
file://defconfig \
|
||||
file://0001-drm-Add-component-aware-simple-encoder.patch \
|
||||
file://0002-drm-arm-komeda-add-RENDER-capability-to-the-device-n.patch \
|
||||
file://0003-mailbox-arm_mhuv2-add-device-tree-binding-documentat.patch \
|
||||
file://0004-mailbox-arm_mhuv2-add-arm-mhuv2-driver.patch \
|
||||
file://0005-mailbox-arm_mhuv2-add-doorbell-transport-protocol-op.patch \
|
||||
file://0006-mailbox-arm_mhuv2-add-multi-word-transport-protocol-.patch \
|
||||
file://0007-firmware-arm_scmi-Add-fast_switch_possible-api.patch \
|
||||
file://0008-cpufreq-arm_scmi-Set-fast_switch_possible-conditiona.patch \
|
||||
file://0009-driver-firmware-Initial-version-of-ffa-driver-based-.patch \
|
||||
file://0010-tee-add-support-for-session-s-client-UUID-generation.patch \
|
||||
file://0011-tee-optee-Add-support-for-session-login-client-UUID-.patch \
|
||||
file://0012-driver-optee-Support-for-ffa-transport.patch \
|
||||
file://0013-tee-optee-fix-mem-handle-removal-in-ffa_shm_unregist.patch \
|
||||
file://0014-arm64-Add-support-for-asymmetric-AArch32-EL0-configu.patch \
|
||||
file://0015-arm64-smp-Prevent-hotplugging-the-last-AArch32-able-.patch \
|
||||
file://0003-Adapt-ION-interface-to-match-Android.patch \
|
||||
file://0004-dt-bindings-mailbox-arm-mhuv2-Add-bindings.patch \
|
||||
file://0005-mailbox-arm_mhuv2-Add-driver.patch \
|
||||
file://0006-mailbox-arm_mhuv2-Fix-sparse-warnings.patch \
|
||||
file://0007-mailbox-arm_mhuv2-make-remove-callback-return-void.patch \
|
||||
file://0008-mailbox-arm_mhuv2-Skip-calling-kfree-with-invalid-po.patch \
|
||||
"
|
||||
|
||||
#
|
||||
|
||||
+11
-10
@@ -1,7 +1,7 @@
|
||||
From 7863ac1515009547bae3a66e0808e72b3bdcf8c8 Mon Sep 17 00:00:00 2001
|
||||
From 9080fb7fc011445d4d6ee164d02d86ff6df0822a Mon Sep 17 00:00:00 2001
|
||||
From: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Date: Tue, 16 Jun 2020 12:39:06 +0000
|
||||
Subject: [PATCH 1/9] drm: Add component-aware simple encoder
|
||||
Subject: [PATCH 01/10] drm: Add component-aware simple encoder
|
||||
|
||||
This is a simple DRM encoder that gets its connector timings information
|
||||
from a OF subnode in the device tree and exposes that as a "discovered"
|
||||
@@ -12,6 +12,7 @@ and the display output is configured outside the kernel.
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.linaro.org/landing-teams/working/arm/kernel-release.git/commit/?h=latest-armlt&id=15283f7be4b1e586702551e85b4caf06531ac2fc]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
drivers/gpu/drm/Kconfig | 11 +
|
||||
drivers/gpu/drm/Makefile | 2 +
|
||||
@@ -20,10 +21,10 @@ Upstream-Status: Backport [https://git.linaro.org/landing-teams/working/arm/kern
|
||||
create mode 100644 drivers/gpu/drm/drm_virtual_encoder.c
|
||||
|
||||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
|
||||
index e67c194c2aca..c95279cd9341 100644
|
||||
index ca868271f4c4..6ae8ba3ca7b3 100644
|
||||
--- a/drivers/gpu/drm/Kconfig
|
||||
+++ b/drivers/gpu/drm/Kconfig
|
||||
@@ -265,6 +265,17 @@ config DRM_VKMS
|
||||
@@ -300,6 +300,17 @@ config DRM_VKMS
|
||||
|
||||
If M is selected the module will be called vkms.
|
||||
|
||||
@@ -38,14 +39,14 @@ index e67c194c2aca..c95279cd9341 100644
|
||||
+ drm_vencoder.
|
||||
+
|
||||
+
|
||||
config DRM_ATI_PCIGART
|
||||
bool
|
||||
source "drivers/gpu/drm/exynos/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/rockchip/Kconfig"
|
||||
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
|
||||
index 82ff826b33cc..d2ab6fc64932 100644
|
||||
index 81569009f884..a3429152c613 100644
|
||||
--- a/drivers/gpu/drm/Makefile
|
||||
+++ b/drivers/gpu/drm/Makefile
|
||||
@@ -53,6 +53,8 @@ drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
|
||||
@@ -56,6 +56,8 @@ drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
|
||||
|
||||
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
||||
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
|
||||
@@ -56,7 +57,7 @@ index 82ff826b33cc..d2ab6fc64932 100644
|
||||
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
|
||||
diff --git a/drivers/gpu/drm/drm_virtual_encoder.c b/drivers/gpu/drm/drm_virtual_encoder.c
|
||||
new file mode 100644
|
||||
index 000000000000..4fd2098df286
|
||||
index 000000000000..2f65c6b47d00
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpu/drm/drm_virtual_encoder.c
|
||||
@@ -0,0 +1,299 @@
|
||||
@@ -250,7 +251,7 @@ index 000000000000..4fd2098df286
|
||||
+ crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
|
||||
+ bridge = of_drm_find_bridge(dev->of_node);
|
||||
+ if (bridge) {
|
||||
+ ret = drm_bridge_attach(encoder, bridge, NULL);
|
||||
+ ret = drm_bridge_attach(encoder, bridge, NULL, 0);
|
||||
+ if (ret) {
|
||||
+ DRM_ERROR("Failed to initialize bridge\n");
|
||||
+ return ret;
|
||||
+7
-6
@@ -1,7 +1,7 @@
|
||||
From 190c6354a0d80c31214550553cfbee25571e1942 Mon Sep 17 00:00:00 2001
|
||||
From 7a0e6189c7b104a679bc7b91465425e2de909456 Mon Sep 17 00:00:00 2001
|
||||
From: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Date: Wed, 17 Jun 2020 10:49:26 +0000
|
||||
Subject: [PATCH 2/9] drm: arm: komeda: add RENDER capability to the device
|
||||
Subject: [PATCH 02/10] drm: arm: komeda: add RENDER capability to the device
|
||||
node
|
||||
|
||||
this is required to make this driver work with android framework
|
||||
@@ -9,23 +9,24 @@ this is required to make this driver work with android framework
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
|
||||
Upstream-Status: Inappropriate [Product specific configuration]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
|
||||
index ae274902ff92..238bd8466206 100644
|
||||
index 1f6682032ca4..9d1a1942e673 100644
|
||||
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
|
||||
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
|
||||
@@ -56,7 +56,7 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
|
||||
@@ -59,7 +59,7 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
|
||||
}
|
||||
|
||||
static struct drm_driver komeda_kms_driver = {
|
||||
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
|
||||
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_RENDER,
|
||||
.lastclose = drm_fb_helper_lastclose,
|
||||
.gem_free_object_unlocked = drm_gem_cma_free_object,
|
||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||
DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(komeda_gem_cma_dumb_create),
|
||||
.fops = &komeda_cma_fops,
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
From b98c6070320ad31318a028482f026d6a5eddce5b Mon Sep 17 00:00:00 2001
|
||||
From: Anders Dellien <anders.dellien@arm.com>
|
||||
Date: Fri, 29 Jan 2021 09:44:38 +0000
|
||||
Subject: [PATCH 03/10] Adapt ION interface to match Android
|
||||
|
||||
Change-Id: I62b69cc357868f725170899c862530b8f3069666
|
||||
Signed-off-by: Anders Dellien <anders.dellien@arm.com>
|
||||
|
||||
Upstream-Status: Inappropriate [Product specific configuration]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
include/uapi/linux/ion.h | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h
|
||||
index 371e44662755..7022ea223736 100644
|
||||
--- a/include/uapi/linux/ion.h
|
||||
+++ b/include/uapi/linux/ion.h
|
||||
@@ -24,7 +24,10 @@
|
||||
*/
|
||||
enum ion_heap_type {
|
||||
ION_HEAP_TYPE_SYSTEM = 0,
|
||||
- ION_HEAP_TYPE_DMA = 2,
|
||||
+ ION_HEAP_TYPE_SYSTEM_CONTIG = 1,
|
||||
+ ION_HEAP_TYPE_CARVEOUT = 2,
|
||||
+ ION_HEAP_TYPE_CHUNK = 3,
|
||||
+ ION_HEAP_TYPE_DMA = 4,
|
||||
/* reserved range for future standard heap types */
|
||||
ION_HEAP_TYPE_CUSTOM = 16,
|
||||
ION_HEAP_TYPE_MAX = 31,
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
From 4cafac5cd54c7f5069a4d6e17bdbd8f94cd5fa0b Mon Sep 17 00:00:00 2001
|
||||
From: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Date: Tue, 17 Nov 2020 15:32:05 +0530
|
||||
Subject: [PATCH 04/10] dt-bindings: mailbox : arm,mhuv2: Add bindings
|
||||
|
||||
This patch adds device tree binding for ARM Message Handling Unit (MHU)
|
||||
controller version 2.
|
||||
|
||||
Based on earlier work by Morten Borup Petersen.
|
||||
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Co-developed-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
|
||||
Upstream-Status: Backport [https://lkml.org/lkml/2020/11/17/234]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
.../bindings/mailbox/arm,mhuv2.yaml | 209 ++++++++++++++++++
|
||||
1 file changed, 209 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..6608545ea66f
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml
|
||||
@@ -0,0 +1,209 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/mailbox/arm,mhuv2.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: ARM MHUv2 Mailbox Controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
+ - Viresh Kumar <viresh.kumar@linaro.org>
|
||||
+
|
||||
+description: |
|
||||
+ The Arm Message Handling Unit (MHU) Version 2 is a mailbox controller that has
|
||||
+ between 1 and 124 channel windows (each 32-bit wide) to provide unidirectional
|
||||
+ communication with remote processor(s), where the number of channel windows
|
||||
+ are implementation dependent.
|
||||
+
|
||||
+ Given the unidirectional nature of the controller, an MHUv2 mailbox may only
|
||||
+ be written to or read from. If a pair of MHU controllers is implemented
|
||||
+ between two processing elements to provide bidirectional communication, these
|
||||
+ must be specified as two separate mailboxes.
|
||||
+
|
||||
+ If the interrupts property is present in device tree node, then its treated as
|
||||
+ a "receiver" mailbox, otherwise a "sender".
|
||||
+
|
||||
+ An MHU controller must be specified along with the supported transport
|
||||
+ protocols. The transport protocols determine the method of data transmission
|
||||
+ as well as the number of provided mailbox channels.
|
||||
+
|
||||
+ Following are the possible transport protocols.
|
||||
+
|
||||
+ - Data-transfer: Each transfer is made of one or more words, using one or more
|
||||
+ channel windows.
|
||||
+
|
||||
+ - Doorbell: Each transfer is made up of single bit flag, using any one of the
|
||||
+ bits in a channel window. A channel window can support up to 32 doorbells
|
||||
+ and the entire window shall be used in doorbell protocol. Optionally, data
|
||||
+ may be transmitted through a shared memory region, wherein the MHU is used
|
||||
+ strictly as an interrupt generation mechanism but that is out of the scope
|
||||
+ of these bindings.
|
||||
+
|
||||
+# We need a select here so we don't match all nodes with 'arm,primecell'
|
||||
+select:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ enum:
|
||||
+ - arm,mhuv2-tx
|
||||
+ - arm,mhuv2-rx
|
||||
+ required:
|
||||
+ - compatible
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - description: Sender mode
|
||||
+ items:
|
||||
+ - const: arm,mhuv2-tx
|
||||
+ - const: arm,primecell
|
||||
+
|
||||
+ - description: Receiver-mode
|
||||
+ items:
|
||||
+ - const: arm,mhuv2-rx
|
||||
+ - const: arm,primecell
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ description: |
|
||||
+ The MHUv2 controller always implements an interrupt in the "receiver"
|
||||
+ mode, while the interrupt in the "sender" mode was not available in the
|
||||
+ version MHUv2.0, but the later versions do have it.
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clock-names:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ arm,mhuv2-protocols:
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
+ description: |
|
||||
+ The MHUv2 controller may contain up to 124 channel windows (each 32-bit
|
||||
+ wide). The hardware and the DT bindings allows any combination of those to
|
||||
+ be used for various transport protocols.
|
||||
+
|
||||
+ This property allows a platform to describe how these channel windows are
|
||||
+ used in various transport protocols. The entries in this property shall be
|
||||
+ present as an array of tuples, where each tuple describes details about
|
||||
+ one of the transport protocol being implemented over some channel
|
||||
+ window(s).
|
||||
+
|
||||
+ The first field of a tuple signifies the transfer protocol, 0 is reserved
|
||||
+ for doorbell protocol, and 1 is reserved for data-transfer protocol.
|
||||
+ Using any other value in the first field of a tuple makes it invalid.
|
||||
+
|
||||
+ The second field of a tuple signifies the number of channel windows where
|
||||
+ the protocol would be used and should be set to a non zero value. For
|
||||
+ doorbell protocol this field signifies the number of 32-bit channel
|
||||
+ windows that implement the doorbell protocol. For data-transfer protocol,
|
||||
+ this field signifies the number of 32-bit channel windows that implement
|
||||
+ the data-transfer protocol.
|
||||
+
|
||||
+ The total number of channel windows specified here shouldn't be more than
|
||||
+ the ones implemented by the platform, though one can specify lesser number
|
||||
+ of windows here than what the platform implements.
|
||||
+
|
||||
+ mhu: mailbox@2b1f0000 {
|
||||
+ ...
|
||||
+
|
||||
+ arm,mhuv2-protocols = <0 2>, <1 1>, <1 5>, <1 7>;
|
||||
+ }
|
||||
+
|
||||
+ The above example defines the protocols of an ARM MHUv2 mailbox
|
||||
+ controller, where a total of 15 channel windows are used. The first two
|
||||
+ windows are used in doorbell protocol (64 doorbells), followed by 1, 5 and
|
||||
+ 7 windows (separately) used in data-transfer protocol.
|
||||
+
|
||||
+ minItems: 1
|
||||
+ maxItems: 124
|
||||
+ items:
|
||||
+ items:
|
||||
+ - enum: [ 0, 1 ]
|
||||
+ - minimum: 0
|
||||
+ maximum: 124
|
||||
+
|
||||
+
|
||||
+ '#mbox-cells':
|
||||
+ description: |
|
||||
+ It is always set to 2. The first argument in the consumers 'mboxes'
|
||||
+ property represents the channel window group, which may be used in
|
||||
+ doorbell, or data-transfer protocol, and the second argument (only
|
||||
+ relevant in doorbell protocol, should be 0 otherwise) represents the
|
||||
+ doorbell number within the 32 bit wide channel window.
|
||||
+
|
||||
+ From the example given above for arm,mhuv2-protocols, here is how a client
|
||||
+ node can reference them.
|
||||
+
|
||||
+ mboxes = <&mhu 0 5>; // Channel Window Group 0, doorbell 5.
|
||||
+ mboxes = <&mhu 1 7>; // Channel Window Group 1, doorbell 7.
|
||||
+ mboxes = <&mhu 2 0>; // Channel Window Group 2, data transfer protocol with 1 window.
|
||||
+ mboxes = <&mhu 3 0>; // Channel Window Group 3, data transfer protocol with 5 windows.
|
||||
+ mboxes = <&mhu 4 0>; // Channel Window Group 4, data transfer protocol with 7 windows.
|
||||
+
|
||||
+ const: 2
|
||||
+
|
||||
+if:
|
||||
+ # Interrupt is compulsory for receiver
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ const: arm,mhuv2-rx
|
||||
+then:
|
||||
+ required:
|
||||
+ - interrupts
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - '#mbox-cells'
|
||||
+ - arm,mhuv2-protocols
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ # Multiple transport protocols implemented by the mailbox controllers
|
||||
+ - |
|
||||
+ soc {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ mhu_tx: mailbox@2b1f0000 {
|
||||
+ #mbox-cells = <2>;
|
||||
+ compatible = "arm,mhuv2-tx", "arm,primecell";
|
||||
+ reg = <0 0x2b1f0000 0 0x1000>;
|
||||
+ clocks = <&clock 0>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ interrupts = <0 45 4>;
|
||||
+ arm,mhuv2-protocols = <1 5>, <1 2>, <1 5>, <1 7>, <0 2>;
|
||||
+ };
|
||||
+
|
||||
+ mhu_rx: mailbox@2b1f1000 {
|
||||
+ #mbox-cells = <2>;
|
||||
+ compatible = "arm,mhuv2-rx", "arm,primecell";
|
||||
+ reg = <0 0x2b1f1000 0 0x1000>;
|
||||
+ clocks = <&clock 0>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ interrupts = <0 46 4>;
|
||||
+ arm,mhuv2-protocols = <1 1>, <1 7>, <0 2>;
|
||||
+ };
|
||||
+
|
||||
+ mhu_client: scb@2e000000 {
|
||||
+ compatible = "fujitsu,mb86s70-scb-1.0";
|
||||
+ reg = <0 0x2e000000 0 0x4000>;
|
||||
+
|
||||
+ mboxes =
|
||||
+ //data-transfer protocol with 5 windows, mhu-tx
|
||||
+ <&mhu_tx 2 0>,
|
||||
+ //data-transfer protocol with 7 windows, mhu-tx
|
||||
+ <&mhu_tx 3 0>,
|
||||
+ //doorbell protocol channel 4, doorbell 27, mhu-tx
|
||||
+ <&mhu_tx 4 27>,
|
||||
+ //data-transfer protocol with 1 window, mhu-rx
|
||||
+ <&mhu_rx 0 0>;
|
||||
+ };
|
||||
+ };
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+1256
File diff suppressed because it is too large
Load Diff
+114
@@ -0,0 +1,114 @@
|
||||
From f082677cb35ea843e749e1c9e5a9b9fba44c5d48 Mon Sep 17 00:00:00 2001
|
||||
From: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Date: Wed, 30 Dec 2020 10:12:04 +0530
|
||||
Subject: [PATCH 06/10] mailbox: arm_mhuv2: Fix sparse warnings
|
||||
|
||||
This patch fixes a bunch of sparse warnings in the newly added arm_mhuv2
|
||||
driver.
|
||||
|
||||
drivers/mailbox/arm_mhuv2.c:506:24: warning: incorrect type in argument 1 (different address spaces)
|
||||
drivers/mailbox/arm_mhuv2.c:506:24: expected void const volatile [noderef] __iomem *addr
|
||||
drivers/mailbox/arm_mhuv2.c:506:24: got unsigned int [usertype] *
|
||||
drivers/mailbox/arm_mhuv2.c:547:42: warning: incorrect type in argument 2 (different address spaces)
|
||||
drivers/mailbox/arm_mhuv2.c:547:42: expected unsigned int [usertype] *reg
|
||||
drivers/mailbox/arm_mhuv2.c:547:42: got unsigned int [noderef] __iomem *
|
||||
drivers/mailbox/arm_mhuv2.c:625:42: warning: incorrect type in argument 2 (different address spaces)
|
||||
drivers/mailbox/arm_mhuv2.c:625:42: expected unsigned int [usertype] *reg
|
||||
drivers/mailbox/arm_mhuv2.c:625:42: got unsigned int [noderef] __iomem *
|
||||
drivers/mailbox/arm_mhuv2.c:972:24: warning: dereference of noderef expression
|
||||
drivers/mailbox/arm_mhuv2.c:973:22: warning: dereference of noderef expression
|
||||
drivers/mailbox/arm_mhuv2.c:993:25: warning: dereference of noderef expression
|
||||
drivers/mailbox/arm_mhuv2.c:1026:24: warning: dereference of noderef expression
|
||||
drivers/mailbox/arm_mhuv2.c:1027:22: warning: dereference of noderef expression
|
||||
drivers/mailbox/arm_mhuv2.c:1048:17: warning: dereference of noderef expression
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
|
||||
Upstream-Status: Backport [https://lkml.org/lkml/2021/2/9/428]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
drivers/mailbox/arm_mhuv2.c | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
|
||||
index 67fb10885bb4..8223c1005254 100644
|
||||
--- a/drivers/mailbox/arm_mhuv2.c
|
||||
+++ b/drivers/mailbox/arm_mhuv2.c
|
||||
@@ -238,19 +238,19 @@ struct mhuv2_mbox_chan_priv {
|
||||
};
|
||||
|
||||
/* Macro for reading a bitfield within a physically mapped packed struct */
|
||||
-#define readl_relaxed_bitfield(_regptr, _field) \
|
||||
+#define readl_relaxed_bitfield(_regptr, _type, _field) \
|
||||
({ \
|
||||
u32 _regval; \
|
||||
_regval = readl_relaxed((_regptr)); \
|
||||
- (*(typeof((_regptr)))(&_regval))._field; \
|
||||
+ (*(_type *)(&_regval))._field; \
|
||||
})
|
||||
|
||||
/* Macro for writing a bitfield within a physically mapped packed struct */
|
||||
-#define writel_relaxed_bitfield(_value, _regptr, _field) \
|
||||
+#define writel_relaxed_bitfield(_value, _regptr, _type, _field) \
|
||||
({ \
|
||||
u32 _regval; \
|
||||
_regval = readl_relaxed(_regptr); \
|
||||
- (*(typeof(_regptr))(&_regval))._field = _value; \
|
||||
+ (*(_type *)(&_regval))._field = _value; \
|
||||
writel_relaxed(_regval, _regptr); \
|
||||
})
|
||||
|
||||
@@ -496,7 +496,7 @@ static const struct mhuv2_protocol_ops mhuv2_data_transfer_ops = {
|
||||
|
||||
/* Interrupt handlers */
|
||||
|
||||
-static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 *reg)
|
||||
+static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg)
|
||||
{
|
||||
struct mbox_chan *chans = mhu->mbox.chans;
|
||||
int channel = 0, i, offset = 0, windows, protocol, ch_wn;
|
||||
@@ -969,8 +969,8 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu,
|
||||
mhu->mbox.ops = &mhuv2_sender_ops;
|
||||
mhu->send = reg;
|
||||
|
||||
- mhu->windows = readl_relaxed_bitfield(&mhu->send->mhu_cfg, num_ch);
|
||||
- mhu->minor = readl_relaxed_bitfield(&mhu->send->aidr, arch_minor_rev);
|
||||
+ mhu->windows = readl_relaxed_bitfield(&mhu->send->mhu_cfg, struct mhu_cfg_t, num_ch);
|
||||
+ mhu->minor = readl_relaxed_bitfield(&mhu->send->aidr, struct aidr_t, arch_minor_rev);
|
||||
|
||||
spin_lock_init(&mhu->doorbell_pending_lock);
|
||||
|
||||
@@ -990,7 +990,7 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu,
|
||||
mhu->mbox.txdone_poll = false;
|
||||
mhu->irq = adev->irq[0];
|
||||
|
||||
- writel_relaxed_bitfield(1, &mhu->send->int_en, chcomb);
|
||||
+ writel_relaxed_bitfield(1, &mhu->send->int_en, struct int_en_t, chcomb);
|
||||
|
||||
/* Disable all channel interrupts */
|
||||
for (i = 0; i < mhu->windows; i++)
|
||||
@@ -1023,8 +1023,8 @@ static int mhuv2_rx_init(struct amba_device *adev, struct mhuv2 *mhu,
|
||||
mhu->mbox.ops = &mhuv2_receiver_ops;
|
||||
mhu->recv = reg;
|
||||
|
||||
- mhu->windows = readl_relaxed_bitfield(&mhu->recv->mhu_cfg, num_ch);
|
||||
- mhu->minor = readl_relaxed_bitfield(&mhu->recv->aidr, arch_minor_rev);
|
||||
+ mhu->windows = readl_relaxed_bitfield(&mhu->recv->mhu_cfg, struct mhu_cfg_t, num_ch);
|
||||
+ mhu->minor = readl_relaxed_bitfield(&mhu->recv->aidr, struct aidr_t, arch_minor_rev);
|
||||
|
||||
mhu->irq = adev->irq[0];
|
||||
if (!mhu->irq) {
|
||||
@@ -1045,7 +1045,7 @@ static int mhuv2_rx_init(struct amba_device *adev, struct mhuv2 *mhu,
|
||||
writel_relaxed(0xFFFFFFFF, &mhu->recv->ch_wn[i].mask_set);
|
||||
|
||||
if (mhu->minor)
|
||||
- writel_relaxed_bitfield(1, &mhu->recv->int_en, chcomb);
|
||||
+ writel_relaxed_bitfield(1, &mhu->recv->int_en, struct int_en_t, chcomb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
From a0e07a4d72dfe8892ebcfb29c0a1007c35eebd66 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
|
||||
Date: Tue, 2 Feb 2021 20:43:08 +0100
|
||||
Subject: [PATCH 07/10] mailbox: arm_mhuv2: make remove callback return void
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
My build tests failed to catch that amba driver that would have needed
|
||||
adaption in commit 3fd269e74f2f ("amba: Make the remove callback return
|
||||
void"). Change the remove function to make the driver build again.
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Fixes: 3fd269e74f2f ("amba: Make the remove callback return void")
|
||||
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
|
||||
Upstream-Status: Backport [https://lkml.org/lkml/2021/2/2/1525]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
drivers/mailbox/arm_mhuv2.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
|
||||
index 8223c1005254..cdfb1939fabf 100644
|
||||
--- a/drivers/mailbox/arm_mhuv2.c
|
||||
+++ b/drivers/mailbox/arm_mhuv2.c
|
||||
@@ -1095,14 +1095,12 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int mhuv2_remove(struct amba_device *adev)
|
||||
+static void mhuv2_remove(struct amba_device *adev)
|
||||
{
|
||||
struct mhuv2 *mhu = amba_get_drvdata(adev);
|
||||
|
||||
if (mhu->frame == SENDER_FRAME)
|
||||
writel_relaxed(0x0, &mhu->send->access_request);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static struct amba_id mhuv2_ids[] = {
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
From c55091b7738802c503b1ce4276ee85d601604506 Mon Sep 17 00:00:00 2001
|
||||
From: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Date: Mon, 22 Feb 2021 12:48:06 +0530
|
||||
Subject: [PATCH 08/10] mailbox: arm_mhuv2: Skip calling kfree() with invalid
|
||||
pointer
|
||||
|
||||
It is possible that 'data' passed to kfree() is set to a error value
|
||||
instead of allocated space. Make sure it doesn't get called with invalid
|
||||
pointer.
|
||||
|
||||
Fixes: 5a6338cce9f4 ("mailbox: arm_mhuv2: Add driver")
|
||||
Cc: v5.11 <stable@vger.kernel.org> # v5.11
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
|
||||
Upstream-Status: Backport [https://lkml.org/lkml/2021/2/22/57]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
drivers/mailbox/arm_mhuv2.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
|
||||
index cdfb1939fabf..d997f8ebfa98 100644
|
||||
--- a/drivers/mailbox/arm_mhuv2.c
|
||||
+++ b/drivers/mailbox/arm_mhuv2.c
|
||||
@@ -699,7 +699,9 @@ static irqreturn_t mhuv2_receiver_interrupt(int irq, void *arg)
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
- kfree(data);
|
||||
+ if (!IS_ERR(data))
|
||||
+ kfree(data);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
+31
-56
@@ -2,7 +2,6 @@ CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_ASYMMETRIC_AARCH32=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
@@ -67,7 +66,6 @@ CONFIG_ARCH_ZYNQMP=y
|
||||
CONFIG_ARM64_VA_BITS_48=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_XEN=y
|
||||
@@ -86,7 +84,6 @@ CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_ARM_PSCI_CPUIDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
@@ -113,10 +110,10 @@ CONFIG_IMX_SCU_PD=y
|
||||
CONFIG_ACPI=y
|
||||
CONFIG_ACPI_APEI=y
|
||||
CONFIG_ACPI_APEI_GHES=y
|
||||
CONFIG_ACPI_APEI_PCIEAER=y
|
||||
CONFIG_ACPI_APEI_MEMORY_FAILURE=y
|
||||
CONFIG_ACPI_APEI_EINJ=y
|
||||
CONFIG_VIRTUALIZATION=y
|
||||
CONFIG_KVM=y
|
||||
CONFIG_ARM64_CRYPTO=y
|
||||
CONFIG_CRYPTO_SHA1_ARM64_CE=y
|
||||
CONFIG_CRYPTO_SHA2_ARM64_CE=y
|
||||
@@ -242,7 +239,6 @@ CONFIG_QRTR_TUN=m
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BT=m
|
||||
CONFIG_BT_HIDP=m
|
||||
# CONFIG_BT_HS is not set
|
||||
# CONFIG_BT_LE is not set
|
||||
CONFIG_BT_LEDS=y
|
||||
# CONFIG_BT_DEBUGFS is not set
|
||||
@@ -278,7 +274,6 @@ CONFIG_PCIE_QCOM=y
|
||||
CONFIG_PCIE_ARMADA_8K=y
|
||||
CONFIG_PCIE_KIRIN=y
|
||||
CONFIG_PCIE_HISI_STB=y
|
||||
CONFIG_PCIE_TEGRA194=m
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_FW_LOADER_USER_HELPER=y
|
||||
@@ -287,12 +282,12 @@ CONFIG_HISILICON_LPC=y
|
||||
CONFIG_SIMPLE_PM_BUS=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_PHRAM=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_MTD_NAND_DENALI_DT=y
|
||||
CONFIG_MTD_NAND_MARVELL=y
|
||||
CONFIG_MTD_NAND_QCOM=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_SPI_CADENCE_QUADSPI=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
@@ -367,14 +362,14 @@ CONFIG_SMSC911X=y
|
||||
CONFIG_SNI_AVE=y
|
||||
CONFIG_SNI_NETSEC=y
|
||||
CONFIG_STMMAC_ETH=m
|
||||
CONFIG_MDIO_BUS_MUX_MMIOREG=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_MESON_GXL_PHY=m
|
||||
CONFIG_MARVELL_PHY=m
|
||||
CONFIG_MARVELL_10G_PHY=m
|
||||
CONFIG_MESON_GXL_PHY=m
|
||||
CONFIG_MICREL_PHY=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_REALTEK_PHY=m
|
||||
CONFIG_ROCKCHIP_PHY=y
|
||||
CONFIG_MDIO_BUS_MUX_MMIOREG=y
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
@@ -403,7 +398,6 @@ CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_ADC=m
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
CONFIG_KEYBOARD_SNVS_PWRKEY=m
|
||||
CONFIG_KEYBOARD_CROS_EC=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
|
||||
CONFIG_INPUT_MISC=y
|
||||
@@ -470,11 +464,11 @@ CONFIG_I2C_SH_MOBILE=y
|
||||
CONFIG_I2C_TEGRA=y
|
||||
CONFIG_I2C_UNIPHIER_F=y
|
||||
CONFIG_I2C_RCAR=y
|
||||
CONFIG_I2C_CROS_EC_TUNNEL=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_ARMADA_3700=y
|
||||
CONFIG_SPI_BCM2835=m
|
||||
CONFIG_SPI_BCM2835AUX=m
|
||||
CONFIG_SPI_CADENCE_QUADSPI=y
|
||||
CONFIG_SPI_NXP_FLEXSPI=y
|
||||
CONFIG_SPI_IMX=m
|
||||
CONFIG_SPI_MESON_SPICC=m
|
||||
@@ -498,16 +492,16 @@ CONFIG_PINCTRL_IMX8MM=y
|
||||
CONFIG_PINCTRL_IMX8MN=y
|
||||
CONFIG_PINCTRL_IMX8MQ=y
|
||||
CONFIG_PINCTRL_IMX8QXP=y
|
||||
CONFIG_PINCTRL_IPQ8074=y
|
||||
CONFIG_PINCTRL_MSM8916=y
|
||||
CONFIG_PINCTRL_MSM8994=y
|
||||
CONFIG_PINCTRL_MSM8996=y
|
||||
CONFIG_PINCTRL_MSM8998=y
|
||||
CONFIG_PINCTRL_QCS404=y
|
||||
CONFIG_PINCTRL_QDF2XXX=y
|
||||
CONFIG_PINCTRL_IPQ8074=m
|
||||
CONFIG_PINCTRL_MSM8916=m
|
||||
CONFIG_PINCTRL_MSM8994=m
|
||||
CONFIG_PINCTRL_MSM8996=m
|
||||
CONFIG_PINCTRL_MSM8998=m
|
||||
CONFIG_PINCTRL_QCS404=m
|
||||
CONFIG_PINCTRL_QDF2XXX=m
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_PINCTRL_SDM845=y
|
||||
CONFIG_PINCTRL_SM8150=y
|
||||
CONFIG_PINCTRL_SDM845=m
|
||||
CONFIG_PINCTRL_SM8150=m
|
||||
CONFIG_GPIO_ALTERA=m
|
||||
CONFIG_GPIO_DWAPB=y
|
||||
CONFIG_GPIO_MB86S7X=y
|
||||
@@ -520,14 +514,13 @@ CONFIG_GPIO_MAX732X=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_GPIO_PCA953X_IRQ=y
|
||||
CONFIG_GPIO_MAX77620=y
|
||||
CONFIG_POWER_AVS=y
|
||||
CONFIG_ROCKCHIP_IODOMAIN=y
|
||||
CONFIG_POWER_RESET_MSM=y
|
||||
CONFIG_POWER_RESET_XGENE=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_SYSCON_REBOOT_MODE=y
|
||||
CONFIG_BATTERY_SBS=m
|
||||
CONFIG_BATTERY_BQ27XXX=y
|
||||
CONFIG_SENSORS_ARM_SCMI=y
|
||||
CONFIG_SENSORS_ARM_SCPI=y
|
||||
CONFIG_SENSORS_LM90=m
|
||||
CONFIG_SENSORS_PWM_FAN=m
|
||||
@@ -586,7 +579,7 @@ CONFIG_REGULATOR_MAX77620=y
|
||||
CONFIG_REGULATOR_MAX8973=y
|
||||
CONFIG_REGULATOR_PFUZE100=y
|
||||
CONFIG_REGULATOR_PWM=y
|
||||
CONFIG_REGULATOR_QCOM_RPMH=y
|
||||
CONFIG_REGULATOR_QCOM_RPMH=m
|
||||
CONFIG_REGULATOR_QCOM_SMD_RPM=y
|
||||
CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
CONFIG_REGULATOR_RK808=y
|
||||
@@ -598,11 +591,7 @@ CONFIG_RC_DEVICES=y
|
||||
CONFIG_IR_MESON=m
|
||||
CONFIG_IR_SUNXI=m
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_CONTROLLER=y
|
||||
CONFIG_VIDEO_V4L2_SUBDEV_API=y
|
||||
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
|
||||
# CONFIG_DVB_NET is not set
|
||||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=m
|
||||
@@ -614,7 +603,6 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
|
||||
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
|
||||
CONFIG_VIDEO_RENESAS_FCP=m
|
||||
CONFIG_VIDEO_RENESAS_VSP1=m
|
||||
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
|
||||
CONFIG_DRM_I2C_CH7006=m
|
||||
@@ -657,7 +645,6 @@ CONFIG_DRM_PANFROST=m
|
||||
CONFIG_DRM_LEGACY=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
CONFIG_FB_EFI=y
|
||||
CONFIG_BACKLIGHT_GENERIC=m
|
||||
CONFIG_BACKLIGHT_PWM=m
|
||||
CONFIG_BACKLIGHT_LP855X=m
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
@@ -699,7 +686,6 @@ CONFIG_HID_REDRAGON=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MONTEREY=y
|
||||
CONFIG_I2C_HID=m
|
||||
CONFIG_USB_CONN_GPIO=m
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_OTG=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
@@ -775,7 +761,6 @@ CONFIG_RTC_DRV_RX8581=m
|
||||
CONFIG_RTC_DRV_S5M=y
|
||||
CONFIG_RTC_DRV_DS3232=y
|
||||
CONFIG_RTC_DRV_EFI=y
|
||||
CONFIG_RTC_DRV_CROS_EC=y
|
||||
CONFIG_RTC_DRV_S3C=y
|
||||
CONFIG_RTC_DRV_PL031=y
|
||||
CONFIG_RTC_DRV_SUN6I=y
|
||||
@@ -811,9 +796,7 @@ CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_SYSTEM_HEAP=y
|
||||
CONFIG_MFD_CROS_EC=y
|
||||
CONFIG_CROS_EC_I2C=y
|
||||
CONFIG_CROS_EC_SPI=y
|
||||
CONFIG_ION_CMA_HEAP=y
|
||||
CONFIG_COMMON_CLK_RK808=y
|
||||
CONFIG_COMMON_CLK_SCMI=y
|
||||
CONFIG_COMMON_CLK_SCPI=y
|
||||
@@ -831,7 +814,7 @@ CONFIG_COMMON_CLK_QCOM=y
|
||||
CONFIG_QCOM_A53PLL=y
|
||||
CONFIG_QCOM_CLK_APCS_MSM8916=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_QCOM_CLK_RPMH=y
|
||||
CONFIG_QCOM_CLK_RPMH=m
|
||||
CONFIG_IPQ_GCC_8074=y
|
||||
CONFIG_MSM_GCC_8916=y
|
||||
CONFIG_MSM_GCC_8994=y
|
||||
@@ -862,26 +845,24 @@ CONFIG_RPMSG_QCOM_GLINK_SMEM=m
|
||||
CONFIG_RPMSG_QCOM_SMD=y
|
||||
CONFIG_OWL_PM_DOMAINS=y
|
||||
CONFIG_RASPBERRYPI_POWER=y
|
||||
CONFIG_IMX_SCU_SOC=y
|
||||
CONFIG_QCOM_AOSS_QMP=y
|
||||
CONFIG_QCOM_GENI_SE=y
|
||||
CONFIG_QCOM_GLINK_SSR=m
|
||||
CONFIG_QCOM_RMTFS_MEM=m
|
||||
CONFIG_QCOM_RPMH=y
|
||||
CONFIG_QCOM_RPMHPD=y
|
||||
CONFIG_QCOM_RPMH=m
|
||||
CONFIG_QCOM_RPMHPD=m
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_QCOM_SMP2P=y
|
||||
CONFIG_QCOM_SMSM=y
|
||||
CONFIG_QCOM_SOCINFO=m
|
||||
CONFIG_ARCH_R8A774A1=y
|
||||
CONFIG_ARCH_R8A774C0=y
|
||||
CONFIG_ARCH_R8A7795=y
|
||||
CONFIG_ARCH_R8A77965=y
|
||||
CONFIG_ARCH_R8A77970=y
|
||||
CONFIG_ARCH_R8A77980=y
|
||||
CONFIG_ARCH_R8A77990=y
|
||||
CONFIG_ARCH_R8A77995=y
|
||||
CONFIG_ARCH_R8A77990=y
|
||||
CONFIG_ARCH_R8A77965=y
|
||||
CONFIG_ARCH_R8A77980=y
|
||||
CONFIG_ARCH_R8A77970=y
|
||||
CONFIG_ARCH_R8A774C0=y
|
||||
CONFIG_ARCH_R8A774A1=y
|
||||
CONFIG_ROCKCHIP_IODOMAIN=y
|
||||
CONFIG_ROCKCHIP_PM_DOMAINS=y
|
||||
CONFIG_ARCH_TEGRA_132_SOC=y
|
||||
CONFIG_ARCH_TEGRA_210_SOC=y
|
||||
@@ -891,21 +872,15 @@ CONFIG_ARCH_K3_AM6_SOC=y
|
||||
CONFIG_ARCH_K3_J721E_SOC=y
|
||||
CONFIG_TI_SCI_PM_DOMAINS=y
|
||||
CONFIG_EXTCON_USB_GPIO=y
|
||||
CONFIG_EXTCON_USBC_CROS_EC=y
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_EXYNOS_ADC=y
|
||||
CONFIG_QCOM_SPMI_ADC5=m
|
||||
CONFIG_ROCKCHIP_SARADC=m
|
||||
CONFIG_IIO_CROS_EC_SENSORS_CORE=m
|
||||
CONFIG_IIO_CROS_EC_SENSORS=m
|
||||
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
|
||||
CONFIG_SENSORS_ISL29018=m
|
||||
CONFIG_IIO_CROS_EC_BARO=m
|
||||
CONFIG_MPL3115=m
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_BCM2835=m
|
||||
CONFIG_PWM_CROS_EC=m
|
||||
CONFIG_PWM_MESON=m
|
||||
CONFIG_PWM_RCAR=m
|
||||
CONFIG_PWM_ROCKCHIP=y
|
||||
@@ -937,9 +912,9 @@ CONFIG_PHY_UNIPHIER_USB3=y
|
||||
CONFIG_PHY_TEGRA_XUSB=y
|
||||
CONFIG_ARM_SMMU_V3_PMU=m
|
||||
CONFIG_FSL_IMX8_DDR_PMU=m
|
||||
CONFIG_HISI_PMU=y
|
||||
CONFIG_QCOM_L2_PMU=y
|
||||
CONFIG_QCOM_L3_PMU=y
|
||||
CONFIG_HISI_PMU=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_NVMEM_IMX_OCOTP=y
|
||||
@@ -995,8 +970,8 @@ CONFIG_CRYPTO_DEV_HISI_ZIP=m
|
||||
CONFIG_CMA_SIZE_MBYTES=256
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
From bca81c4c54765565651634b6de5edb6a191577a3 Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Thu, 27 Jun 2019 11:16:22 +0100
|
||||
Subject: [PATCH 3/9] mailbox: arm_mhuv2: add device tree binding documentation
|
||||
|
||||
This patch adds device tree binding for Message Handling Unit
|
||||
controller version 2 from Arm.
|
||||
|
||||
Change-Id: I8c46dd7cd1a48450020c33721ea7cce9f8b8e64f
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc: robh+dt@kernel.org
|
||||
Cc: mark.rutland@arm.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Cc: jassisinghbrar@gmail.com
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
.../devicetree/bindings/mailbox/arm,mhuv2.txt | 101 ++++++++++++++++++
|
||||
1 file changed, 101 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt
|
||||
new file mode 100644
|
||||
index 000000000000..5b8a2ab21ae0
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/mailbox/arm,mhuv2.txt
|
||||
@@ -0,0 +1,101 @@
|
||||
+Arm MHUv2 Mailbox Driver
|
||||
+========================
|
||||
+
|
||||
+The Arm Message-Handling-Unit (MHU) Version 2 is a mailbox controller that has
|
||||
+between 1 and 124 channel windows to provide unidirectional communication with
|
||||
+remote processor(s).
|
||||
+
|
||||
+Given the unidirectional nature of the device, an MHUv2 mailbox may only be
|
||||
+written to or read from. If a pair of MHU devices is implemented between two
|
||||
+processing elements to provide bidirectional communication, these must be
|
||||
+specified as two separate mailboxes.
|
||||
+
|
||||
+If the interrupts property is present in device tree node, then its treated
|
||||
+as a receiver frame, otherwise a sender frame.
|
||||
+
|
||||
+An MHU device must be specified with a transport protocol. The transport
|
||||
+protocol of an MHU device determines the method of data transmission as well as
|
||||
+the number of provided mailboxes.
|
||||
+Following are the possible transport protocol types:
|
||||
+- Single-word: An MHU device implements as many mailboxes as it
|
||||
+ provides channel windows. Data is transmitted through
|
||||
+ the MHU registers.
|
||||
+- Multi-word: An MHU device implements a single mailbox. All channel windows
|
||||
+ will be used during transmission. Data is transmitted through
|
||||
+ the MHU registers.
|
||||
+- Doorbell: An MHU device implements as many mailboxes as there are flag
|
||||
+ bits available in its channel windows. Optionally, data may
|
||||
+ be transmitted through a shared memory region, wherein the MHU
|
||||
+ is used strictly as an interrupt generation mechanism.
|
||||
+
|
||||
+Mailbox Device Node:
|
||||
+====================
|
||||
+
|
||||
+Required properties:
|
||||
+--------------------
|
||||
+- compatible: Shall be "arm,mhuv2" & "arm,primecell"
|
||||
+- reg: Contains the mailbox register address range (base
|
||||
+ address and length)
|
||||
+- #mbox-cells Shall be 1 - the index of the channel needed.
|
||||
+- mhu-protocol Transport protocol of the device. Shall be one of the
|
||||
+ following: "single-word", "multi-word", "doorbell"
|
||||
+
|
||||
+Required properties (receiver frame):
|
||||
+-------------------------------------
|
||||
+- interrupts: Contains the interrupt information for the receiver frame
|
||||
+
|
||||
+Example:
|
||||
+--------
|
||||
+
|
||||
+ mbox_mw_tx: mhu@10000000 {
|
||||
+ compatible = "arm,mhuv2","arm,primecell";
|
||||
+ reg = <0x10000000 0x1000>;
|
||||
+ clocks = <&refclk100mhz>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ #mbox-cells = <1>;
|
||||
+ mhu-protocol = "multi-word";
|
||||
+ };
|
||||
+
|
||||
+ mbox_sw_tx: mhu@10000000 {
|
||||
+ compatible = "arm,mhuv2","arm,primecell";
|
||||
+ reg = <0x11000000 0x1000>;
|
||||
+ clocks = <&refclk100mhz>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ #mbox-cells = <1>;
|
||||
+ mhu-protocol = "single-word";
|
||||
+ };
|
||||
+
|
||||
+ mbox_db_rx: mhu@10000000 {
|
||||
+ compatible = "arm,mhuv2","arm,primecell";
|
||||
+ reg = <0x12000000 0x1000>;
|
||||
+ clocks = <&refclk100mhz>;
|
||||
+ clock-names = "apb_pclk";
|
||||
+ #mbox-cells = <1>;
|
||||
+ interrupts = <0 45 4>;
|
||||
+ interrupt-names = "mhu_rx";
|
||||
+ mhu-protocol = "doorbell";
|
||||
+ };
|
||||
+
|
||||
+ mhu_client: scb@2e000000 {
|
||||
+ compatible = "fujitsu,mb86s70-scb-1.0";
|
||||
+ reg = <0 0x2e000000 0x4000>;
|
||||
+ mboxes =
|
||||
+ // For multi-word frames, client may only instantiate a single
|
||||
+ // mailbox for a mailbox controller
|
||||
+ <&mbox_mw_tx 0>,
|
||||
+
|
||||
+ // For single-word frames, client may instantiate as many
|
||||
+ // mailboxes as there are channel windows in the MHU
|
||||
+ <&mbox_sw_tx 0>,
|
||||
+ <&mbox_sw_tx 1>,
|
||||
+ <&mbox_sw_tx 2>,
|
||||
+ <&mbox_sw_tx 3>,
|
||||
+
|
||||
+ // For doorbell frames, client may instantiate as many mailboxes
|
||||
+ // as there are bits available in the combined number of channel
|
||||
+ // windows ((channel windows * 32) mailboxes)
|
||||
+ <mbox_db_rx 0>,
|
||||
+ <mbox_db_rx 1>,
|
||||
+ ...
|
||||
+ <mbox_db_rx 17>;
|
||||
+ };
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.17.1
|
||||
|
||||
-822
@@ -1,822 +0,0 @@
|
||||
From 364539028799290814a35aa10d32d850486f0b4a Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Thu, 27 Jun 2019 11:17:14 +0100
|
||||
Subject: [PATCH 4/9] mailbox: arm_mhuv2: add arm mhuv2 driver
|
||||
|
||||
This commit adds a driver for the ARM MHUv2 (Message Handling Unit).
|
||||
The driver registers itself as a mailbox controller within the common
|
||||
mailbox framework.
|
||||
|
||||
This commit implements the single-word transport protocol;
|
||||
In single-word mode, the mailbox controller will provide a mailbox for each
|
||||
channel window available in the MHU device.
|
||||
Transmitting and receiving data through the mailbox framework in
|
||||
single-word mode is done through a struct arm_mbox_msg.
|
||||
|
||||
Change-Id: I718253ceb902a2d53f7199a746063a36129b0fa6
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc: jassisinghbrar@gmail.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
drivers/mailbox/Kconfig | 7 +
|
||||
drivers/mailbox/Makefile | 2 +
|
||||
drivers/mailbox/arm_mhu_v2.c | 707 +++++++++++++++++++++++
|
||||
include/linux/mailbox/arm-mbox-message.h | 37 ++
|
||||
4 files changed, 753 insertions(+)
|
||||
create mode 100644 drivers/mailbox/arm_mhu_v2.c
|
||||
create mode 100644 include/linux/mailbox/arm-mbox-message.h
|
||||
|
||||
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
|
||||
index ab4eb750bbdd..0a0dce01098c 100644
|
||||
--- a/drivers/mailbox/Kconfig
|
||||
+++ b/drivers/mailbox/Kconfig
|
||||
@@ -22,6 +22,13 @@ config IMX_MBOX
|
||||
help
|
||||
Mailbox implementation for i.MX Messaging Unit (MU).
|
||||
|
||||
+config ARM_MHU_V2
|
||||
+ tristate "ARM MHUv2 Mailbox"
|
||||
+ depends on ARM_AMBA
|
||||
+ help
|
||||
+ Say Y here if you want to build the ARM MHUv2 controller driver,
|
||||
+ which provides unidirectional mailboxes between processing elements.
|
||||
+
|
||||
config PLATFORM_MHU
|
||||
tristate "Platform MHU Mailbox"
|
||||
depends on OF
|
||||
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
|
||||
index c22fad6f696b..78377f459421 100644
|
||||
--- a/drivers/mailbox/Makefile
|
||||
+++ b/drivers/mailbox/Makefile
|
||||
@@ -11,6 +11,8 @@ obj-$(CONFIG_IMX_MBOX) += imx-mailbox.o
|
||||
|
||||
obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX) += armada-37xx-rwtm-mailbox.o
|
||||
|
||||
+obj-$(CONFIG_ARM_MHU_V2) += arm_mhu_v2.o
|
||||
+
|
||||
obj-$(CONFIG_PLATFORM_MHU) += platform_mhu.o
|
||||
|
||||
obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
|
||||
diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
|
||||
new file mode 100644
|
||||
index 000000000000..d809076eb47b
|
||||
--- /dev/null
|
||||
+++ b/drivers/mailbox/arm_mhu_v2.c
|
||||
@@ -0,0 +1,707 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Arm Message Handling Unit Version 2 (MHUv2) driver
|
||||
+ *
|
||||
+ * An MHU device may function in one of three transport protocol modes
|
||||
+ * (single-word, multi-word and doorbell).
|
||||
+ * This transport protocol should be specified in the device tree entry for the
|
||||
+ * device. The transport protocol determines how the underlying hardware
|
||||
+ * resources of the device are utilized when transmitting data.
|
||||
+ *
|
||||
+ * The arm MHUv2 driver registers as a mailbox controller with the common
|
||||
+ * mailbox framework. Each mailbox channel represents a separate virtual
|
||||
+ * communication channel through the MHU device.
|
||||
+ * The number of registered mailbox channels is dependent on both the
|
||||
+ * underlying hardware - mainly the number of channel windows within each MHU
|
||||
+ * frame, as well as the selected transport protocol.
|
||||
+ *
|
||||
+ * Copyright (C) 2019 Arm Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/amba/bus.h>
|
||||
+#include <linux/mailbox_controller.h>
|
||||
+#include <linux/mailbox/arm-mbox-message.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+/* Maximum number of channel windows */
|
||||
+#define MHUV2_CHANNEL_MAX 124
|
||||
+/* Number of combined interrupt status registers */
|
||||
+#define MHUV2_CMB_INT_ST_REG_CNT 4
|
||||
+#define MHUV2_CH_UNKNOWN -1
|
||||
+
|
||||
+/* Channel window status register type */
|
||||
+typedef u32 mhuv2_stat_reg_t;
|
||||
+#define MHUV2_STAT_BYTES sizeof(mhuv2_stat_reg_t)
|
||||
+#define MHUV2_STAT_BITS (MHUV2_STAT_BYTES * __CHAR_BIT__)
|
||||
+
|
||||
+#define LSB_MASK(n) ((1 << (n)) - 1)
|
||||
+
|
||||
+#ifndef PAD
|
||||
+#define _PADLINE(line) pad##line
|
||||
+#define _XSTR(line) _PADLINE(line)
|
||||
+#define PAD _XSTR(__LINE__)
|
||||
+#endif
|
||||
+
|
||||
+/* ====== Arm MHUv2 register defines ====== */
|
||||
+
|
||||
+/* Register Message Handling Unit Configuration fields */
|
||||
+struct MHU_CFG_t {
|
||||
+ u32 NUM_CH : 7;
|
||||
+ u32 PAD : 25;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Implementer Identification fields */
|
||||
+struct IIDR_t {
|
||||
+ u32 IMPLEMENTER : 12;
|
||||
+ u32 REVISION : 4;
|
||||
+ u32 VARIANT : 4;
|
||||
+ u32 PRODUCT_ID : 12;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Architecture Identification Register fields */
|
||||
+struct AIDR_t {
|
||||
+ u32 ARCH_MINOR_REV : 4;
|
||||
+ u32 ARCH_MAJOR_REV : 4;
|
||||
+ u32 PAD : 24;
|
||||
+} __packed;
|
||||
+
|
||||
+/* register Interrupt Status fields */
|
||||
+struct INT_ST_t {
|
||||
+ u32 NR2R : 1;
|
||||
+ u32 R2NR : 1;
|
||||
+ u32 PAD : 30;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Interrupt Clear fields */
|
||||
+struct INT_CLR_t {
|
||||
+ u32 NR2R : 1;
|
||||
+ u32 R2NR : 1;
|
||||
+ u32 PAD : 30;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Register Interrupt Enable fields */
|
||||
+struct INT_EN_t {
|
||||
+ u32 R2NR : 1;
|
||||
+ u32 NR2R : 1;
|
||||
+ u32 CHCOMB : 1;
|
||||
+ u32 PAD : 29;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Sender Channel Window fields */
|
||||
+struct mhu2_send_channel_reg {
|
||||
+ mhuv2_stat_reg_t STAT;
|
||||
+ u8 PAD[0xC - 0x4];
|
||||
+ mhuv2_stat_reg_t STAT_SET;
|
||||
+ u8 PAD[0x20 - 0x10];
|
||||
+} __packed;
|
||||
+
|
||||
+/* Sender frame register fields */
|
||||
+struct mhu2_send_frame_reg {
|
||||
+ struct mhu2_send_channel_reg channel[MHUV2_CHANNEL_MAX];
|
||||
+ struct MHU_CFG_t MHU_CFG;
|
||||
+ u32 RESP_CFG;
|
||||
+ u32 ACCESS_REQUEST;
|
||||
+ u32 ACCESS_READY;
|
||||
+ struct INT_ST_t INT_ST;
|
||||
+ struct INT_CLR_t INT_CLR;
|
||||
+ struct INT_EN_t INT_EN;
|
||||
+ u32 RESERVED0;
|
||||
+ u32 CHCOMB_INT_ST[MHUV2_CMB_INT_ST_REG_CNT];
|
||||
+ u8 PAD[0xFC8 - 0xFB0];
|
||||
+ struct IIDR_t IIDR;
|
||||
+ struct AIDR_t AIDR;
|
||||
+} __packed;
|
||||
+
|
||||
+/* Receiver Channel Window fields */
|
||||
+struct mhu2_recv_channel_reg {
|
||||
+ mhuv2_stat_reg_t STAT;
|
||||
+ mhuv2_stat_reg_t STAT_PEND;
|
||||
+ mhuv2_stat_reg_t STAT_CLEAR;
|
||||
+ u8 RESERVED0[0x10 - 0x0C];
|
||||
+ mhuv2_stat_reg_t MASK;
|
||||
+ mhuv2_stat_reg_t MASK_SET;
|
||||
+ mhuv2_stat_reg_t MASK_CLEAR;
|
||||
+ u8 PAD[0x20 - 0x1C];
|
||||
+} __packed;
|
||||
+
|
||||
+/* Receiver frame register fields */
|
||||
+struct mhu2_recv_frame_reg {
|
||||
+ struct mhu2_recv_channel_reg channel[MHUV2_CHANNEL_MAX];
|
||||
+ struct MHU_CFG_t MHU_CFG;
|
||||
+ u8 RESERVED0[0xF90 - 0xF84];
|
||||
+ struct INT_ST_t INT_ST;
|
||||
+ struct INT_CLR_t INT_CLR;
|
||||
+ struct INT_EN_t INT_EN;
|
||||
+ u32 PAD;
|
||||
+ mhuv2_stat_reg_t CHCOMB_INT_ST[MHUV2_CMB_INT_ST_REG_CNT];
|
||||
+ u8 RESERVED2[0xFC8 - 0xFB0];
|
||||
+ struct IIDR_t IIDR;
|
||||
+ struct AIDR_t AIDR;
|
||||
+} __packed;
|
||||
+
|
||||
+/* ====== Arm MHUv2 device tree property identifiers ====== */
|
||||
+
|
||||
+static const char *const mhuv2_protocol_dt_identifiers[] = { "single-word",
|
||||
+ "multi-word",
|
||||
+ "doorbell" };
|
||||
+
|
||||
+static const char *const mhuv2_frame_dt_identifiers[] = { "receiver",
|
||||
+ "sender" };
|
||||
+
|
||||
+/* ====== Arm MHUv2 data structures ====== */
|
||||
+
|
||||
+enum mhuv2_transport_protocol { SINGLE_WORD, MULTI_WORD, DOORBELL };
|
||||
+
|
||||
+enum mhuv2_frame { RECEIVER_FRAME, SENDER_FRAME };
|
||||
+
|
||||
+/**
|
||||
+ * Arm MHUv2 operations
|
||||
+ *
|
||||
+ * Each transport protocol must provide an implementation of the operations
|
||||
+ * presented in this structure.
|
||||
+ * Most operations present a struct mbox_chan* as argument. This channel will
|
||||
+ * correspond to one of the virtual channels within the MHU device. What
|
||||
+ * constitutes a channel within the MHU device is dependent on the transport
|
||||
+ * protocol.
|
||||
+ */
|
||||
+struct arm_mhuv2;
|
||||
+struct mhuv2_ops {
|
||||
+ int (*read_data)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg);
|
||||
+ int (*clear_data)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg);
|
||||
+ int (*send_data)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg);
|
||||
+ int (*setup)(struct arm_mhuv2 *mhuv2);
|
||||
+ int (*last_tx_done)(struct arm_mhuv2 *mhuv2, struct mbox_chan *chan);
|
||||
+ struct mbox_chan *(*get_active_mbox_chan)(struct arm_mhuv2 *mhuv2);
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * Arm MHUv2 mailbox channel information
|
||||
+ *
|
||||
+ * A channel contains a notion of its index within the array of mailbox channels
|
||||
+ * which a mailbox controller allocates.
|
||||
+ */
|
||||
+struct arm_mhuv2_mbox_chan_priv {
|
||||
+ u32 ch_idx;
|
||||
+};
|
||||
+
|
||||
+#define mhuv2_chan_idx(_chanptr) \
|
||||
+ (((struct arm_mhuv2_mbox_chan_priv *)(_chanptr)->con_priv)->ch_idx)
|
||||
+
|
||||
+/**
|
||||
+ * Arm MHUv2 mailbox controller data
|
||||
+ *
|
||||
+ * @reg: Base address of the register mapping region
|
||||
+ * @protocol: Transport protocol, derived from device tree
|
||||
+ * @frame: Frame type, derived from device tree
|
||||
+ * @irq: Interrupt, only valid for receiver frames
|
||||
+ * @mbox: Mailbox controller belonging to the MHU frame
|
||||
+ * @ops: Pointer to transport-protocol specific operations
|
||||
+ * @dev: Device to which it is attached
|
||||
+ */
|
||||
+struct arm_mhuv2 {
|
||||
+ union {
|
||||
+ struct mhu2_send_frame_reg __iomem *send;
|
||||
+ struct mhu2_recv_frame_reg __iomem *recv;
|
||||
+ } reg;
|
||||
+ enum mhuv2_frame frame;
|
||||
+ unsigned int irq;
|
||||
+ struct mbox_controller mbox;
|
||||
+ struct mhuv2_ops *ops;
|
||||
+ struct device *dev;
|
||||
+};
|
||||
+
|
||||
+#define mhu2_from_mbox_ctrl(_mbox) container_of(_mbox, struct arm_mhuv2, mbox)
|
||||
+#define mhu2_from_mbox_chan(_chan) mhu2_from_mbox_ctrl(_chan->mbox)
|
||||
+
|
||||
+/* Macro for reading a bitfield within a physically mapped packed struct */
|
||||
+#define readl_relaxed_bitfield(_regptr, _field) \
|
||||
+ ({ \
|
||||
+ mhuv2_stat_reg_t _regval; \
|
||||
+ BUILD_BUG_ON(sizeof(*(_regptr)) > sizeof(typeof(_regval))); \
|
||||
+ _regval = readl_relaxed((_regptr)); \
|
||||
+ (*(typeof((_regptr)))(&_regval))._field; \
|
||||
+ })
|
||||
+
|
||||
+/* Macro for writing a bitfield within a physically mapped packed struct */
|
||||
+#define writel_relaxed_bitfield(_value, _regptr, _field) \
|
||||
+ ({ \
|
||||
+ mhuv2_stat_reg_t _regval; \
|
||||
+ BUILD_BUG_ON(sizeof(*_regptr) > sizeof(typeof(_regval))); \
|
||||
+ _regval = readl_relaxed(_regptr); \
|
||||
+ (*(typeof(_regptr))(&_regval))._field = _value; \
|
||||
+ writel_relaxed(_regval, _regptr); \
|
||||
+ })
|
||||
+
|
||||
+static inline int __find_set_bit(uint32_t val)
|
||||
+{
|
||||
+ const uint32_t trailing_zeros = __builtin_ctz(val);
|
||||
+ return trailing_zeros == 32 ? -1 : trailing_zeros;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Get index of a set bit within the combined interrupt status registers
|
||||
+ *
|
||||
+ * The function will calculate the index being the offset from the LSB of the
|
||||
+ * first combined interrupt status register.
|
||||
+ *
|
||||
+ */
|
||||
+static inline int mhuv2_combint_idx(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int ch_idx = 0;
|
||||
+ int set_bit_index, reg_idx;
|
||||
+
|
||||
+ for (reg_idx = 0; reg_idx < MHUV2_CMB_INT_ST_REG_CNT; reg_idx++) {
|
||||
+ mhuv2_stat_reg_t stat_reg;
|
||||
+
|
||||
+ stat_reg =
|
||||
+ readl_relaxed(&mhuv2->reg.recv->CHCOMB_INT_ST[reg_idx]);
|
||||
+ set_bit_index = __find_set_bit(stat_reg);
|
||||
+ if (set_bit_index == -1) {
|
||||
+ ch_idx += MHUV2_STAT_BITS;
|
||||
+ } else {
|
||||
+ ch_idx += set_bit_index;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return (ch_idx >= (MHUV2_CMB_INT_ST_REG_CNT * MHUV2_STAT_BITS) ?
|
||||
+ MHUV2_CH_UNKNOWN :
|
||||
+ ch_idx);
|
||||
+}
|
||||
+
|
||||
+/* ================ Single word transport protocol operations =============== */
|
||||
+static inline int mhuv20_get_non_zero_ch_idx(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ /* Locate a channel window with a non-zero STAT register */
|
||||
+ int ch_idx;
|
||||
+ int ch = MHUV2_CH_UNKNOWN;
|
||||
+
|
||||
+ for (ch_idx = 0;
|
||||
+ ch_idx < readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+ ch_idx++) {
|
||||
+ if (readl_relaxed(&mhuv2->reg.recv->channel[ch_idx].STAT)) {
|
||||
+ ch = ch_idx;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return ch;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_get_non_zero_ch_idx(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ /* Identify index of channel window containing non-zero data */
|
||||
+ switch (readl_relaxed_bitfield(&mhuv2->reg.recv->AIDR,
|
||||
+ ARCH_MINOR_REV)) {
|
||||
+ case 1:
|
||||
+ return mhuv2_combint_idx(mhuv2);
|
||||
+ default:
|
||||
+ return mhuv20_get_non_zero_ch_idx(mhuv2);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_read_data_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+
|
||||
+ msg->data = kzalloc(MHUV2_STAT_BYTES, GFP_KERNEL);
|
||||
+ if (!msg->data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *(mhuv2_stat_reg_t *)msg->data =
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch_idx].STAT);
|
||||
+ msg->len = MHUV2_STAT_BYTES;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_clear_data_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+
|
||||
+ writel_relaxed(readl_relaxed(&mhuv2->reg.recv->channel[ch_idx].STAT),
|
||||
+ &mhuv2->reg.recv->channel[ch_idx].STAT_CLEAR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_send_data_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+ int bytes_left = msg->len;
|
||||
+ char *data = msg->data;
|
||||
+
|
||||
+ if (ch_idx >= readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ while (bytes_left > 0) {
|
||||
+ mhuv2_stat_reg_t word = *(mhuv2_stat_reg_t *)(data);
|
||||
+
|
||||
+ if (bytes_left < MHUV2_STAT_BYTES)
|
||||
+ word &= LSB_MASK(bytes_left * __CHAR_BIT__);
|
||||
+
|
||||
+ if (!word) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "Data transmitted in single-word mode must be non-zero\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ writel_relaxed(word,
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT_SET);
|
||||
+ while (readl_relaxed(&mhuv2->reg.send->channel[ch_idx].STAT))
|
||||
+ continue;
|
||||
+ bytes_left -= MHUV2_STAT_BYTES;
|
||||
+ data += MHUV2_STAT_BYTES;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_last_tx_done_single_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_chan_idx(chan);
|
||||
+
|
||||
+ return readl_relaxed(&mhuv2->reg.send->channel[ch_idx].STAT) == 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_setup_single_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int i;
|
||||
+ const u32 channel_windows =
|
||||
+ readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
|
||||
+ &mhuv2->reg.recv->MHU_CFG :
|
||||
+ &mhuv2->reg.send->MHU_CFG,
|
||||
+ NUM_CH);
|
||||
+
|
||||
+ mhuv2->mbox.num_chans = channel_windows;
|
||||
+ mhuv2->mbox.chans =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < mhuv2->mbox.num_chans; i++) {
|
||||
+ mhuv2->mbox.chans[i].con_priv =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ sizeof(struct arm_mhuv2_mbox_chan_priv),
|
||||
+ GFP_KERNEL);
|
||||
+ mhuv2_chan_idx(&mhuv2->mbox.chans[i]) = i;
|
||||
+ }
|
||||
+
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ /* Ensure all status registers are unmasked */
|
||||
+ for (i = 0; i < channel_windows; i++) {
|
||||
+ writel_relaxed(0x0,
|
||||
+ &mhuv2->reg.recv->channel[i].MASK_SET);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline struct mbox_chan *
|
||||
+ mhuv2_get_active_mbox_chan_single_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ const u32 ch_idx = mhuv2_get_non_zero_ch_idx(mhuv2);
|
||||
+
|
||||
+ if (ch_idx >= mhuv2->mbox.num_chans) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "Invalid active channel in single word mode\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+ return &mhuv2->mbox.chans[ch_idx];
|
||||
+}
|
||||
+
|
||||
+static const struct mhuv2_ops mhuv2_single_word_ops = {
|
||||
+ .read_data = mhuv2_read_data_single_word,
|
||||
+ .clear_data = mhuv2_clear_data_single_word,
|
||||
+ .send_data = mhuv2_send_data_single_word,
|
||||
+ .setup = mhuv2_setup_single_word,
|
||||
+ .last_tx_done = mhuv2_last_tx_done_single_word,
|
||||
+ .get_active_mbox_chan = mhuv2_get_active_mbox_chan_single_word,
|
||||
+};
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
+/*
|
||||
+ * MHUv2 receiver interrupt service routine
|
||||
+ *
|
||||
+ * This routine will be called whenever a reception interrupt is raised on the
|
||||
+ * MHU device. Given that an MHU device may manage multiple mailboxes, it is
|
||||
+ * up to the protocol-specific operations to determine:
|
||||
+ * - What is the active mailbox channel
|
||||
+ * - Read the data within the MHU corresponding to the channel
|
||||
+ * - Clear the data within the MHU corresponding to the channel
|
||||
+ *
|
||||
+ * These operations must also ensure to not overwrite any data which may belong
|
||||
+ * to a different mailbox channel. For instance, if data is received in two
|
||||
+ * channel windows in single-word mode, the ISR will read and clear the data
|
||||
+ * from one of these channel windows within a pass. This will result in a status
|
||||
+ * register being non-zero upon returning from this routine, which in turn
|
||||
+ * will keep the interrupt asserted for a second round.
|
||||
+ */
|
||||
+static irqreturn_t mhuv2_rx_interrupt(int irq, void *data)
|
||||
+{
|
||||
+ struct arm_mbox_msg msg;
|
||||
+ int status;
|
||||
+ struct arm_mhuv2 *mhuv2 = data;
|
||||
+ struct mbox_chan *chan = mhuv2->ops->get_active_mbox_chan(mhuv2);
|
||||
+
|
||||
+ msg.data = NULL;
|
||||
+ msg.len = 0;
|
||||
+
|
||||
+ status = mhuv2->ops->read_data(mhuv2, chan, &msg);
|
||||
+ if (status != 0)
|
||||
+ goto rx_exit;
|
||||
+
|
||||
+ if (!chan->cl) {
|
||||
+ dev_warn(
|
||||
+ mhuv2->dev,
|
||||
+ "Warning: Received data on channel not currently attached to "
|
||||
+ "a mailbox client\n");
|
||||
+ } else {
|
||||
+ mbox_chan_received_data(chan, (void *)&msg);
|
||||
+ }
|
||||
+
|
||||
+ status = mhuv2->ops->clear_data(mhuv2, chan, &msg);
|
||||
+
|
||||
+rx_exit:
|
||||
+ kfree(msg.data);
|
||||
+
|
||||
+ return status == 0 ? IRQ_HANDLED : IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static bool mhuv2_last_tx_done(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_chan(chan);
|
||||
+
|
||||
+ return mhuv2->ops->last_tx_done(mhuv2, chan);
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_send_data(struct mbox_chan *chan, void *data)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_chan(chan);
|
||||
+ struct arm_mbox_msg *msg = data;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mhuv2->ops->last_tx_done(mhuv2, chan))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ ret = mhuv2->ops->send_data(mhuv2, chan, msg);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_startup(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_ctrl(chan->mbox);
|
||||
+
|
||||
+ writel_relaxed(0x1, &mhuv2->reg.send->ACCESS_REQUEST);
|
||||
+ while (!readl_relaxed(&mhuv2->reg.send->ACCESS_READY))
|
||||
+ continue;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mhuv2_shutdown(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct arm_mhuv2 *mhuv2 = mhu2_from_mbox_ctrl(chan->mbox);
|
||||
+
|
||||
+ writel_relaxed(0x0, &mhuv2->reg.send->ACCESS_REQUEST);
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_recv_startup(struct mbox_chan *chan)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mhuv2_recv_shutdown(struct mbox_chan *chan)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_recv_send_data(struct mbox_chan *chan, void *data)
|
||||
+{
|
||||
+ dev_err(chan->mbox->dev,
|
||||
+ "Trying to transmit on a receiver MHU frame\n");
|
||||
+ return -EIO;
|
||||
+}
|
||||
+
|
||||
+static bool mhuv2_recv_last_tx_done(struct mbox_chan *chan)
|
||||
+{
|
||||
+ dev_err(chan->mbox->dev, "Trying to Tx poll on a receiver MHU frame\n");
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static const struct mbox_chan_ops mhuv2_receiver_ops = {
|
||||
+ .send_data = mhuv2_recv_send_data,
|
||||
+ .startup = mhuv2_recv_startup,
|
||||
+ .shutdown = mhuv2_recv_shutdown,
|
||||
+ .last_tx_done = mhuv2_recv_last_tx_done,
|
||||
+};
|
||||
+
|
||||
+static const struct mbox_chan_ops mhuv2_sender_ops = {
|
||||
+ .send_data = mhuv2_send_data,
|
||||
+ .startup = mhuv2_startup,
|
||||
+ .shutdown = mhuv2_shutdown,
|
||||
+ .last_tx_done = mhuv2_last_tx_done,
|
||||
+};
|
||||
+
|
||||
+static struct mbox_chan *mhuv2_mbox_of_xlate(struct mbox_controller *ctrl,
|
||||
+ const struct of_phandle_args *pa)
|
||||
+{
|
||||
+ struct mbox_chan *chan;
|
||||
+
|
||||
+ if (pa->args_count != 1)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ if (pa->args[0] >= ctrl->num_chans)
|
||||
+ return ERR_PTR(-ENOENT);
|
||||
+
|
||||
+ chan = &ctrl->chans[pa->args[0]];
|
||||
+ return chan;
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
+{
|
||||
+ int err;
|
||||
+ struct device *dev = &adev->dev;
|
||||
+ const struct device_node *np = dev->of_node;
|
||||
+ struct arm_mhuv2 *mhuv2;
|
||||
+ const char *mhuv2_protocol_str;
|
||||
+
|
||||
+ /* Allocate memory for device */
|
||||
+ mhuv2 = devm_kzalloc(dev, sizeof(*mhuv2), GFP_KERNEL);
|
||||
+ if (!mhuv2)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mhuv2->dev = dev;
|
||||
+
|
||||
+ /* Assign transport protocol-specific operations */
|
||||
+ err = of_property_read_string(np, "mhu-protocol", &mhuv2_protocol_str);
|
||||
+
|
||||
+ if (err) {
|
||||
+ dev_err(dev,
|
||||
+ "Probe failed: no transport protocol specified\n");
|
||||
+ return -ENODEV;
|
||||
+ } else if (strcmp(mhuv2_protocol_str,
|
||||
+ mhuv2_protocol_dt_identifiers[SINGLE_WORD]) == 0) {
|
||||
+ mhuv2->ops = &mhuv2_single_word_ops;
|
||||
+ } else {
|
||||
+ dev_err(dev,
|
||||
+ "Probe failed: '%s' is not a valid transport protocol specifier\n",
|
||||
+ mhuv2_protocol_str);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* Get MHU type specific properties from device tree */
|
||||
+ if (adev->irq[0]) {
|
||||
+ mhuv2->frame = RECEIVER_FRAME;
|
||||
+ mhuv2->reg.recv = (struct mhu2_recv_frame_reg *)of_iomap(
|
||||
+ (struct device_node *)np, 0);
|
||||
+ if (!mhuv2->reg.recv)
|
||||
+ goto io_fail;
|
||||
+ mhuv2->irq = adev->irq[0];
|
||||
+ } else {
|
||||
+ mhuv2->frame = SENDER_FRAME;
|
||||
+ mhuv2->reg.send = (struct mhu2_send_frame_reg *)of_iomap(
|
||||
+ (struct device_node *)np, 0);
|
||||
+ if (!mhuv2->reg.send)
|
||||
+ goto io_fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Mailbox controller setup */
|
||||
+ mhuv2->mbox.dev = dev;
|
||||
+ mhuv2->mbox.txdone_irq = false;
|
||||
+ mhuv2->mbox.txdone_poll = true;
|
||||
+ mhuv2->mbox.txpoll_period = 1;
|
||||
+ mhuv2->mbox.of_xlate = mhuv2_mbox_of_xlate;
|
||||
+ mhuv2->mbox.ops = mhuv2->frame == SENDER_FRAME ? &mhuv2_sender_ops :
|
||||
+ &mhuv2_receiver_ops;
|
||||
+ /*
|
||||
+ * Transport protocol specific setup
|
||||
+ * Setup function _must_ allocate mailbox channels according to the
|
||||
+ * number of channels provided in the given transport protocol mode.
|
||||
+ */
|
||||
+ err = mhuv2->ops->setup(mhuv2);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ /* Request an interrupt if this is a receiver frame */
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ err = devm_request_threaded_irq(dev, adev->irq[0], NULL,
|
||||
+ mhuv2_rx_interrupt, IRQF_ONESHOT, "mhuv2_link", mhuv2);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "unable to acquire IRQ %d\n", mhuv2->irq);
|
||||
+ return err;
|
||||
+ }
|
||||
+ /*
|
||||
+ * For minor version 1 and forward, the combined interrupt of
|
||||
+ * the receiver frame must be explicitly enabled during startup.
|
||||
+ */
|
||||
+ if (readl_relaxed_bitfield(&mhuv2->reg.recv->AIDR,
|
||||
+ ARCH_MINOR_REV) > 0) {
|
||||
+ writel_relaxed_bitfield(1, &mhuv2->reg.recv->INT_EN,
|
||||
+ CHCOMB);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ amba_set_drvdata(adev, mhuv2);
|
||||
+
|
||||
+ err = devm_mbox_controller_register(dev, &mhuv2->mbox);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "failed to register ARM MHUv2 driver %d\n", err);
|
||||
+ iounmap(mhuv2->frame == RECEIVER_FRAME ? mhuv2->reg.recv :
|
||||
+ mhuv2->reg.send);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(dev, "ARM MHUv2 %s frame (%s) Mailbox driver registered\n",
|
||||
+ mhuv2_frame_dt_identifiers[mhuv2->frame],
|
||||
+ mhuv2_protocol_str);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+io_fail:
|
||||
+ dev_err(dev, "Probe failed: failed to map '%s' frame\n",
|
||||
+ mhuv2_frame_dt_identifiers[mhuv2->frame]);
|
||||
+ iounmap(mhuv2->frame == RECEIVER_FRAME ? mhuv2->reg.recv :
|
||||
+ mhuv2->reg.send);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static int mhuv2_remove(struct amba_device *adev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct amba_id mhuv2_ids[] = {
|
||||
+ {
|
||||
+ .id = 0x4b0d1,
|
||||
+ .mask = 0xfffff,
|
||||
+ },
|
||||
+ {
|
||||
+ .id = 0xbb0d1,
|
||||
+ .mask = 0xfffff,
|
||||
+ },
|
||||
+ { 0, 0 },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(amba, mhuv2_ids);
|
||||
+
|
||||
+static struct amba_driver arm_mhuv2_driver = {
|
||||
+ .drv = {
|
||||
+ .name = "mhuv2",
|
||||
+ },
|
||||
+ .id_table = mhuv2_ids,
|
||||
+ .probe = mhuv2_probe,
|
||||
+ .remove = mhuv2_remove,
|
||||
+};
|
||||
+module_amba_driver(arm_mhuv2_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_DESCRIPTION("ARM MHUv2 Driver");
|
||||
+MODULE_AUTHOR("Morten Borup Petersen <morten.petersen@arm.com>");
|
||||
diff --git a/include/linux/mailbox/arm-mbox-message.h b/include/linux/mailbox/arm-mbox-message.h
|
||||
new file mode 100644
|
||||
index 000000000000..112b4f927c1a
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mailbox/arm-mbox-message.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Arm Mailbox Message
|
||||
+ *
|
||||
+ * The Arm mailbox message structure is used to pass data- and length
|
||||
+ * information between a mailbox client and mailbox controller, through the
|
||||
+ * provided void* of the common mailbox frameworks send- and receive APIs.
|
||||
+ *
|
||||
+ * This will be utilized when a mailbox controller is able to transmit
|
||||
+ * more than a single word within a transmission, allowing the controller
|
||||
+ * to fully utilize its available resources.
|
||||
+ * No message protocol is enforced through this structure - a utilizing mailbox
|
||||
+ * client driver shall implement its own message protocol, which may then be
|
||||
+ * transmitted through an arm_mbox_msg.
|
||||
+ *
|
||||
+ * Given a message protocol of size A and an arm_mbox_msg containing data of
|
||||
+ * length B, a mailbox channel may callback with B < A. In this case, the
|
||||
+ * message protocol driver must implement a state machine which allows for
|
||||
+ * multiple callbacks that provides parts of a full message of size A. This
|
||||
+ * state machine must account for, that the length of the arm_mbox_msg received
|
||||
+ * may vary between callbacks based on the underlying hardware as well as the
|
||||
+ * transmitted data.
|
||||
+ *
|
||||
+ * Copyright (C) 2019 Arm Ltd.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LINUX_ARM_MBOX_MESSAGE_H_
|
||||
+#define _LINUX_ARM_MBOX_MESSAGE_H_
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+struct arm_mbox_msg {
|
||||
+ void *data;
|
||||
+ size_t len;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_ARM_MBOX_MESSAGE_H_ */
|
||||
--
|
||||
2.17.1
|
||||
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
From 515a936531a25a0c48a97efe3828962ed8d781dd Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 19 Jun 2019 16:55:20 +0100
|
||||
Subject: [PATCH 5/9] mailbox: arm_mhuv2: add doorbell transport protocol
|
||||
operations
|
||||
|
||||
In doorbell mode, the mailbox controller will provide a mailbox for each
|
||||
flag bit available in the combined number of channel windows available
|
||||
within the MHU device.
|
||||
|
||||
When in doorbell mode, the MHU should be used solely as an interrupt
|
||||
generating mechanism. If data is to be transmitted, this must be done
|
||||
out-band, ie. through shared memory, by a driving utilizing the mailbox
|
||||
for interrupt generation.
|
||||
|
||||
Change-Id: I8410b21471743c0b624c873388f9629ea0863789
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc:Jassi Brar <jassisinghbrar@gmail.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
drivers/mailbox/arm_mhu_v2.c | 108 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 108 insertions(+)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
|
||||
index d809076eb47b..efde7a71a3f7 100644
|
||||
--- a/drivers/mailbox/arm_mhu_v2.c
|
||||
+++ b/drivers/mailbox/arm_mhu_v2.c
|
||||
@@ -429,6 +429,111 @@ static const struct mhuv2_ops mhuv2_single_word_ops = {
|
||||
};
|
||||
/* ========================================================================== */
|
||||
|
||||
+/* =================== Doorbell transport protocol operations =============== */
|
||||
+
|
||||
+static inline int mhuv2_read_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_clear_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
|
||||
+ const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
|
||||
+ const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
|
||||
+
|
||||
+ writel_relaxed(BIT(ch_window_reg_idx),
|
||||
+ &mhuv2->reg.recv->channel[ch_window_idx].STAT_CLEAR);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_send_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
|
||||
+ const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
|
||||
+ const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
|
||||
+
|
||||
+ writel_relaxed(
|
||||
+ readl_relaxed(&mhuv2->reg.send->channel[ch_window_idx].STAT) |
|
||||
+ BIT(ch_window_reg_idx),
|
||||
+ &mhuv2->reg.send->channel[ch_window_idx].STAT_SET);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_last_tx_done_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan)
|
||||
+{
|
||||
+ const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
|
||||
+ const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
|
||||
+ const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
|
||||
+
|
||||
+ return (readl_relaxed(&mhuv2->reg.send->channel[ch_window_idx].STAT) &
|
||||
+ BIT(ch_window_reg_idx)) == 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_setup_doorbell(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int i;
|
||||
+ const u32 channel_windows =
|
||||
+ readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
|
||||
+ &mhuv2->reg.recv->MHU_CFG :
|
||||
+ &mhuv2->reg.send->MHU_CFG,
|
||||
+ NUM_CH);
|
||||
+
|
||||
+ mhuv2->mbox.num_chans = MHUV2_STAT_BITS * channel_windows;
|
||||
+ mhuv2->mbox.chans =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < mhuv2->mbox.num_chans; i++) {
|
||||
+ mhuv2->mbox.chans[i].con_priv =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ sizeof(struct arm_mhuv2_mbox_chan_priv),
|
||||
+ GFP_KERNEL);
|
||||
+ mhuv2_chan_idx(&mhuv2->mbox.chans[i]) = i;
|
||||
+ }
|
||||
+
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ /* Ensure all status registers are unmasked */
|
||||
+ for (i = 0; i < channel_windows; i++) {
|
||||
+ writel_relaxed(0x0,
|
||||
+ &mhuv2->reg.recv->channel[i].MASK_SET);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline struct mbox_chan *
|
||||
+ mhuv2_get_active_mbox_chan_doorbell(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ const u32 ch_window_idx = mhuv2_get_non_zero_ch_idx(mhuv2);
|
||||
+ const u32 ch_window_reg_idx = __find_set_bit(
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch_window_idx].STAT));
|
||||
+ if (ch_window_reg_idx == -1)
|
||||
+ return ERR_PTR(-EIO);
|
||||
+
|
||||
+ return &mhuv2->mbox.chans[ch_window_reg_idx +
|
||||
+ ch_window_idx * MHUV2_STAT_BITS];
|
||||
+}
|
||||
+
|
||||
+static const struct mhuv2_ops mhuv2_doorbell_ops = {
|
||||
+ .read_data = mhuv2_read_data_doorbell,
|
||||
+ .clear_data = mhuv2_clear_data_doorbell,
|
||||
+ .send_data = mhuv2_send_data_doorbell,
|
||||
+ .setup = mhuv2_setup_doorbell,
|
||||
+ .last_tx_done = mhuv2_last_tx_done_doorbell,
|
||||
+ .get_active_mbox_chan = mhuv2_get_active_mbox_chan_doorbell,
|
||||
+};
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
/*
|
||||
* MHUv2 receiver interrupt service routine
|
||||
*
|
||||
@@ -591,6 +696,9 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
} else if (strcmp(mhuv2_protocol_str,
|
||||
mhuv2_protocol_dt_identifiers[SINGLE_WORD]) == 0) {
|
||||
mhuv2->ops = &mhuv2_single_word_ops;
|
||||
+ } else if (strcmp(mhuv2_protocol_str,
|
||||
+ mhuv2_protocol_dt_identifiers[DOORBELL]) == 0) {
|
||||
+ mhuv2->ops = &mhuv2_doorbell_ops;
|
||||
} else {
|
||||
dev_err(dev,
|
||||
"Probe failed: '%s' is not a valid transport protocol specifier\n",
|
||||
--
|
||||
2.17.1
|
||||
|
||||
-271
@@ -1,271 +0,0 @@
|
||||
From 31140984e2ead5d56b072d0fed0b5f18a1e7e825 Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 19 Jun 2019 17:00:31 +0100
|
||||
Subject: [PATCH 6/9] mailbox: arm_mhuv2: add multi word transport protocol
|
||||
operations
|
||||
|
||||
When in multi-word mode, the mailbox controller will provide a single
|
||||
mailbox. It is required that the MHU device has at least 2 channel windows
|
||||
available for the MHU to function in multi-word mode.
|
||||
|
||||
Transmitting and receiving data through the mailbox framework in
|
||||
multi-word mode is done through a struct arm_mbox_msg.
|
||||
|
||||
Change-Id: Ibcf352d19ae3908093b20350853b16cf6a7933a2
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
|
||||
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
|
||||
Cc: jassisinghbrar@gmail.com
|
||||
Cc: devicetree@vger.kernel.org
|
||||
|
||||
Upstream-Status: Denied [https://lkml.org/lkml/2019/7/17/615]
|
||||
---
|
||||
drivers/mailbox/arm_mhu_v2.c | 225 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 225 insertions(+)
|
||||
|
||||
diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
|
||||
index efde7a71a3f7..e73e829d4f1e 100644
|
||||
--- a/drivers/mailbox/arm_mhu_v2.c
|
||||
+++ b/drivers/mailbox/arm_mhu_v2.c
|
||||
@@ -429,6 +429,228 @@ static const struct mhuv2_ops mhuv2_single_word_ops = {
|
||||
};
|
||||
/* ========================================================================== */
|
||||
|
||||
+/* ================ Multi word transport protocol operations ================ */
|
||||
+static inline int mhuv2_read_data_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ int ch;
|
||||
+ const int channels =
|
||||
+ readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+
|
||||
+ msg->data = kzalloc(MHUV2_STAT_BYTES * channels, GFP_KERNEL);
|
||||
+
|
||||
+ for (ch = 0; ch < channels; ch++) {
|
||||
+ /*
|
||||
+ * Messages are expected to be received in order of most
|
||||
+ * significant word to least significant word.
|
||||
+ * (see mhuv2_send_data_multi_word)
|
||||
+ */
|
||||
+ const mhuv2_stat_reg_t word =
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch].STAT);
|
||||
+ ((mhuv2_stat_reg_t *)msg->data)[channels - 1 - ch] = word;
|
||||
+ }
|
||||
+
|
||||
+ msg->len = channels * MHUV2_STAT_BYTES;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_clear_data_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ int ch;
|
||||
+ const int channels =
|
||||
+ readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+
|
||||
+ for (ch = 0; ch < channels; ch++) {
|
||||
+ /*
|
||||
+ * Last channel window must be cleared as the final operation.
|
||||
+ * Upon clearing the last channel window register, which is
|
||||
+ * unmasked in multi-word mode, the interrupt is deasserted.
|
||||
+ */
|
||||
+ writel_relaxed(
|
||||
+ readl_relaxed(&mhuv2->reg.recv->channel[ch].STAT),
|
||||
+ &mhuv2->reg.recv->channel[ch].STAT_CLEAR);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int __mhuv2_mw_bytes_to_send(const int bytes_in_round,
|
||||
+ const int bytes_left)
|
||||
+{
|
||||
+ /*
|
||||
+ * Bytes to send on the current channel will always be MHUV2_STAT_BYTES
|
||||
+ * unless in the last round and
|
||||
+ * msg->len % MHUV2_STAT_BYTES != 0
|
||||
+ */
|
||||
+ if (bytes_in_round % MHUV2_STAT_BYTES != 0) {
|
||||
+ const int bts = bytes_left % MHUV2_STAT_BYTES;
|
||||
+ return bts == 0 ? MHUV2_STAT_BYTES : bts;
|
||||
+ } else {
|
||||
+ return MHUV2_STAT_BYTES;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_send_data_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan,
|
||||
+ const struct arm_mbox_msg *msg)
|
||||
+{
|
||||
+ /*
|
||||
+ * Message will be transmitted from most significant to least
|
||||
+ * significant word. This is to allow for messages shorter than
|
||||
+ * $channels to still trigger the receiver interrupt which gets
|
||||
+ * activated when the last STAT register is written. As an example, a
|
||||
+ * 6-word message is to be written on a 4-channel MHU connection:
|
||||
+ * Registers marked with '*' are masked, and will not generate an
|
||||
+ * interrupt on the receiver side once written.
|
||||
+ *
|
||||
+ * uint32_t *data = [0x00000001],[0x00000002],[0x00000003],[0x00000004],
|
||||
+ * [0x00000005], [0x00000006]
|
||||
+ *
|
||||
+ * ROUND 1:
|
||||
+ * STAT reg To write Write sequence
|
||||
+ * [ STAT 3 ] <- [0x00000001] 4 <- triggers interrupt on receiver
|
||||
+ * *[ STAT 2 ] <- [0x00000002] 3
|
||||
+ * *[ STAT 1 ] <- [0x00000003] 2
|
||||
+ * *[ STAT 0 ] <- [0x00000004] 1
|
||||
+ *
|
||||
+ * data += 4 // Increment data pointer by number of STAT regs
|
||||
+ *
|
||||
+ * ROUND 2:
|
||||
+ * STAT reg To write Write sequence
|
||||
+ * [ STAT 3 ] <- [0x00000005] 2 <- triggers interrupt on receiver
|
||||
+ * *[ STAT 2 ] <- [0x00000006] 1
|
||||
+ * *[ STAT 1 ] <- [0x00000000]
|
||||
+ * *[ STAT 0 ] <- [0x00000000]
|
||||
+ */
|
||||
+ int bytes_left, bytes_to_send, i, ch_idx;
|
||||
+ const int ch_windows =
|
||||
+ readl_relaxed_bitfield(&mhuv2->reg.recv->MHU_CFG, NUM_CH);
|
||||
+ const size_t round_capacity = ch_windows * MHUV2_STAT_BYTES;
|
||||
+
|
||||
+ bytes_left = msg->len;
|
||||
+ mhuv2_stat_reg_t *data = msg->data;
|
||||
+
|
||||
+ while (bytes_left > 0) {
|
||||
+ /* Note: Each entry of this loop indicates a new ROUND */
|
||||
+ if (*(u32 *)data == 0) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "values in *data aligned on NUM_STAT boundaries must not be zero to ensure that receiver interrupt is triggered\n",
|
||||
+ ch_windows);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ const int bytes_in_round = bytes_left > round_capacity ?
|
||||
+ round_capacity :
|
||||
+ bytes_left;
|
||||
+
|
||||
+ for (i = (ch_windows - 1); i >= 0; i--) {
|
||||
+ ch_idx = ch_windows - 1 - i;
|
||||
+ /*
|
||||
+ * Check whether data should be transmitted in register
|
||||
+ * of index 'ch'.
|
||||
+ */
|
||||
+ if (bytes_in_round > (i * MHUV2_STAT_BYTES)) {
|
||||
+ mhuv2_stat_reg_t word = data[i];
|
||||
+
|
||||
+ bytes_to_send = __mhuv2_mw_bytes_to_send(
|
||||
+ bytes_in_round, bytes_left);
|
||||
+
|
||||
+ if (bytes_to_send != MHUV2_STAT_BYTES) {
|
||||
+ word &= LSB_MASK(bytes_to_send *
|
||||
+ __CHAR_BIT__);
|
||||
+ }
|
||||
+ while (readl_relaxed(
|
||||
+ &mhuv2->reg.send->channel[ch_idx]
|
||||
+ .STAT) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ writel_relaxed(
|
||||
+ word,
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT_SET);
|
||||
+ bytes_left -= bytes_to_send;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ data += ch_windows;
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < ch_windows; ch_idx++) {
|
||||
+ while (readl_relaxed(
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT) != 0)
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static inline int mhuv2_last_tx_done_multi_word(struct arm_mhuv2 *mhuv2,
|
||||
+ struct mbox_chan *chan)
|
||||
+{
|
||||
+ int ch_idx;
|
||||
+ bool tx_done = true;
|
||||
+
|
||||
+ for (ch_idx = 0;
|
||||
+ ch_idx < readl_relaxed_bitfield(&mhuv2->reg.send->MHU_CFG, NUM_CH);
|
||||
+ ch_idx++) {
|
||||
+ tx_done &= readl_relaxed(
|
||||
+ &mhuv2->reg.send->channel[ch_idx].STAT) == 0;
|
||||
+ }
|
||||
+ return tx_done;
|
||||
+}
|
||||
+
|
||||
+static inline int mhuv2_setup_multi_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ int ret, i;
|
||||
+
|
||||
+ const u32 channel_windows =
|
||||
+ readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
|
||||
+ &mhuv2->reg.recv->MHU_CFG :
|
||||
+ &mhuv2->reg.send->MHU_CFG,
|
||||
+ NUM_CH);
|
||||
+ if (channel_windows < 2) {
|
||||
+ dev_err(mhuv2->dev,
|
||||
+ "Error: at least 2 MHU channel windows are required for using the multi-word transfer protocol");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ if (mhuv2->frame == RECEIVER_FRAME) {
|
||||
+ /*
|
||||
+ * The multi-word transport protocol mandates that all but
|
||||
+ * the last status register must be masked.
|
||||
+ */
|
||||
+ for (i = 0; i < (channel_windows - 1); i++) {
|
||||
+ writel_relaxed(-1,
|
||||
+ &mhuv2->reg.recv->channel[i].MASK_SET);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mhuv2->mbox.num_chans = 1;
|
||||
+ mhuv2->mbox.chans =
|
||||
+ devm_kzalloc(mhuv2->dev,
|
||||
+ mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline struct mbox_chan *
|
||||
+ mhuv2_get_active_mbox_chan_multi_word(struct arm_mhuv2 *mhuv2)
|
||||
+{
|
||||
+ return &mhuv2->mbox.chans[0];
|
||||
+}
|
||||
+
|
||||
+static const struct mhuv2_ops mhuv2_multi_word_ops = {
|
||||
+ .read_data = mhuv2_read_data_multi_word,
|
||||
+ .clear_data = mhuv2_clear_data_multi_word,
|
||||
+ .send_data = mhuv2_send_data_multi_word,
|
||||
+ .setup = mhuv2_setup_multi_word,
|
||||
+ .last_tx_done = mhuv2_last_tx_done_multi_word,
|
||||
+ .get_active_mbox_chan = mhuv2_get_active_mbox_chan_multi_word,
|
||||
+};
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
/* =================== Doorbell transport protocol operations =============== */
|
||||
|
||||
static inline int mhuv2_read_data_doorbell(struct arm_mhuv2 *mhuv2,
|
||||
@@ -696,6 +918,9 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
} else if (strcmp(mhuv2_protocol_str,
|
||||
mhuv2_protocol_dt_identifiers[SINGLE_WORD]) == 0) {
|
||||
mhuv2->ops = &mhuv2_single_word_ops;
|
||||
+ } else if (strcmp(mhuv2_protocol_str,
|
||||
+ mhuv2_protocol_dt_identifiers[MULTI_WORD]) == 0) {
|
||||
+ mhuv2->ops = &mhuv2_multi_word_ops;
|
||||
} else if (strcmp(mhuv2_protocol_str,
|
||||
mhuv2_protocol_dt_identifiers[DOORBELL]) == 0) {
|
||||
mhuv2->ops = &mhuv2_doorbell_ops;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
From 68ce2dfe4c6f3806001fb8d682d6e99a9580dc2a Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 24 Jun 2020 11:16:01 +0100
|
||||
Subject: [PATCH 7/9] firmware: arm_scmi: Add fast_switch_possible() api
|
||||
|
||||
Add a new fast_switch_possible interface to the existing
|
||||
perf_ops api to export the information of whether or not
|
||||
fast_switch is possible in this driver.
|
||||
|
||||
This can be used by the CPUFreq driver and framework to
|
||||
choose proper mechanism for frequency change.
|
||||
|
||||
Suggested-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/firmware/arm_scmi?id=1909872ff20fc378ec6a44ea1a2b2966d834e504]
|
||||
---
|
||||
drivers/firmware/arm_scmi/perf.c | 12 ++++++++++++
|
||||
include/linux/scmi_protocol.h | 2 ++
|
||||
2 files changed, 14 insertions(+)
|
||||
|
||||
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
|
||||
index 601af4edad5e..c9350bb2ba1f 100644
|
||||
--- a/drivers/firmware/arm_scmi/perf.c
|
||||
+++ b/drivers/firmware/arm_scmi/perf.c
|
||||
@@ -691,6 +691,17 @@ static int scmi_dvfs_est_power_get(const struct scmi_handle *handle, u32 domain,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static bool scmi_fast_switch_possible(const struct scmi_handle *handle,
|
||||
+ struct device *dev)
|
||||
+{
|
||||
+ struct perf_dom_info *dom;
|
||||
+ struct scmi_perf_info *pi = handle->perf_priv;
|
||||
+
|
||||
+ dom = pi->dom_info + scmi_dev_domain_id(dev);
|
||||
+
|
||||
+ return (dom->fc_info && dom->fc_info->level_set_addr);
|
||||
+}
|
||||
+
|
||||
static struct scmi_perf_ops perf_ops = {
|
||||
.limits_set = scmi_perf_limits_set,
|
||||
.limits_get = scmi_perf_limits_get,
|
||||
@@ -702,6 +713,7 @@ static struct scmi_perf_ops perf_ops = {
|
||||
.freq_set = scmi_dvfs_freq_set,
|
||||
.freq_get = scmi_dvfs_freq_get,
|
||||
.est_power_get = scmi_dvfs_est_power_get,
|
||||
+ .fast_switch_possible = scmi_fast_switch_possible,
|
||||
};
|
||||
|
||||
static int scmi_perf_protocol_init(struct scmi_handle *handle)
|
||||
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
|
||||
index 881fea47c83d..b1f4a88219c5 100644
|
||||
--- a/include/linux/scmi_protocol.h
|
||||
+++ b/include/linux/scmi_protocol.h
|
||||
@@ -114,6 +114,8 @@ struct scmi_perf_ops {
|
||||
unsigned long *rate, bool poll);
|
||||
int (*est_power_get)(const struct scmi_handle *handle, u32 domain,
|
||||
unsigned long *rate, unsigned long *power);
|
||||
+ bool (*fast_switch_possible)(const struct scmi_handle *handle,
|
||||
+ struct device *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.17.1
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
From 47300d8385801913709eda5fd237d54f51477546 Mon Sep 17 00:00:00 2001
|
||||
From: Usama Arif <usama.arif@arm.com>
|
||||
Date: Wed, 24 Jun 2020 11:25:02 +0100
|
||||
Subject: [PATCH 8/9] cpufreq: arm_scmi: Set fast_switch_possible conditionally
|
||||
|
||||
Currently the fast_switch_possible flag is set unconditionally
|
||||
to true. Based on this, schedutil does not create a
|
||||
thread for frequency switching and would always use the
|
||||
fast switch path.
|
||||
However, if the platform does not support frequency
|
||||
fast switch, this may cause the governor to attempt an
|
||||
operation that is not supported by the platform.
|
||||
|
||||
Fix this by correctly retrieve the fast_switch capability
|
||||
from the driver which knows if the platform can support
|
||||
this feature.
|
||||
|
||||
Suggested-by: Lukasz Luba <lukasz.luba@arm.com>
|
||||
Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/cpufreq?id=fb3571276b970cbe7b45ecdc762e92f3f305ad6d]
|
||||
---
|
||||
drivers/cpufreq/scmi-cpufreq.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
|
||||
index e6182c89df79..931fcf0ef221 100644
|
||||
--- a/drivers/cpufreq/scmi-cpufreq.c
|
||||
+++ b/drivers/cpufreq/scmi-cpufreq.c
|
||||
@@ -198,7 +198,8 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
|
||||
policy->cpuinfo.transition_latency = latency;
|
||||
|
||||
- policy->fast_switch_possible = true;
|
||||
+ policy->fast_switch_possible =
|
||||
+ handle->perf_ops->fast_switch_possible(handle, cpu_dev);
|
||||
|
||||
em_register_perf_domain(policy->cpus, nr_opp, &em_cb);
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
-1461
File diff suppressed because it is too large
Load Diff
-252
@@ -1,252 +0,0 @@
|
||||
Upstream-Status: Backport [https://github.com/linaro-swg/linux/commit/e33bcbab16d1c0dd85d72bec275308369ad901f5#diff-317c0445401e56bde9d2ee0e0bb2758b0362a4099dca8e535dd20f1f649ecfc8]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
|
||||
From 69a50f4234d8fb143d499e92e3f0f67009bae586 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?=
|
||||
<vesa.jaaskelainen@vaisala.com>
|
||||
Date: Wed, 22 Apr 2020 15:28:07 +0300
|
||||
Subject: [PATCH] tee: add support for session's client UUID generation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
TEE Client API defines that from user space only information needed for
|
||||
specified login operations is group identifier for group based logins.
|
||||
|
||||
REE kernel is expected to formulate trustworthy client UUID and pass that
|
||||
to TEE environment. REE kernel is required to verify that provided group
|
||||
identifier for group based logins matches calling processes group
|
||||
memberships.
|
||||
|
||||
TEE specification only defines that the information passed from REE
|
||||
environment to TEE environment is encoded into on UUID.
|
||||
|
||||
In order to guarantee trustworthiness of client UUID user space is not
|
||||
allowed to freely pass client UUID.
|
||||
|
||||
UUIDv5 form is used encode variable amount of information needed for
|
||||
different login types.
|
||||
|
||||
Signed-off-by: Vesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
|
||||
Change-Id: I414f68d7485f95277d292fcb2646cc41bd57e62a
|
||||
---
|
||||
drivers/tee/Kconfig | 1 +
|
||||
drivers/tee/tee_core.c | 143 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/tee_drv.h | 16 +++++
|
||||
3 files changed, 160 insertions(+)
|
||||
|
||||
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
|
||||
index 676ffcb64985..5a56317f3f4e 100644
|
||||
--- a/drivers/tee/Kconfig
|
||||
+++ b/drivers/tee/Kconfig
|
||||
@@ -3,6 +3,7 @@
|
||||
config TEE
|
||||
tristate "Trusted Execution Environment support"
|
||||
depends on HAVE_ARM_SMCCC || COMPILE_TEST
|
||||
+ select CRYPTO_SHA1
|
||||
select DMA_SHARED_BUFFER
|
||||
select GENERIC_ALLOCATOR
|
||||
help
|
||||
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
|
||||
index 0f16d9ffd8d1..3d32a2ca48c3 100644
|
||||
--- a/drivers/tee/tee_core.c
|
||||
+++ b/drivers/tee/tee_core.c
|
||||
@@ -6,18 +6,33 @@
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/cdev.h>
|
||||
+#include <linux/cred.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tee_drv.h>
|
||||
#include <linux/uaccess.h>
|
||||
+#include <crypto/hash.h>
|
||||
+#include <crypto/sha.h>
|
||||
#include "tee_private.h"
|
||||
|
||||
#define TEE_NUM_DEVICES 32
|
||||
|
||||
#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
|
||||
|
||||
+#define TEE_UUID_NS_NAME_SIZE 128
|
||||
+
|
||||
+/*
|
||||
+ * TEE Client UUID name space identifier (UUIDv4)
|
||||
+ *
|
||||
+ * Value here is random UUID that is allocated as name space identifier for
|
||||
+ * forming Client UUID's for TEE environment using UUIDv5 scheme.
|
||||
+ */
|
||||
+static const uuid_t tee_client_uuid_ns = UUID_INIT(0x58ac9ca0, 0x2086, 0x4683,
|
||||
+ 0xa1, 0xb8, 0xec, 0x4b,
|
||||
+ 0xc0, 0x8e, 0x01, 0xb6);
|
||||
+
|
||||
/*
|
||||
* Unprivileged devices in the lower half range and privileged devices in
|
||||
* the upper half range.
|
||||
@@ -111,6 +126,134 @@ static int tee_release(struct inode *inode, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * uuid_v5() - Calculate UUIDv5
|
||||
+ * @uuid: Resulting UUID
|
||||
+ * @ns: Name space ID for UUIDv5 function
|
||||
+ * @name: Name for UUIDv5 function
|
||||
+ * @size: Size of name
|
||||
+ *
|
||||
+ * UUIDv5 is specific in RFC 4122.
|
||||
+ *
|
||||
+ * This implements section (for SHA-1):
|
||||
+ * 4.3. Algorithm for Creating a Name-Based UUID
|
||||
+ */
|
||||
+static int uuid_v5(uuid_t *uuid, const uuid_t *ns, const void *name,
|
||||
+ size_t size)
|
||||
+{
|
||||
+ unsigned char hash[SHA1_DIGEST_SIZE];
|
||||
+ struct crypto_shash *shash = NULL;
|
||||
+ struct shash_desc *desc = NULL;
|
||||
+ int rc;
|
||||
+
|
||||
+ shash = crypto_alloc_shash("sha1", 0, 0);
|
||||
+ if (IS_ERR(shash)) {
|
||||
+ rc = PTR_ERR(shash);
|
||||
+ pr_err("shash(sha1) allocation failed\n");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash),
|
||||
+ GFP_KERNEL);
|
||||
+ if (IS_ERR(desc)) {
|
||||
+ rc = PTR_ERR(desc);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ desc->tfm = shash;
|
||||
+
|
||||
+ rc = crypto_shash_init(desc);
|
||||
+ if (rc < 0)
|
||||
+ goto out2;
|
||||
+
|
||||
+ rc = crypto_shash_update(desc, (const u8 *)ns, sizeof(*ns));
|
||||
+ if (rc < 0)
|
||||
+ goto out2;
|
||||
+
|
||||
+ rc = crypto_shash_update(desc, (const u8 *)name, size);
|
||||
+ if (rc < 0)
|
||||
+ goto out2;
|
||||
+
|
||||
+ rc = crypto_shash_final(desc, hash);
|
||||
+ if (rc < 0)
|
||||
+ goto out2;
|
||||
+
|
||||
+ memcpy(uuid->b, hash, UUID_SIZE);
|
||||
+
|
||||
+ /* Tag for version 5 */
|
||||
+ uuid->b[6] = (hash[6] & 0x0F) | 0x50;
|
||||
+ uuid->b[8] = (hash[8] & 0x3F) | 0x80;
|
||||
+
|
||||
+out2:
|
||||
+ kfree(desc);
|
||||
+
|
||||
+out:
|
||||
+ crypto_free_shash(shash);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
|
||||
+ const u8 connection_data[TEE_IOCTL_UUID_LEN])
|
||||
+{
|
||||
+ const char *application_id = NULL;
|
||||
+ gid_t ns_grp = (gid_t)-1;
|
||||
+ kgid_t grp = INVALID_GID;
|
||||
+ char *name = NULL;
|
||||
+ int rc;
|
||||
+
|
||||
+ if (connection_method == TEE_IOCTL_LOGIN_PUBLIC) {
|
||||
+ /* Nil UUID to be passed to TEE environment */
|
||||
+ uuid_copy(uuid, &uuid_null);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * In Linux environment client UUID is based on UUIDv5.
|
||||
+ *
|
||||
+ * Determine client UUID with following semantics for 'name':
|
||||
+ *
|
||||
+ * For TEEC_LOGIN_USER:
|
||||
+ * uid=<uid>
|
||||
+ *
|
||||
+ * For TEEC_LOGIN_GROUP:
|
||||
+ * gid=<gid>
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+ name = kzalloc(TEE_UUID_NS_NAME_SIZE, GFP_KERNEL);
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ switch (connection_method) {
|
||||
+ case TEE_IOCTL_LOGIN_USER:
|
||||
+ scnprintf(name, TEE_UUID_NS_NAME_SIZE, "uid=%x",
|
||||
+ current_euid().val);
|
||||
+ break;
|
||||
+
|
||||
+ case TEE_IOCTL_LOGIN_GROUP:
|
||||
+ memcpy(&ns_grp, connection_data, sizeof(gid_t));
|
||||
+ grp = make_kgid(current_user_ns(), ns_grp);
|
||||
+ if (!gid_valid(grp) || !in_egroup_p(grp)) {
|
||||
+ rc = -EPERM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ scnprintf(name, TEE_UUID_NS_NAME_SIZE, "gid=%x", grp.val);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ rc = uuid_v5(uuid, &tee_client_uuid_ns, name, strlen(name));
|
||||
+out:
|
||||
+ kfree(name);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(tee_session_calc_client_uuid);
|
||||
+
|
||||
static int tee_ioctl_version(struct tee_context *ctx,
|
||||
struct tee_ioctl_version_data __user *uvers)
|
||||
{
|
||||
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
|
||||
index 7a03f68fb982..545a57f61a5e 100644
|
||||
--- a/include/linux/tee_drv.h
|
||||
+++ b/include/linux/tee_drv.h
|
||||
@@ -166,6 +166,22 @@ int tee_device_register(struct tee_device *teedev);
|
||||
*/
|
||||
void tee_device_unregister(struct tee_device *teedev);
|
||||
|
||||
+/**
|
||||
+ * tee_session_calc_client_uuid() - Calculates client UUID for session
|
||||
+ * @uuid: Resulting UUID
|
||||
+ * @connection_method: Connection method for session (TEE_IOCTL_LOGIN_*)
|
||||
+ * @connectuon_data: Connection data for opening session
|
||||
+ *
|
||||
+ * Based on connection method calculates UUIDv5 based client UUID.
|
||||
+ *
|
||||
+ * For group based logins verifies that calling process has specified
|
||||
+ * credentials.
|
||||
+ *
|
||||
+ * @return < 0 on failure
|
||||
+ */
|
||||
+int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
|
||||
+ const u8 connection_data[TEE_IOCTL_UUID_LEN]);
|
||||
+
|
||||
/**
|
||||
* struct tee_shm - shared memory object
|
||||
* @teedev: device used to allocate the object
|
||||
--
|
||||
2.26.2
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
Upstream-Status: Backport [https://github.com/linaro-swg/linux/commit/c5b4312bea5d5e5e3d4f0af640e2ef8a1c1bb167#diff-2d83bca4adf0468bdb51b155a5df495e0226f7971f4150cfffbf043fe3b5a279]
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
|
||||
From c6c4046d8fcd34a4b8da9d844ce592951780ba8c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?=
|
||||
<vesa.jaaskelainen@vaisala.com>
|
||||
Date: Wed, 22 Apr 2020 15:30:39 +0300
|
||||
Subject: [PATCH] tee: optee: Add support for session login client UUID
|
||||
generation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Adds support for client UUID generation for OP-TEE. For group based session
|
||||
logins membership is verified.
|
||||
|
||||
Signed-off-by: Vesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
|
||||
---
|
||||
drivers/tee/optee/call.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
|
||||
index cf2367ba08d6..dbed3f480dc0 100644
|
||||
--- a/drivers/tee/optee/call.c
|
||||
+++ b/drivers/tee/optee/call.c
|
||||
@@ -233,9 +233,13 @@ int optee_open_session(struct tee_context *ctx,
|
||||
msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
|
||||
OPTEE_MSG_ATTR_META;
|
||||
memcpy(&msg_arg->params[0].u.value, arg->uuid, sizeof(arg->uuid));
|
||||
- memcpy(&msg_arg->params[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));
|
||||
msg_arg->params[1].u.value.c = arg->clnt_login;
|
||||
|
||||
+ rc = tee_session_calc_client_uuid((uuid_t *)&msg_arg->params[1].u.value,
|
||||
+ arg->clnt_login, arg->clnt_uuid);
|
||||
+ if (rc)
|
||||
+ goto out;
|
||||
+
|
||||
rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
|
||||
if (rc)
|
||||
goto out;
|
||||
--
|
||||
2.26.2
|
||||
|
||||
-3150
File diff suppressed because it is too large
Load Diff
-51
@@ -1,51 +0,0 @@
|
||||
From 957e0145899813017a6a2b7f863a4a2b4e4b75aa Mon Sep 17 00:00:00 2001
|
||||
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
Date: Tue, 5 Jan 2021 09:27:41 +0000
|
||||
Subject: [PATCH] tee: optee: fix mem handle removal in ffa_shm_unregister
|
||||
|
||||
Remove ffa memory handle before calling mem_reclaim. This enables the
|
||||
handle to be re-used by another thread once mem_claim for that handle
|
||||
is completed.
|
||||
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
Change-Id: I7294bd71f2bbc28514eaa09ae757dd216bc7df45
|
||||
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
drivers/tee/optee/call.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
|
||||
index ac89ab42a43f..9c9480add0b5 100644
|
||||
--- a/drivers/tee/optee/call.c
|
||||
+++ b/drivers/tee/optee/call.c
|
||||
@@ -843,6 +843,10 @@ int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
|
||||
{
|
||||
struct optee *optee = tee_get_drvdata(ctx->teedev);
|
||||
int rc = 0;
|
||||
+ u64 handle = shm->sec_world_id;
|
||||
+
|
||||
+ optee_shm_rem_ffa_handle(optee, handle);
|
||||
+ shm->sec_world_id = 0;
|
||||
|
||||
/*
|
||||
* We're skipping the OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM call
|
||||
@@ -850,14 +854,10 @@ int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
|
||||
* this ID.
|
||||
*/
|
||||
|
||||
- rc = optee->ffa.ops->mem_reclaim(shm->sec_world_id, 0);
|
||||
+ rc = optee->ffa.ops->mem_reclaim(handle, 0);
|
||||
if (rc)
|
||||
pr_err("mem_reclain: %d", rc);
|
||||
|
||||
- optee_shm_rem_ffa_handle(optee, shm->sec_world_id);
|
||||
-
|
||||
- shm->sec_world_id = 0;
|
||||
-
|
||||
return rc;
|
||||
}
|
||||
#endif /*CONFIG_ARM_FFA_TRANSPORT*/
|
||||
--
|
||||
2.26.2
|
||||
|
||||
-462
@@ -1,462 +0,0 @@
|
||||
Upstream-Status: Backport [http://www.linux-arm.org/git?p=linux-power.git;a=commit;h=ce7d6e205568b7949ff26f2b3c65dc4db1c15b96]
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
|
||||
From 0316669bc2a0e1279427b7a3ed01313b70544756 Mon Sep 17 00:00:00 2001
|
||||
From: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Date: Thu, 20 Jun 2019 17:59:25 +0100
|
||||
Subject: [PATCH 1/2] arm64: Add support for asymmetric AArch32 EL0
|
||||
configurations
|
||||
|
||||
There is a non-negligible chance that we may see asymmetric big.LITTLE
|
||||
configurations where only the LITTLE CPUs have AArch32 support at EL0.
|
||||
While Linux currently handles such configurations by not allowing
|
||||
AArch32 tasks, there is a strong marketing push to investigate the
|
||||
possibility of allowing compat applications. This patch is aimed to
|
||||
facilitate internal testing and NOT FOR UPSTREAM.
|
||||
|
||||
When the CONFIG_ASYMMETRIC_AARCH32 option is enabled (EXPERT), the type
|
||||
of the ARM64_HAS_32BIT_EL0 capability becomes WEAK_LOCAL_CPU_FEATURE.
|
||||
The kernel will now return true for system_supports_32bit_el0() and
|
||||
32-bit tasks will be migrated to the capable CPUs during
|
||||
do_notify_resume(). If the last CPU supporting 32-bit is offlined, the
|
||||
kernel will SIGKILL any scheduled 32-bit tasks (the alternative is to
|
||||
prevent offlining through a new .cpu_disable feature entry).
|
||||
|
||||
In addition to the relaxation of the ARM64_HAS_32BIT_EL0 capability,
|
||||
this patch factors out the 32-bit cpuinfo and features setting into
|
||||
separate functions: __cpuinfo_store_cpu_32bit(),
|
||||
init_cpu_32bit_features(). The cpuinfo of the booting CPU
|
||||
(boot_cpu_data) is now updated on the first 32-bit capable CPU even if
|
||||
it is a secondary one. The ID_AA64PFR0_EL0_64BIT_ONLY feature is relaxed
|
||||
to FTR_NONSTRICT and FTR_HIGHER_SAFE when the asymmetric AArch32 support
|
||||
is enabled. The compat_elf_hwcaps are only verified for the
|
||||
AArch32-capable CPUs to still allow hotplugging AArch64-only CPUs.
|
||||
|
||||
Cc: Suzuki K Poulose <Suzuki.Poulose@arm.com>
|
||||
Cc: Morten Rasmussen <Morten.Rasmussen@arm.com>
|
||||
Cc: Valentin Schneider <valentin.schneider@arm.com>
|
||||
Cc: Qais Yousef <qais.yousef@arm.com>
|
||||
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Signed-off-by: Qais Yousef <qais.yousef@arm.com>
|
||||
---
|
||||
arch/arm64/Kconfig | 13 ++++++
|
||||
arch/arm64/include/asm/cpu.h | 2 +
|
||||
arch/arm64/include/asm/cpufeature.h | 3 ++
|
||||
arch/arm64/include/asm/thread_info.h | 5 ++-
|
||||
arch/arm64/kernel/cpufeature.c | 64 ++++++++++++++++++----------
|
||||
arch/arm64/kernel/cpuinfo.c | 61 +++++++++++++++++---------
|
||||
arch/arm64/kernel/process.c | 17 ++++++++
|
||||
arch/arm64/kernel/signal.c | 30 ++++++++++++-
|
||||
8 files changed, 150 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
|
||||
index 71d23b5d10d4..068e9e9ffc40 100644
|
||||
--- a/arch/arm64/Kconfig
|
||||
+++ b/arch/arm64/Kconfig
|
||||
@@ -1680,6 +1680,19 @@ config DMI
|
||||
|
||||
endmenu
|
||||
|
||||
+config ASYMMETRIC_AARCH32
|
||||
+ bool "Allow support for asymmetric AArch32 support"
|
||||
+ depends on COMPAT && EXPERT && !KVM
|
||||
+ help
|
||||
+ Enable this option to allow support for asymmetric AArch32 EL0
|
||||
+ CPU configurations. Once the AArch32 EL0 support is detected
|
||||
+ on a CPU, the feature is made available to user space to allow
|
||||
+ the execution of 32-bit (compat) applications by migrating
|
||||
+ them to the capable CPUs. Offlining such CPUs leads to 32-bit
|
||||
+ applications being killed.
|
||||
+
|
||||
+ If unsure say N.
|
||||
+
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on COMPAT && SYSVIPC
|
||||
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
|
||||
index d72d995b7e25..39dbf5827070 100644
|
||||
--- a/arch/arm64/include/asm/cpu.h
|
||||
+++ b/arch/arm64/include/asm/cpu.h
|
||||
@@ -15,6 +15,7 @@
|
||||
struct cpuinfo_arm64 {
|
||||
struct cpu cpu;
|
||||
struct kobject kobj;
|
||||
+ bool aarch32_valid;
|
||||
u32 reg_ctr;
|
||||
u32 reg_cntfrq;
|
||||
u32 reg_dczid;
|
||||
@@ -60,6 +61,7 @@ void cpuinfo_store_cpu(void);
|
||||
void __init cpuinfo_store_boot_cpu(void);
|
||||
|
||||
void __init init_cpu_features(struct cpuinfo_arm64 *info);
|
||||
+void init_cpu_32bit_features(struct cpuinfo_arm64 *info);
|
||||
void update_cpu_features(int cpu, struct cpuinfo_arm64 *info,
|
||||
struct cpuinfo_arm64 *boot);
|
||||
|
||||
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
|
||||
index 9cde5d2e768f..d00d673d423b 100644
|
||||
--- a/arch/arm64/include/asm/cpufeature.h
|
||||
+++ b/arch/arm64/include/asm/cpufeature.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/bug.h>
|
||||
+#include <linux/cpumask.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
@@ -370,6 +371,8 @@ cpucap_multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry,
|
||||
return false;
|
||||
}
|
||||
|
||||
+extern cpumask_t aarch32_el0_mask;
|
||||
+
|
||||
extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
|
||||
extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
|
||||
extern struct static_key_false arm64_const_caps_ready;
|
||||
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
|
||||
index 8c73764b9ed2..54a4c912a7ab 100644
|
||||
--- a/arch/arm64/include/asm/thread_info.h
|
||||
+++ b/arch/arm64/include/asm/thread_info.h
|
||||
@@ -66,6 +66,7 @@ void arch_release_task_struct(struct task_struct *tsk);
|
||||
#define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */
|
||||
#define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */
|
||||
#define TIF_FSCHECK 5 /* Check FS is USER_DS on return */
|
||||
+#define TIF_SET_32BIT_AFFINITY 6 /* set thread affinity for asymmetric AArch32 */
|
||||
#define TIF_NOHZ 7
|
||||
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
|
||||
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing */
|
||||
@@ -95,11 +96,13 @@ void arch_release_task_struct(struct task_struct *tsk);
|
||||
#define _TIF_UPROBE (1 << TIF_UPROBE)
|
||||
#define _TIF_FSCHECK (1 << TIF_FSCHECK)
|
||||
#define _TIF_32BIT (1 << TIF_32BIT)
|
||||
+#define _TIF_SET_32BIT_AFFINITY (1 << TIF_SET_32BIT_AFFINITY)
|
||||
#define _TIF_SVE (1 << TIF_SVE)
|
||||
|
||||
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
|
||||
_TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
|
||||
- _TIF_UPROBE | _TIF_FSCHECK)
|
||||
+ _TIF_UPROBE | _TIF_FSCHECK | \
|
||||
+ _TIF_SET_32BIT_AFFINITY)
|
||||
|
||||
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
|
||||
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
|
||||
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
|
||||
index da92693b202c..c0d656cfe5b8 100644
|
||||
--- a/arch/arm64/kernel/cpufeature.c
|
||||
+++ b/arch/arm64/kernel/cpufeature.c
|
||||
@@ -8,7 +8,6 @@
|
||||
#define pr_fmt(fmt) "CPU features: " fmt
|
||||
|
||||
#include <linux/bsearch.h>
|
||||
-#include <linux/cpumask.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/stop_machine.h>
|
||||
@@ -164,7 +163,11 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL3_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL2_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_EL1_64BIT_ONLY),
|
||||
+#ifndef CONFIG_ASYMMETRIC_AARCH32
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY),
|
||||
+#else
|
||||
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_HIGHER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY),
|
||||
+#endif
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
||||
@@ -509,7 +512,7 @@ static void __init sort_ftr_regs(void)
|
||||
* Any bits that are not covered by an arm64_ftr_bits entry are considered
|
||||
* RES0 for the system-wide value, and must strictly match.
|
||||
*/
|
||||
-static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)
|
||||
+static void init_cpu_ftr_reg(u32 sys_reg, u64 new)
|
||||
{
|
||||
u64 val = 0;
|
||||
u64 strict_mask = ~0x0ULL;
|
||||
@@ -590,25 +593,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
|
||||
|
||||
- if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
|
||||
- init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
|
||||
- init_cpu_ftr_reg(SYS_ID_ISAR0_EL1, info->reg_id_isar0);
|
||||
- init_cpu_ftr_reg(SYS_ID_ISAR1_EL1, info->reg_id_isar1);
|
||||
- init_cpu_ftr_reg(SYS_ID_ISAR2_EL1, info->reg_id_isar2);
|
||||
- init_cpu_ftr_reg(SYS_ID_ISAR3_EL1, info->reg_id_isar3);
|
||||
- init_cpu_ftr_reg(SYS_ID_ISAR4_EL1, info->reg_id_isar4);
|
||||
- init_cpu_ftr_reg(SYS_ID_ISAR5_EL1, info->reg_id_isar5);
|
||||
- init_cpu_ftr_reg(SYS_ID_MMFR0_EL1, info->reg_id_mmfr0);
|
||||
- init_cpu_ftr_reg(SYS_ID_MMFR1_EL1, info->reg_id_mmfr1);
|
||||
- init_cpu_ftr_reg(SYS_ID_MMFR2_EL1, info->reg_id_mmfr2);
|
||||
- init_cpu_ftr_reg(SYS_ID_MMFR3_EL1, info->reg_id_mmfr3);
|
||||
- init_cpu_ftr_reg(SYS_ID_PFR0_EL1, info->reg_id_pfr0);
|
||||
- init_cpu_ftr_reg(SYS_ID_PFR1_EL1, info->reg_id_pfr1);
|
||||
- init_cpu_ftr_reg(SYS_MVFR0_EL1, info->reg_mvfr0);
|
||||
- init_cpu_ftr_reg(SYS_MVFR1_EL1, info->reg_mvfr1);
|
||||
- init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
|
||||
- }
|
||||
-
|
||||
if (id_aa64pfr0_sve(info->reg_id_aa64pfr0)) {
|
||||
init_cpu_ftr_reg(SYS_ZCR_EL1, info->reg_zcr);
|
||||
sve_init_vq_map();
|
||||
@@ -627,6 +611,26 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
setup_boot_cpu_capabilities();
|
||||
}
|
||||
|
||||
+void init_cpu_32bit_features(struct cpuinfo_arm64 *info)
|
||||
+{
|
||||
+ init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
|
||||
+ init_cpu_ftr_reg(SYS_ID_ISAR0_EL1, info->reg_id_isar0);
|
||||
+ init_cpu_ftr_reg(SYS_ID_ISAR1_EL1, info->reg_id_isar1);
|
||||
+ init_cpu_ftr_reg(SYS_ID_ISAR2_EL1, info->reg_id_isar2);
|
||||
+ init_cpu_ftr_reg(SYS_ID_ISAR3_EL1, info->reg_id_isar3);
|
||||
+ init_cpu_ftr_reg(SYS_ID_ISAR4_EL1, info->reg_id_isar4);
|
||||
+ init_cpu_ftr_reg(SYS_ID_ISAR5_EL1, info->reg_id_isar5);
|
||||
+ init_cpu_ftr_reg(SYS_ID_MMFR0_EL1, info->reg_id_mmfr0);
|
||||
+ init_cpu_ftr_reg(SYS_ID_MMFR1_EL1, info->reg_id_mmfr1);
|
||||
+ init_cpu_ftr_reg(SYS_ID_MMFR2_EL1, info->reg_id_mmfr2);
|
||||
+ init_cpu_ftr_reg(SYS_ID_MMFR3_EL1, info->reg_id_mmfr3);
|
||||
+ init_cpu_ftr_reg(SYS_ID_PFR0_EL1, info->reg_id_pfr0);
|
||||
+ init_cpu_ftr_reg(SYS_ID_PFR1_EL1, info->reg_id_pfr1);
|
||||
+ init_cpu_ftr_reg(SYS_MVFR0_EL1, info->reg_mvfr0);
|
||||
+ init_cpu_ftr_reg(SYS_MVFR1_EL1, info->reg_mvfr1);
|
||||
+ init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
|
||||
+}
|
||||
+
|
||||
static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
|
||||
{
|
||||
const struct arm64_ftr_bits *ftrp;
|
||||
@@ -1264,6 +1268,16 @@ static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry,
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_ASYMMETRIC_AARCH32
|
||||
+cpumask_t aarch32_el0_mask;
|
||||
+
|
||||
+static void cpu_enable_aarch32_el0(struct arm64_cpu_capabilities const *cap)
|
||||
+{
|
||||
+ if (has_cpuid_feature(cap, SCOPE_LOCAL_CPU))
|
||||
+ cpumask_set_cpu(smp_processor_id(), &aarch32_el0_mask);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
{
|
||||
.desc = "GIC system register CPU interface",
|
||||
@@ -1340,7 +1354,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
{
|
||||
.desc = "32-bit EL0 Support",
|
||||
.capability = ARM64_HAS_32BIT_EL0,
|
||||
+#ifndef CONFIG_ASYMMETRIC_AARCH32
|
||||
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
||||
+#else
|
||||
+ .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
|
||||
+ .cpu_enable = cpu_enable_aarch32_el0,
|
||||
+#endif
|
||||
.matches = has_cpuid_feature,
|
||||
.sys_reg = SYS_ID_AA64PFR0_EL1,
|
||||
.sign = FTR_UNSIGNED,
|
||||
@@ -1983,7 +2002,8 @@ static void verify_local_cpu_capabilities(void)
|
||||
|
||||
verify_local_elf_hwcaps(arm64_elf_hwcaps);
|
||||
|
||||
- if (system_supports_32bit_el0())
|
||||
+ if (system_supports_32bit_el0() &&
|
||||
+ this_cpu_has_cap(ARM64_HAS_32BIT_EL0))
|
||||
verify_local_elf_hwcaps(compat_elf_hwcaps);
|
||||
|
||||
if (system_supports_sve())
|
||||
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
|
||||
index 05933c065732..bda37687bb66 100644
|
||||
--- a/arch/arm64/kernel/cpuinfo.c
|
||||
+++ b/arch/arm64/kernel/cpuinfo.c
|
||||
@@ -351,27 +351,6 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
|
||||
info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
|
||||
info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
|
||||
|
||||
- /* Update the 32bit ID registers only if AArch32 is implemented */
|
||||
- if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
|
||||
- info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
|
||||
- info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
|
||||
- info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
|
||||
- info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
|
||||
- info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1);
|
||||
- info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1);
|
||||
- info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1);
|
||||
- info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1);
|
||||
- info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1);
|
||||
- info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1);
|
||||
- info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1);
|
||||
- info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
|
||||
- info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
|
||||
-
|
||||
- info->reg_mvfr0 = read_cpuid(MVFR0_EL1);
|
||||
- info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
|
||||
- info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
|
||||
- }
|
||||
-
|
||||
if (IS_ENABLED(CONFIG_ARM64_SVE) &&
|
||||
id_aa64pfr0_sve(info->reg_id_aa64pfr0))
|
||||
info->reg_zcr = read_zcr_features();
|
||||
@@ -379,10 +358,46 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
|
||||
cpuinfo_detect_icache_policy(info);
|
||||
}
|
||||
|
||||
+static void __cpuinfo_store_cpu_32bit(struct cpuinfo_arm64 *info)
|
||||
+{
|
||||
+ info->aarch32_valid = true;
|
||||
+
|
||||
+ info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
|
||||
+ info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
|
||||
+ info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
|
||||
+ info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
|
||||
+ info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1);
|
||||
+ info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1);
|
||||
+ info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1);
|
||||
+ info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1);
|
||||
+ info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1);
|
||||
+ info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1);
|
||||
+ info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1);
|
||||
+ info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
|
||||
+ info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
|
||||
+
|
||||
+ info->reg_mvfr0 = read_cpuid(MVFR0_EL1);
|
||||
+ info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
|
||||
+ info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
|
||||
+}
|
||||
+
|
||||
void cpuinfo_store_cpu(void)
|
||||
{
|
||||
struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
|
||||
__cpuinfo_store_cpu(info);
|
||||
+ if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
|
||||
+ __cpuinfo_store_cpu_32bit(info);
|
||||
+ /*
|
||||
+ * With asymmetric AArch32 support, populate the boot CPU information
|
||||
+ * on the first 32-bit capable secondary CPU if the primary one
|
||||
+ * skipped this step.
|
||||
+ */
|
||||
+ if (IS_ENABLED(CONFIG_ASYMMETRIC_AARCH32) &&
|
||||
+ !boot_cpu_data.aarch32_valid &&
|
||||
+ id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
|
||||
+ __cpuinfo_store_cpu_32bit(&boot_cpu_data);
|
||||
+ init_cpu_32bit_features(&boot_cpu_data);
|
||||
+ }
|
||||
update_cpu_features(smp_processor_id(), info, &boot_cpu_data);
|
||||
}
|
||||
|
||||
@@ -390,9 +405,13 @@ void __init cpuinfo_store_boot_cpu(void)
|
||||
{
|
||||
struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
|
||||
__cpuinfo_store_cpu(info);
|
||||
+ if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
|
||||
+ __cpuinfo_store_cpu_32bit(info);
|
||||
|
||||
boot_cpu_data = *info;
|
||||
init_cpu_features(&boot_cpu_data);
|
||||
+ if (id_aa64pfr0_32bit_el0(boot_cpu_data.reg_id_aa64pfr0))
|
||||
+ init_cpu_32bit_features(&boot_cpu_data);
|
||||
}
|
||||
|
||||
device_initcall(cpuinfo_regs_init);
|
||||
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
|
||||
index cc1d8b1025b1..35f0c93699ce 100644
|
||||
--- a/arch/arm64/kernel/process.c
|
||||
+++ b/arch/arm64/kernel/process.c
|
||||
@@ -494,6 +494,15 @@ static void entry_task_switch(struct task_struct *next)
|
||||
__this_cpu_write(__entry_task, next);
|
||||
}
|
||||
|
||||
+static void aarch32_thread_switch(struct task_struct *next)
|
||||
+{
|
||||
+ struct thread_info *ti = task_thread_info(next);
|
||||
+
|
||||
+ if (IS_ENABLED(CONFIG_ASYMMETRIC_AARCH32) && is_compat_thread(ti) &&
|
||||
+ !cpumask_test_cpu(smp_processor_id(), &aarch32_el0_mask))
|
||||
+ set_ti_thread_flag(ti, TIF_SET_32BIT_AFFINITY);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Thread switching.
|
||||
*/
|
||||
@@ -511,6 +520,7 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
|
||||
ptrauth_thread_switch(next);
|
||||
ssbs_thread_switch(next);
|
||||
scs_overflow_check(next);
|
||||
+ aarch32_thread_switch(next);
|
||||
|
||||
/*
|
||||
* Complete any pending TLB or cache maintenance on this CPU in case
|
||||
@@ -569,6 +579,13 @@ void arch_setup_new_exec(void)
|
||||
current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0;
|
||||
|
||||
ptrauth_thread_init_user(current);
|
||||
+
|
||||
+ /*
|
||||
+ * If exec'ing a 32-bit task, force the asymmetric 32-bit feature
|
||||
+ * check as the task may not go through a switch_to() call.
|
||||
+ */
|
||||
+ if (IS_ENABLED(CONFIG_ASYMMETRIC_AARCH32) && is_compat_task())
|
||||
+ set_thread_flag(TIF_SET_32BIT_AFFINITY);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
|
||||
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
|
||||
index dd2cdc0d5be2..d8cdd3211d68 100644
|
||||
--- a/arch/arm64/kernel/signal.c
|
||||
+++ b/arch/arm64/kernel/signal.c
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <linux/cache.h>
|
||||
#include <linux/compat.h>
|
||||
+#include <linux/cpumask.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/signal.h>
|
||||
@@ -896,6 +897,29 @@ static void do_signal(struct pt_regs *regs)
|
||||
restore_saved_sigmask();
|
||||
}
|
||||
|
||||
+static void set_32bit_cpus_allowed(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /*
|
||||
+ * Try to honour as best as possible whatever affinity request this
|
||||
+ * task has. If it spans no compatible CPU, disregard it entirely.
|
||||
+ */
|
||||
+ if (cpumask_intersects(current->cpus_ptr, &aarch32_el0_mask)) {
|
||||
+ cpumask_t cpus_allowed;
|
||||
+
|
||||
+ cpumask_and(&cpus_allowed, current->cpus_ptr, &aarch32_el0_mask);
|
||||
+ ret = set_cpus_allowed_ptr(current, &cpus_allowed);
|
||||
+ } else {
|
||||
+ ret = set_cpus_allowed_ptr(current, &aarch32_el0_mask);
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ pr_warn_once("No CPUs capable of running 32-bit tasks\n");
|
||||
+ force_sig(SIGKILL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
asmlinkage void do_notify_resume(struct pt_regs *regs,
|
||||
unsigned long thread_flags)
|
||||
{
|
||||
@@ -910,7 +934,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
|
||||
/* Check valid user FS if needed */
|
||||
addr_limit_user_check();
|
||||
|
||||
- if (thread_flags & _TIF_NEED_RESCHED) {
|
||||
+ if (IS_ENABLED(CONFIG_ASYMMETRIC_AARCH32) &&
|
||||
+ thread_flags & _TIF_SET_32BIT_AFFINITY) {
|
||||
+ clear_thread_flag(TIF_SET_32BIT_AFFINITY);
|
||||
+ set_32bit_cpus_allowed();
|
||||
+ } else if (thread_flags & _TIF_NEED_RESCHED) {
|
||||
/* Unmask Debug and SError for the next task */
|
||||
local_daif_restore(DAIF_PROCCTX_NOIRQ);
|
||||
|
||||
--
|
||||
2.29.2
|
||||
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
Upstream-Status: Backport [http://www.linux-arm.org/git?p=linux-power.git;a=commit;h=e6b567c1cc07dd1690e5d34b6a93ab9819ab2eeb]
|
||||
Signed-off-by: Usama Arif <usama.arif@arm.com>
|
||||
|
||||
From d6acb605de7d40c295ada9b1f4c8336e4db71ae4 Mon Sep 17 00:00:00 2001
|
||||
From: Valentin Schneider <valentin.schneider@arm.com>
|
||||
Date: Thu, 5 Sep 2019 17:53:19 +0100
|
||||
Subject: [PATCH 2/2] arm64: smp: Prevent hotplugging the last AArch32-able CPU
|
||||
|
||||
EL0 AArch32 tasks are now sigkilled when they can't run on any
|
||||
compatible CPU, either because there aren't any left (hotplug) or
|
||||
because they aren't allowed to run on those left (task affinity).
|
||||
|
||||
However, it has been deemed valuable to prevent the loss of
|
||||
functionality resulting in offlining the last AArch32-compatible CPU.
|
||||
|
||||
Add arch-specific hook in _cpu_down() that allows checking whether we
|
||||
can offline a cpu or not and use that hook to veto offlining the last
|
||||
AArch32 CPU.
|
||||
|
||||
Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
|
||||
Signed-off-by: Qais Yousef <qais.yousef@arm.com>
|
||||
---
|
||||
arch/arm64/kernel/smp.c | 22 ++++++++++++++++++++++
|
||||
kernel/cpu.c | 9 +++++++++
|
||||
2 files changed, 31 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
|
||||
index 038ce6263d1c..c8ab4ee29f32 100644
|
||||
--- a/arch/arm64/kernel/smp.c
|
||||
+++ b/arch/arm64/kernel/smp.c
|
||||
@@ -85,6 +85,28 @@ static inline int op_cpu_kill(unsigned int cpu)
|
||||
}
|
||||
#endif
|
||||
|
||||
+bool arch_allows_cpu_disable(int cpu, int tasks_frozen,
|
||||
+ enum cpuhp_state target)
|
||||
+{
|
||||
+ /*
|
||||
+ * Don't let the last AArch32-compatible CPU go down unless the request
|
||||
+ * is related to suspend (!tasks_frozen) then allow it to be offlined
|
||||
+ * or we'll break suspend-to-ram functionality.
|
||||
+ */
|
||||
+ if (IS_ENABLED(CONFIG_ASYMMETRIC_AARCH32) &&
|
||||
+ !cpumask_empty(&aarch32_el0_mask) &&
|
||||
+ !tasks_frozen) {
|
||||
+ cpumask_t online;
|
||||
+
|
||||
+ cpumask_and(&online, &aarch32_el0_mask, cpu_online_mask);
|
||||
+
|
||||
+ if (cpumask_weight(&online) == 1)
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
|
||||
/*
|
||||
* Boot a secondary CPU, and assign it the specified idle task.
|
||||
diff --git a/kernel/cpu.c b/kernel/cpu.c
|
||||
index 261b5098f81c..4fae9b61f442 100644
|
||||
--- a/kernel/cpu.c
|
||||
+++ b/kernel/cpu.c
|
||||
@@ -134,6 +134,12 @@ static struct cpuhp_step *cpuhp_get_step(enum cpuhp_state state)
|
||||
return cpuhp_hp_states + state;
|
||||
}
|
||||
|
||||
+bool __weak arch_allows_cpu_disable(int cpu, int tasks_frozen,
|
||||
+ enum cpuhp_state target)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* cpuhp_invoke_callback _ Invoke the callbacks for a given state
|
||||
* @cpu: The cpu for which the callback should be invoked
|
||||
@@ -985,6 +991,9 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
|
||||
if (!cpu_present(cpu))
|
||||
return -EINVAL;
|
||||
|
||||
+ if (!arch_allows_cpu_disable(cpu, tasks_frozen, target))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
cpus_write_lock();
|
||||
|
||||
cpuhp_tasks_frozen = tasks_frozen;
|
||||
--
|
||||
2.29.2
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright (c) 2020 Arm Limited
|
||||
# Copyright (c) 2021 Arm Limited
|
||||
#
|
||||
|
||||
DESCRIPTION = "Linux Android Common Kernel"
|
||||
SECTION = "kernel"
|
||||
LICENSE = "GPLv2"
|
||||
LIC_FILES_CHKSUM = "file://${S}/COPYING;md5=bbea815ee2795b2f4230826c0c6b8814"
|
||||
LIC_FILES_CHKSUM = "file://${S}/COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
|
||||
|
||||
require recipes-kernel/linux/linux-yocto.inc
|
||||
|
||||
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From 28c69b683210b5d5321ceb71e44a77bc31a32c8a Mon Sep 17 00:00:00 2001
|
||||
From: Leo Yan <leo.yan@linaro.org>
|
||||
Date: Tue, 5 May 2020 21:36:42 +0800
|
||||
Subject: [PATCH 1/4] perf cs-etm: Move definition of 'traceid_list' global
|
||||
variable from header file
|
||||
|
||||
The variable 'traceid_list' is defined in the header file cs-etm.h,
|
||||
if multiple C files include cs-etm.h the compiler might complaint for
|
||||
multiple definition of 'traceid_list'.
|
||||
|
||||
To fix multiple definition error, move the definition of 'traceid_list'
|
||||
into cs-etm.c.
|
||||
|
||||
Fixes: cd8bfd8c973e ("perf tools: Add processing of coresight metadata")
|
||||
Reported-by: Thomas Backlund <tmb@mageia.org>
|
||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
||||
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
Reviewed-by: Mike Leach <mike.leach@linaro.org>
|
||||
Tested-by: Mike Leach <mike.leach@linaro.org>
|
||||
Tested-by: Thomas Backlund <tmb@mageia.org>
|
||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
|
||||
Cc: Tor Jeremiassen <tor@ti.com>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Link: http://lore.kernel.org/lkml/20200505133642.4756-1-leo.yan@linaro.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
tools/perf/util/cs-etm.c | 3 +++
|
||||
tools/perf/util/cs-etm.h | 3 ---
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
|
||||
index f5f855fff412..50de6a1ed0ce 100644
|
||||
--- a/tools/perf/util/cs-etm.c
|
||||
+++ b/tools/perf/util/cs-etm.c
|
||||
@@ -94,6 +94,9 @@ struct cs_etm_queue {
|
||||
struct cs_etm_traceid_queue **traceid_queues;
|
||||
};
|
||||
|
||||
+/* RB tree for quick conversion between traceID and metadata pointers */
|
||||
+static struct intlist *traceid_list;
|
||||
+
|
||||
static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
|
||||
static int cs_etm__process_queues(struct cs_etm_auxtrace *etm);
|
||||
static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
|
||||
diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
|
||||
index 650ecc2a6349..4ad925d6d799 100644
|
||||
--- a/tools/perf/util/cs-etm.h
|
||||
+++ b/tools/perf/util/cs-etm.h
|
||||
@@ -114,9 +114,6 @@ enum cs_etm_isa {
|
||||
CS_ETM_ISA_T32,
|
||||
};
|
||||
|
||||
-/* RB tree for quick conversion between traceID and metadata pointers */
|
||||
-struct intlist *traceid_list;
|
||||
-
|
||||
struct cs_etm_queue;
|
||||
|
||||
struct cs_etm_packet {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From b28dc646b4c5cd3844bd591af841494dd1de0a9f Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Mon, 2 Mar 2020 11:13:19 -0300
|
||||
Subject: [PATCH 2/4] perf tests bp_account: Make global variable static
|
||||
|
||||
To fix the build with newer gccs, that without this patch exit with:
|
||||
|
||||
LD /tmp/build/perf/tests/perf-in.o
|
||||
ld: /tmp/build/perf/tests/bp_account.o:/git/perf/tools/perf/tests/bp_account.c:22: multiple definition of `the_var'; /tmp/build/perf/tests/bp_signal.o:/git/perf/tools/perf/tests/bp_signal.c:38: first defined here
|
||||
make[4]: *** [/git/perf/tools/build/Makefile.build:145: /tmp/build/perf/tests/perf-in.o] Error 1
|
||||
|
||||
First noticed in fedora:rawhide/32 with:
|
||||
|
||||
[perfbuilder@a5ff49d6e6e4 ~]$ gcc --version
|
||||
gcc (GCC) 10.0.1 20200216 (Red Hat 10.0.1-0.8)
|
||||
|
||||
Reported-by: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
tools/perf/tests/bp_account.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c
|
||||
index 016bba2c142d..55a9de311d7b 100644
|
||||
--- a/tools/perf/tests/bp_account.c
|
||||
+++ b/tools/perf/tests/bp_account.c
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "../perf-sys.h"
|
||||
#include "cloexec.h"
|
||||
|
||||
-volatile long the_var;
|
||||
+static volatile long the_var;
|
||||
|
||||
static noinline int test_function(void)
|
||||
{
|
||||
--
|
||||
2.25.1
|
||||
|
||||
-240
@@ -1,240 +0,0 @@
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From e6ae6031755b6781af42af28f11186bb18e94842 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Mon, 2 Mar 2020 12:09:38 -0300
|
||||
Subject: [PATCH 3/4] perf bench: Share some global variables to fix build with
|
||||
gcc 10
|
||||
|
||||
Noticed with gcc 10 (fedora rawhide) that those variables were not being
|
||||
declared as static, so end up with:
|
||||
|
||||
ld: /tmp/build/perf/bench/epoll-wait.o:/git/perf/tools/perf/bench/epoll-wait.c:93: multiple definition of `end'; /tmp/build/perf/bench/futex-hash.o:/git/perf/tools/perf/bench/futex-hash.c:40: first defined here
|
||||
ld: /tmp/build/perf/bench/epoll-wait.o:/git/perf/tools/perf/bench/epoll-wait.c:93: multiple definition of `start'; /tmp/build/perf/bench/futex-hash.o:/git/perf/tools/perf/bench/futex-hash.c:40: first defined here
|
||||
ld: /tmp/build/perf/bench/epoll-wait.o:/git/perf/tools/perf/bench/epoll-wait.c:93: multiple definition of `runtime'; /tmp/build/perf/bench/futex-hash.o:/git/perf/tools/perf/bench/futex-hash.c:40: first defined here
|
||||
ld: /tmp/build/perf/bench/epoll-ctl.o:/git/perf/tools/perf/bench/epoll-ctl.c:38: multiple definition of `end'; /tmp/build/perf/bench/futex-hash.o:/git/perf/tools/perf/bench/futex-hash.c:40: first defined here
|
||||
ld: /tmp/build/perf/bench/epoll-ctl.o:/git/perf/tools/perf/bench/epoll-ctl.c:38: multiple definition of `start'; /tmp/build/perf/bench/futex-hash.o:/git/perf/tools/perf/bench/futex-hash.c:40: first defined here
|
||||
ld: /tmp/build/perf/bench/epoll-ctl.o:/git/perf/tools/perf/bench/epoll-ctl.c:38: multiple definition of `runtime'; /tmp/build/perf/bench/futex-hash.o:/git/perf/tools/perf/bench/futex-hash.c:40: first defined here
|
||||
make[4]: *** [/git/perf/tools/build/Makefile.build:145: /tmp/build/perf/bench/perf-in.o] Error 1
|
||||
|
||||
Prefix those with bench__ and add them to bench/bench.h, so that we can
|
||||
share those on the tools needing to access those variables from signal
|
||||
handlers.
|
||||
|
||||
Acked-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: Davidlohr Bueso <dave@stgolabs.net>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Link: http://lore.kernel.org/lkml/20200303155811.GD13702@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
tools/perf/bench/bench.h | 4 ++++
|
||||
tools/perf/bench/epoll-ctl.c | 7 +++----
|
||||
tools/perf/bench/epoll-wait.c | 11 +++++------
|
||||
tools/perf/bench/futex-hash.c | 12 ++++++------
|
||||
tools/perf/bench/futex-lock-pi.c | 11 +++++------
|
||||
5 files changed, 23 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
|
||||
index fddb3ced9db6..4aa6de1aa67d 100644
|
||||
--- a/tools/perf/bench/bench.h
|
||||
+++ b/tools/perf/bench/bench.h
|
||||
@@ -2,6 +2,10 @@
|
||||
#ifndef BENCH_H
|
||||
#define BENCH_H
|
||||
|
||||
+#include <sys/time.h>
|
||||
+
|
||||
+extern struct timeval bench__start, bench__end, bench__runtime;
|
||||
+
|
||||
/*
|
||||
* The madvise transparent hugepage constants were added in glibc
|
||||
* 2.13. For compatibility with older versions of glibc, define these
|
||||
diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c
|
||||
index bb617e568841..a7526c05df38 100644
|
||||
--- a/tools/perf/bench/epoll-ctl.c
|
||||
+++ b/tools/perf/bench/epoll-ctl.c
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
static unsigned int nthreads = 0;
|
||||
static unsigned int nsecs = 8;
|
||||
-struct timeval start, end, runtime;
|
||||
static bool done, __verbose, randomize;
|
||||
|
||||
/*
|
||||
@@ -94,8 +93,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
- gettimeofday(&end, NULL);
|
||||
- timersub(&end, &start, &runtime);
|
||||
+ gettimeofday(&bench__end, NULL);
|
||||
+ timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void nest_epollfd(void)
|
||||
@@ -361,7 +360,7 @@ int bench_epoll_ctl(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
|
||||
- gettimeofday(&start, NULL);
|
||||
+ gettimeofday(&bench__start, NULL);
|
||||
|
||||
do_threads(worker, cpu);
|
||||
|
||||
diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c
|
||||
index 7af694437f4e..d1c5cb526b9f 100644
|
||||
--- a/tools/perf/bench/epoll-wait.c
|
||||
+++ b/tools/perf/bench/epoll-wait.c
|
||||
@@ -90,7 +90,6 @@
|
||||
|
||||
static unsigned int nthreads = 0;
|
||||
static unsigned int nsecs = 8;
|
||||
-struct timeval start, end, runtime;
|
||||
static bool wdone, done, __verbose, randomize, nonblocking;
|
||||
|
||||
/*
|
||||
@@ -276,8 +275,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
- gettimeofday(&end, NULL);
|
||||
- timersub(&end, &start, &runtime);
|
||||
+ gettimeofday(&bench__end, NULL);
|
||||
+ timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void print_summary(void)
|
||||
@@ -287,7 +286,7 @@ static void print_summary(void)
|
||||
|
||||
printf("\nAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
|
||||
avg, rel_stddev_stats(stddev, avg),
|
||||
- (int) runtime.tv_sec);
|
||||
+ (int)bench__runtime.tv_sec);
|
||||
}
|
||||
|
||||
static int do_threads(struct worker *worker, struct perf_cpu_map *cpu)
|
||||
@@ -479,7 +478,7 @@ int bench_epoll_wait(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
|
||||
- gettimeofday(&start, NULL);
|
||||
+ gettimeofday(&bench__start, NULL);
|
||||
|
||||
do_threads(worker, cpu);
|
||||
|
||||
@@ -519,7 +518,7 @@ int bench_epoll_wait(int argc, const char **argv)
|
||||
qsort(worker, nthreads, sizeof(struct worker), cmpworker);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
- unsigned long t = worker[i].ops/runtime.tv_sec;
|
||||
+ unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
|
||||
update_stats(&throughput_stats, t);
|
||||
|
||||
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
|
||||
index 8ba0c3330a9a..21776862e940 100644
|
||||
--- a/tools/perf/bench/futex-hash.c
|
||||
+++ b/tools/perf/bench/futex-hash.c
|
||||
@@ -37,7 +37,7 @@ static unsigned int nfutexes = 1024;
|
||||
static bool fshared = false, done = false, silent = false;
|
||||
static int futex_flag = 0;
|
||||
|
||||
-struct timeval start, end, runtime;
|
||||
+struct timeval bench__start, bench__end, bench__runtime;
|
||||
static pthread_mutex_t thread_lock;
|
||||
static unsigned int threads_starting;
|
||||
static struct stats throughput_stats;
|
||||
@@ -103,8 +103,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
- gettimeofday(&end, NULL);
|
||||
- timersub(&end, &start, &runtime);
|
||||
+ gettimeofday(&bench__end, NULL);
|
||||
+ timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void print_summary(void)
|
||||
@@ -114,7 +114,7 @@ static void print_summary(void)
|
||||
|
||||
printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
|
||||
!silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
|
||||
- (int) runtime.tv_sec);
|
||||
+ (int)bench__runtime.tv_sec);
|
||||
}
|
||||
|
||||
int bench_futex_hash(int argc, const char **argv)
|
||||
@@ -161,7 +161,7 @@ int bench_futex_hash(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
pthread_attr_init(&thread_attr);
|
||||
- gettimeofday(&start, NULL);
|
||||
+ gettimeofday(&bench__start, NULL);
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
worker[i].tid = i;
|
||||
worker[i].futex = calloc(nfutexes, sizeof(*worker[i].futex));
|
||||
@@ -204,7 +204,7 @@ int bench_futex_hash(int argc, const char **argv)
|
||||
pthread_mutex_destroy(&thread_lock);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
- unsigned long t = worker[i].ops/runtime.tv_sec;
|
||||
+ unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
update_stats(&throughput_stats, t);
|
||||
if (!silent) {
|
||||
if (nfutexes == 1)
|
||||
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
|
||||
index d0cae8125423..30d97121dc4f 100644
|
||||
--- a/tools/perf/bench/futex-lock-pi.c
|
||||
+++ b/tools/perf/bench/futex-lock-pi.c
|
||||
@@ -37,7 +37,6 @@ static bool silent = false, multi = false;
|
||||
static bool done = false, fshared = false;
|
||||
static unsigned int nthreads = 0;
|
||||
static int futex_flag = 0;
|
||||
-struct timeval start, end, runtime;
|
||||
static pthread_mutex_t thread_lock;
|
||||
static unsigned int threads_starting;
|
||||
static struct stats throughput_stats;
|
||||
@@ -64,7 +63,7 @@ static void print_summary(void)
|
||||
|
||||
printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
|
||||
!silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
|
||||
- (int) runtime.tv_sec);
|
||||
+ (int)bench__runtime.tv_sec);
|
||||
}
|
||||
|
||||
static void toggle_done(int sig __maybe_unused,
|
||||
@@ -73,8 +72,8 @@ static void toggle_done(int sig __maybe_unused,
|
||||
{
|
||||
/* inform all threads that we're done for the day */
|
||||
done = true;
|
||||
- gettimeofday(&end, NULL);
|
||||
- timersub(&end, &start, &runtime);
|
||||
+ gettimeofday(&bench__end, NULL);
|
||||
+ timersub(&bench__end, &bench__start, &bench__runtime);
|
||||
}
|
||||
|
||||
static void *workerfn(void *arg)
|
||||
@@ -185,7 +184,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
|
||||
|
||||
threads_starting = nthreads;
|
||||
pthread_attr_init(&thread_attr);
|
||||
- gettimeofday(&start, NULL);
|
||||
+ gettimeofday(&bench__start, NULL);
|
||||
|
||||
create_threads(worker, thread_attr, cpu);
|
||||
pthread_attr_destroy(&thread_attr);
|
||||
@@ -211,7 +210,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
|
||||
pthread_mutex_destroy(&thread_lock);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
- unsigned long t = worker[i].ops/runtime.tv_sec;
|
||||
+ unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
|
||||
update_stats(&throughput_stats, t);
|
||||
if (!silent)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From c2c2c58915def6cda401d1782048d23b2b02ed85 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Sat, 25 Jul 2020 02:06:23 +0100
|
||||
Subject: [PATCH 4/4] libtraceevent: Fix build with binutils 2.35
|
||||
|
||||
In binutils 2.35, 'nm -D' changed to show symbol versions along with
|
||||
symbol names, with the usual @@ separator. When generating
|
||||
libtraceevent-dynamic-list we need just the names, so strip off the
|
||||
version suffix if present.
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Tested-by: Salvatore Bonaccorso <carnil@debian.org>
|
||||
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
|
||||
Cc: linux-trace-devel@vger.kernel.org
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
tools/lib/traceevent/plugins/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/lib/traceevent/plugins/Makefile b/tools/lib/traceevent/plugins/Makefile
|
||||
index f440989fa55e..23c3535bcbd6 100644
|
||||
--- a/tools/lib/traceevent/plugins/Makefile
|
||||
+++ b/tools/lib/traceevent/plugins/Makefile
|
||||
@@ -196,7 +196,7 @@ define do_generate_dynamic_list_file
|
||||
xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\
|
||||
if [ "$$symbol_type" = "U W" ];then \
|
||||
(echo '{'; \
|
||||
- $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\
|
||||
+ $(NM) -u -D $1 | awk 'NF>1 {sub("@.*", "", $$2); print "\t"$$2";"}' | sort -u;\
|
||||
echo '};'; \
|
||||
) > $2; \
|
||||
else \
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright (c) 2021 Arm Limited
|
||||
#
|
||||
require linux-arm64-ack.inc
|
||||
|
||||
SRC_URI = " \
|
||||
git://android.googlesource.com/kernel/common.git;protocol=https;branch=android12-5.10-lts \
|
||||
"
|
||||
|
||||
# tag: ASB-2021-06-05_12-5.10
|
||||
SRCREV = "00dc4c64e6592a2e469f7886a6a927778c4a2806"
|
||||
@@ -1,16 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Copyright (c) 2020 Arm Limited
|
||||
#
|
||||
require linux-arm64-ack.inc
|
||||
|
||||
SRC_URI = " \
|
||||
git://android.googlesource.com/kernel/common.git;protocol=https;branch=android11-5.4-lts \
|
||||
file://0001-perf-cs-etm-Move-definition-of-traceid_list-global-v.patch \
|
||||
file://0002-perf-tests-bp_account-Make-global-variable-static.patch \
|
||||
file://0003-perf-bench-Share-some-global-variables-to-fix-build-.patch \
|
||||
file://0004-libtraceevent-Fix-build-with-binutils-2.35.patch \
|
||||
"
|
||||
|
||||
# ASB-2020-07-05_5.4-stable tag commit
|
||||
SRCREV = "056684c0d252f75c13be4abb7408f692eedab653"
|
||||
Reference in New Issue
Block a user