aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuzuki K. Poulose <suzuki.poulose@arm.com>2015-03-18 08:24:40 -0400
committerWill Deacon <will.deacon@arm.com>2015-03-27 09:44:35 -0400
commit772742a6c7ea4612fe043353531e6435ed33e719 (patch)
tree947c0f53161efdec39acab32c6cc246d33f2ee8f
parentfc17c839448e498393009e06ca30a204eefaccee (diff)
arm-cci: Get rid of secure transactions for PMU driver
Avoid secure transactions while probing the CCI PMU. The existing code makes use of the Peripheral ID2 (PID2) register to determine the revision of the CCI400, which requires a secure transaction. This puts a limitation on the usage of the driver on systems running non-secure Linux(e.g, ARM64). Updated the device-tree binding for cci pmu node to add the explicit revision number for the compatible field. The supported strings are : arm,cci-400-pmu,r0 arm,cci-400-pmu,r1 arm,cci-400-pmu - DEPRECATED. See NOTE below NOTE: If the revision is not mentioned, we need to probe the cci revision, which could be fatal on a platform running non-secure. We need a reliable way to know if we can poke the CCI registers at runtime on ARM32. We depend on 'mcpm_is_available()' when it is available. mcpm_is_available() returns true only when there is a registered driver for mcpm. Otherwise, we assume that we don't have secure access, and skips probing the revision number(ARM64 case). The MCPM should figure out if it is safe to access the CCI. Unfortunately there isn't a reliable way to indicate the same via dtb. This patch doesn't address/change the current situation. It only deals with the CCI-PMU, leaving the assumptions about the secure access as it has been, prior to this patch. Cc: devicetree@vger.kernel.org Cc: Punit Agrawal <punit.agrawal@arm.com> Tested-by: Sudeep Holla <sudeep.holla@arm.com> Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--Documentation/devicetree/bindings/arm/cci.txt7
-rw-r--r--arch/arm/include/asm/arm-cci.h42
-rw-r--r--arch/arm64/include/asm/arm-cci.h27
-rw-r--r--drivers/bus/arm-cci.c17
-rw-r--r--include/linux/arm-cci.h2
5 files changed, 92 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/arm/cci.txt b/Documentation/devicetree/bindings/arm/cci.txt
index f28d82bbbc56..3c5c631328d3 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -94,8 +94,11 @@ specific to ARM.
94 - compatible 94 - compatible
95 Usage: required 95 Usage: required
96 Value type: <string> 96 Value type: <string>
97 Definition: must be "arm,cci-400-pmu" 97 Definition: Must contain one of:
98 98 "arm,cci-400-pmu,r0"
99 "arm,cci-400-pmu,r1"
100 "arm,cci-400-pmu" - DEPRECATED, permitted only where OS has
101 secure acces to CCI registers
99 - reg: 102 - reg:
100 Usage: required 103 Usage: required
101 Value type: Integer cells. A register entry, expressed 104 Value type: Integer cells. A register entry, expressed
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000000000000..fe77f7ab7e6b
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
1/*
2 * arch/arm/include/asm/arm-cci.h
3 *
4 * Copyright (C) 2015 ARM Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __ASM_ARM_CCI_H
20#define __ASM_ARM_CCI_H
21
22#ifdef CONFIG_MCPM
23#include <asm/mcpm.h>
24
25/*
26 * We don't have a reliable way of detecting whether,
27 * if we have access to secure-only registers, unless
28 * mcpm is registered.
29 */
30static inline bool platform_has_secure_cci_access(void)
31{
32 return mcpm_is_available();
33}
34
35#else
36static inline bool platform_has_secure_cci_access(void)
37{
38 return false;
39}
40#endif
41
42#endif
diff --git a/arch/arm64/include/asm/arm-cci.h b/arch/arm64/include/asm/arm-cci.h
new file mode 100644
index 000000000000..f0b63712e10e
--- /dev/null
+++ b/arch/arm64/include/asm/arm-cci.h
@@ -0,0 +1,27 @@
1/*
2 * arch/arm64/include/asm/arm-cci.h
3 *
4 * Copyright (C) 2015 ARM Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __ASM_ARM_CCI_H
20#define __ASM_ARM_CCI_H
21
22static inline bool platform_has_secure_cci_access(void)
23{
24 return false;
25}
26
27#endif
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index ae3864d95e6c..a23663c7a306 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -217,7 +217,9 @@ static int probe_cci_revision(void)
217 217
218static const struct cci_pmu_model *probe_cci_model(struct platform_device *pdev) 218static const struct cci_pmu_model *probe_cci_model(struct platform_device *pdev)
219{ 219{
220 return &cci_pmu_models[probe_cci_revision()]; 220 if (platform_has_secure_cci_access())
221 return &cci_pmu_models[probe_cci_revision()];
222 return NULL;
221} 223}
222 224
223static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx) 225static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
@@ -882,6 +884,15 @@ static struct cci_pmu_model cci_pmu_models[] = {
882static const struct of_device_id arm_cci_pmu_matches[] = { 884static const struct of_device_id arm_cci_pmu_matches[] = {
883 { 885 {
884 .compatible = "arm,cci-400-pmu", 886 .compatible = "arm,cci-400-pmu",
887 .data = NULL,
888 },
889 {
890 .compatible = "arm,cci-400-pmu,r0",
891 .data = &cci_pmu_models[CCI_REV_R0],
892 },
893 {
894 .compatible = "arm,cci-400-pmu,r1",
895 .data = &cci_pmu_models[CCI_REV_R1],
885 }, 896 },
886 {}, 897 {},
887}; 898};
@@ -892,7 +903,11 @@ static inline const struct cci_pmu_model *get_cci_model(struct platform_device *
892 pdev->dev.of_node); 903 pdev->dev.of_node);
893 if (!match) 904 if (!match)
894 return NULL; 905 return NULL;
906 if (match->data)
907 return match->data;
895 908
909 dev_warn(&pdev->dev, "DEPRECATED compatible property,"
910 "requires secure access to CCI registers");
896 return probe_cci_model(pdev); 911 return probe_cci_model(pdev);
897} 912}
898 913
diff --git a/include/linux/arm-cci.h b/include/linux/arm-cci.h
index 79d6edf446d5..aede5c765eec 100644
--- a/include/linux/arm-cci.h
+++ b/include/linux/arm-cci.h
@@ -24,6 +24,8 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/types.h> 25#include <linux/types.h>
26 26
27#include <asm/arm-cci.h>
28
27struct device_node; 29struct device_node;
28 30
29#ifdef CONFIG_ARM_CCI 31#ifdef CONFIG_ARM_CCI