| .. | .. |
|---|
| 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, |
|---|