Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 1 | Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e3f9da608f14cfebac2659d8dd8737b79d01308] |
| 2 | Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> |
| 3 | |
| 4 | From a8f3e351c07c48774be2a45e184b9f08dc92f1db Mon Sep 17 00:00:00 2001 |
| 5 | From: Sudeep Holla <sudeep.holla@arm.com> |
| 6 | Date: Wed, 13 Apr 2022 15:43:19 +0100 |
| 7 | Subject: [PATCH] UPSTREAM: firmware: arm_ffa: Handle compatibility with |
| 8 | different firmware versions |
| 9 | |
| 10 | The driver currently just support v1.0 of Arm FFA specification. It also |
| 11 | expects the firmware implementation to match the same and bail out if it |
| 12 | doesn't match. This is causing issue when running with higher version of |
| 13 | firmware implementation(e.g. v1.1 which will released soon). |
| 14 | |
| 15 | In order to support compatibility with different firmware versions, let |
| 16 | us add additional checks and find the compatible version the driver can |
| 17 | work with. |
| 18 | |
| 19 | Link: https://lore.kernel.org/r/20211013091127.990992-1-sudeep.holla@arm.com |
| 20 | Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org> |
| 21 | Signed-off-by: Sudeep Holla <sudeep.holla@arm.com> |
| 22 | (cherry picked from commit 8e3f9da608f14cfebac2659d8dd8737b79d01308) |
| 23 | Change-Id: I7bc9a3b172a9067bfd4e9bb9d50b4729e915b5a5 |
| 24 | Bug: 168585974 |
| 25 | --- |
| 26 | drivers/firmware/arm_ffa/driver.c | 37 ++++++++++++++++++++++++++----- |
| 27 | 1 file changed, 32 insertions(+), 5 deletions(-) |
| 28 | |
| 29 | diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c |
| 30 | index 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 | -- |
| 89 | 2.17.1 |
| 90 | |