.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * System Control and Power Interface (SCPI) Message Protocol driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
11 | 12 | * clocks configuration, thermal sensors and many others. |
---|
12 | 13 | * |
---|
13 | 14 | * Copyright (C) 2015 ARM Ltd. |
---|
14 | | - * |
---|
15 | | - * This program is free software; you can redistribute it and/or modify it |
---|
16 | | - * under the terms and conditions of the GNU General Public License, |
---|
17 | | - * version 2, as published by the Free Software Foundation. |
---|
18 | | - * |
---|
19 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
20 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
21 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
22 | | - * more details. |
---|
23 | | - * |
---|
24 | | - * You should have received a copy of the GNU General Public License along |
---|
25 | | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
26 | 15 | */ |
---|
27 | 16 | |
---|
28 | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
273 | 262 | struct scpi_shared_mem { |
---|
274 | 263 | __le32 command; |
---|
275 | 264 | __le32 status; |
---|
276 | | - u8 payload[0]; |
---|
| 265 | + u8 payload[]; |
---|
277 | 266 | } __packed; |
---|
278 | 267 | |
---|
279 | 268 | struct legacy_scpi_shared_mem { |
---|
280 | 269 | __le32 status; |
---|
281 | | - u8 payload[0]; |
---|
| 270 | + u8 payload[]; |
---|
282 | 271 | } __packed; |
---|
283 | 272 | |
---|
284 | 273 | struct scp_capabilities { |
---|
.. | .. |
---|
826 | 815 | info->firmware_version = le32_to_cpu(caps.platform_version); |
---|
827 | 816 | } |
---|
828 | 817 | /* Ignore error if not implemented */ |
---|
829 | | - if (scpi_info->is_legacy && ret == -EOPNOTSUPP) |
---|
| 818 | + if (info->is_legacy && ret == -EOPNOTSUPP) |
---|
830 | 819 | return 0; |
---|
831 | 820 | |
---|
832 | 821 | return ret; |
---|
.. | .. |
---|
916 | 905 | struct resource res; |
---|
917 | 906 | struct device *dev = &pdev->dev; |
---|
918 | 907 | struct device_node *np = dev->of_node; |
---|
| 908 | + struct scpi_drvinfo *scpi_drvinfo; |
---|
919 | 909 | |
---|
920 | | - scpi_info = devm_kzalloc(dev, sizeof(*scpi_info), GFP_KERNEL); |
---|
921 | | - if (!scpi_info) |
---|
| 910 | + scpi_drvinfo = devm_kzalloc(dev, sizeof(*scpi_drvinfo), GFP_KERNEL); |
---|
| 911 | + if (!scpi_drvinfo) |
---|
922 | 912 | return -ENOMEM; |
---|
923 | 913 | |
---|
924 | 914 | if (of_match_device(legacy_scpi_of_match, &pdev->dev)) |
---|
925 | | - scpi_info->is_legacy = true; |
---|
| 915 | + scpi_drvinfo->is_legacy = true; |
---|
926 | 916 | |
---|
927 | 917 | count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); |
---|
928 | 918 | if (count < 0) { |
---|
.. | .. |
---|
930 | 920 | return -ENODEV; |
---|
931 | 921 | } |
---|
932 | 922 | |
---|
933 | | - scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan), |
---|
934 | | - GFP_KERNEL); |
---|
935 | | - if (!scpi_info->channels) |
---|
| 923 | + scpi_drvinfo->channels = |
---|
| 924 | + devm_kcalloc(dev, count, sizeof(struct scpi_chan), GFP_KERNEL); |
---|
| 925 | + if (!scpi_drvinfo->channels) |
---|
936 | 926 | return -ENOMEM; |
---|
937 | 927 | |
---|
938 | | - ret = devm_add_action(dev, scpi_free_channels, scpi_info); |
---|
| 928 | + ret = devm_add_action(dev, scpi_free_channels, scpi_drvinfo); |
---|
939 | 929 | if (ret) |
---|
940 | 930 | return ret; |
---|
941 | 931 | |
---|
942 | | - for (; scpi_info->num_chans < count; scpi_info->num_chans++) { |
---|
| 932 | + for (; scpi_drvinfo->num_chans < count; scpi_drvinfo->num_chans++) { |
---|
943 | 933 | resource_size_t size; |
---|
944 | | - int idx = scpi_info->num_chans; |
---|
945 | | - struct scpi_chan *pchan = scpi_info->channels + idx; |
---|
| 934 | + int idx = scpi_drvinfo->num_chans; |
---|
| 935 | + struct scpi_chan *pchan = scpi_drvinfo->channels + idx; |
---|
946 | 936 | struct mbox_client *cl = &pchan->cl; |
---|
947 | 937 | struct device_node *shmem = of_parse_phandle(np, "shmem", idx); |
---|
948 | 938 | |
---|
.. | .. |
---|
986 | 976 | return ret; |
---|
987 | 977 | } |
---|
988 | 978 | |
---|
989 | | - scpi_info->commands = scpi_std_commands; |
---|
| 979 | + scpi_drvinfo->commands = scpi_std_commands; |
---|
990 | 980 | |
---|
991 | | - platform_set_drvdata(pdev, scpi_info); |
---|
| 981 | + platform_set_drvdata(pdev, scpi_drvinfo); |
---|
992 | 982 | |
---|
993 | | - if (scpi_info->is_legacy) { |
---|
| 983 | + if (scpi_drvinfo->is_legacy) { |
---|
994 | 984 | /* Replace with legacy variants */ |
---|
995 | 985 | scpi_ops.clk_set_val = legacy_scpi_clk_set_val; |
---|
996 | | - scpi_info->commands = scpi_legacy_commands; |
---|
| 986 | + scpi_drvinfo->commands = scpi_legacy_commands; |
---|
997 | 987 | |
---|
998 | 988 | /* Fill priority bitmap */ |
---|
999 | 989 | for (idx = 0; idx < ARRAY_SIZE(legacy_hpriority_cmds); idx++) |
---|
1000 | 990 | set_bit(legacy_hpriority_cmds[idx], |
---|
1001 | | - scpi_info->cmd_priority); |
---|
| 991 | + scpi_drvinfo->cmd_priority); |
---|
1002 | 992 | } |
---|
1003 | 993 | |
---|
1004 | | - ret = scpi_init_versions(scpi_info); |
---|
| 994 | + scpi_info = scpi_drvinfo; |
---|
| 995 | + |
---|
| 996 | + ret = scpi_init_versions(scpi_drvinfo); |
---|
1005 | 997 | if (ret) { |
---|
1006 | 998 | dev_err(dev, "incorrect or no SCP firmware found\n"); |
---|
| 999 | + scpi_info = NULL; |
---|
1007 | 1000 | return ret; |
---|
1008 | 1001 | } |
---|
1009 | 1002 | |
---|
1010 | | - if (scpi_info->is_legacy && !scpi_info->protocol_version && |
---|
1011 | | - !scpi_info->firmware_version) |
---|
| 1003 | + if (scpi_drvinfo->is_legacy && !scpi_drvinfo->protocol_version && |
---|
| 1004 | + !scpi_drvinfo->firmware_version) |
---|
1012 | 1005 | dev_info(dev, "SCP Protocol legacy pre-1.0 firmware\n"); |
---|
1013 | 1006 | else |
---|
1014 | 1007 | dev_info(dev, "SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n", |
---|
1015 | 1008 | FIELD_GET(PROTO_REV_MAJOR_MASK, |
---|
1016 | | - scpi_info->protocol_version), |
---|
| 1009 | + scpi_drvinfo->protocol_version), |
---|
1017 | 1010 | FIELD_GET(PROTO_REV_MINOR_MASK, |
---|
1018 | | - scpi_info->protocol_version), |
---|
| 1011 | + scpi_drvinfo->protocol_version), |
---|
1019 | 1012 | FIELD_GET(FW_REV_MAJOR_MASK, |
---|
1020 | | - scpi_info->firmware_version), |
---|
| 1013 | + scpi_drvinfo->firmware_version), |
---|
1021 | 1014 | FIELD_GET(FW_REV_MINOR_MASK, |
---|
1022 | | - scpi_info->firmware_version), |
---|
| 1015 | + scpi_drvinfo->firmware_version), |
---|
1023 | 1016 | FIELD_GET(FW_REV_PATCH_MASK, |
---|
1024 | | - scpi_info->firmware_version)); |
---|
1025 | | - scpi_info->scpi_ops = &scpi_ops; |
---|
| 1017 | + scpi_drvinfo->firmware_version)); |
---|
1026 | 1018 | |
---|
1027 | | - ret = devm_device_add_groups(dev, versions_groups); |
---|
| 1019 | + scpi_drvinfo->scpi_ops = &scpi_ops; |
---|
| 1020 | + |
---|
| 1021 | + ret = devm_of_platform_populate(dev); |
---|
1028 | 1022 | if (ret) |
---|
1029 | | - dev_err(dev, "unable to create sysfs version group\n"); |
---|
| 1023 | + scpi_info = NULL; |
---|
1030 | 1024 | |
---|
1031 | | - return devm_of_platform_populate(dev); |
---|
| 1025 | + return ret; |
---|
1032 | 1026 | } |
---|
1033 | 1027 | |
---|
1034 | 1028 | static const struct of_device_id scpi_of_match[] = { |
---|
.. | .. |
---|
1043 | 1037 | .driver = { |
---|
1044 | 1038 | .name = "scpi_protocol", |
---|
1045 | 1039 | .of_match_table = scpi_of_match, |
---|
| 1040 | + .dev_groups = versions_groups, |
---|
1046 | 1041 | }, |
---|
1047 | 1042 | .probe = scpi_probe, |
---|
1048 | 1043 | .remove = scpi_remove, |
---|