blob: a4fd67308450c6251f06e8dabc87e0d41effdf97 [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e3f9da608f14cfebac2659d8dd8737b79d01308]
2Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
3
4From a8f3e351c07c48774be2a45e184b9f08dc92f1db Mon Sep 17 00:00:00 2001
5From: Sudeep Holla <sudeep.holla@arm.com>
6Date: Wed, 13 Apr 2022 15:43:19 +0100
7Subject: [PATCH] UPSTREAM: firmware: arm_ffa: Handle compatibility with
8 different firmware versions
9
10The driver currently just support v1.0 of Arm FFA specification. It also
11expects the firmware implementation to match the same and bail out if it
12doesn't match. This is causing issue when running with higher version of
13firmware implementation(e.g. v1.1 which will released soon).
14
15In order to support compatibility with different firmware versions, let
16us add additional checks and find the compatible version the driver can
17work with.
18
19Link: https://lore.kernel.org/r/20211013091127.990992-1-sudeep.holla@arm.com
20Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
21Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
22(cherry picked from commit 8e3f9da608f14cfebac2659d8dd8737b79d01308)
23Change-Id: I7bc9a3b172a9067bfd4e9bb9d50b4729e915b5a5
24Bug: 168585974
25---
26 drivers/firmware/arm_ffa/driver.c | 37 ++++++++++++++++++++++++++-----
27 1 file changed, 32 insertions(+), 5 deletions(-)
28
29diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
30index c9fb56afbcb4..6e0c883ab708 100644
31--- a/drivers/firmware/arm_ffa/driver.c
32+++ b/drivers/firmware/arm_ffa/driver.c
33@@ -167,6 +167,28 @@ struct ffa_drv_info {
34
35 static struct ffa_drv_info *drv_info;
36
37+/*
38+ * The driver must be able to support all the versions from the earliest
39+ * supported FFA_MIN_VERSION to the latest supported FFA_DRIVER_VERSION.
40+ * The specification states that if firmware supports a FFA implementation
41+ * that is incompatible with and at a greater version number than specified
42+ * by the caller(FFA_DRIVER_VERSION passed as parameter to FFA_VERSION),
43+ * it must return the NOT_SUPPORTED error code.
44+ */
45+static u32 ffa_compatible_version_find(u32 version)
46+{
47+ u32 compat_version;
48+ u16 major = MAJOR_VERSION(version), minor = MINOR_VERSION(version);
49+ u16 drv_major = MAJOR_VERSION(FFA_DRIVER_VERSION);
50+ u16 drv_minor = MINOR_VERSION(FFA_DRIVER_VERSION);
51+
52+ if ((major < drv_major) || (major == drv_major && minor <= drv_minor))
53+ return version;
54+
55+ pr_info("Firmware version higher than driver version, downgrading\n");
56+ return FFA_DRIVER_VERSION;
57+}
58+
59 static int ffa_version_check(u32 *version)
60 {
61 ffa_value_t ver;
62@@ -180,15 +202,20 @@ static int ffa_version_check(u32 *version)
63 return -EOPNOTSUPP;
64 }
65
66- if (ver.a0 < FFA_MIN_VERSION || ver.a0 > FFA_DRIVER_VERSION) {
67- pr_err("Incompatible version %d.%d found\n",
68- MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0));
69+ if (ver.a0 < FFA_MIN_VERSION) {
70+ pr_err("Incompatible v%d.%d! Earliest supported v%d.%d\n",
71+ MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0),
72+ MAJOR_VERSION(FFA_MIN_VERSION),
73+ MINOR_VERSION(FFA_MIN_VERSION));
74 return -EINVAL;
75 }
76
77- *version = ver.a0;
78- pr_info("Version %d.%d found\n", MAJOR_VERSION(ver.a0),
79+ pr_info("Driver version %d.%d\n", MAJOR_VERSION(FFA_DRIVER_VERSION),
80+ MINOR_VERSION(FFA_DRIVER_VERSION));
81+ pr_info("Firmware version %d.%d found\n", MAJOR_VERSION(ver.a0),
82 MINOR_VERSION(ver.a0));
83+ *version = ffa_compatible_version_find(ver.a0);
84+
85 return 0;
86 }
87
88--
892.17.1
90