diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2017-09-29 17:44:09 -0400 |
---|---|---|
committer | Sudeep Holla <sudeep.holla@arm.com> | 2017-10-04 06:09:47 -0400 |
commit | 27c54cd3142184b7798e082d06c17135cafb3f60 (patch) | |
tree | bbf86df816425c5e717841da06c0abcb2d92fc77 /drivers/firmware | |
parent | 931cf0c53e6999375eac65f3650a656b88634b9d (diff) |
firmware: arm_scpi: make freeing mbox channels device-managed
Make freeing the mbox channels device-managed, thus further simplifying
scpi_remove and and one further step to get rid of scpi_remove.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/arm_scpi.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 97a22a73c2d2..ee19b365c289 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c | |||
@@ -893,16 +893,13 @@ static struct attribute *versions_attrs[] = { | |||
893 | }; | 893 | }; |
894 | ATTRIBUTE_GROUPS(versions); | 894 | ATTRIBUTE_GROUPS(versions); |
895 | 895 | ||
896 | static void | 896 | static void scpi_free_channels(void *data) |
897 | scpi_free_channels(struct device *dev, struct scpi_chan *pchan, int count) | ||
898 | { | 897 | { |
898 | struct scpi_drvinfo *info = data; | ||
899 | int i; | 899 | int i; |
900 | 900 | ||
901 | for (i = 0; i < count && pchan->chan; i++, pchan++) { | 901 | for (i = 0; i < info->num_chans; i++) |
902 | mbox_free_channel(pchan->chan); | 902 | mbox_free_channel(info->channels[i].chan); |
903 | devm_kfree(dev, pchan->xfers); | ||
904 | devm_iounmap(dev, pchan->rx_payload); | ||
905 | } | ||
906 | } | 903 | } |
907 | 904 | ||
908 | static int scpi_remove(struct platform_device *pdev) | 905 | static int scpi_remove(struct platform_device *pdev) |
@@ -911,7 +908,6 @@ static int scpi_remove(struct platform_device *pdev) | |||
911 | 908 | ||
912 | of_platform_depopulate(dev); | 909 | of_platform_depopulate(dev); |
913 | sysfs_remove_groups(&dev->kobj, versions_groups); | 910 | sysfs_remove_groups(&dev->kobj, versions_groups); |
914 | scpi_free_channels(dev, scpi_info->channels, scpi_info->num_chans); | ||
915 | 911 | ||
916 | return 0; | 912 | return 0; |
917 | } | 913 | } |
@@ -944,7 +940,6 @@ static int scpi_probe(struct platform_device *pdev) | |||
944 | { | 940 | { |
945 | int count, idx, ret; | 941 | int count, idx, ret; |
946 | struct resource res; | 942 | struct resource res; |
947 | struct scpi_chan *scpi_chan; | ||
948 | struct device *dev = &pdev->dev; | 943 | struct device *dev = &pdev->dev; |
949 | struct device_node *np = dev->of_node; | 944 | struct device_node *np = dev->of_node; |
950 | 945 | ||
@@ -961,13 +956,19 @@ static int scpi_probe(struct platform_device *pdev) | |||
961 | return -ENODEV; | 956 | return -ENODEV; |
962 | } | 957 | } |
963 | 958 | ||
964 | scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL); | 959 | scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan), |
965 | if (!scpi_chan) | 960 | GFP_KERNEL); |
961 | if (!scpi_info->channels) | ||
966 | return -ENOMEM; | 962 | return -ENOMEM; |
967 | 963 | ||
968 | for (idx = 0; idx < count; idx++) { | 964 | ret = devm_add_action(dev, scpi_free_channels, scpi_info); |
965 | if (ret) | ||
966 | return ret; | ||
967 | |||
968 | for (; scpi_info->num_chans < count; scpi_info->num_chans++) { | ||
969 | resource_size_t size; | 969 | resource_size_t size; |
970 | struct scpi_chan *pchan = scpi_chan + idx; | 970 | int idx = scpi_info->num_chans; |
971 | struct scpi_chan *pchan = scpi_info->channels + idx; | ||
971 | struct mbox_client *cl = &pchan->cl; | 972 | struct mbox_client *cl = &pchan->cl; |
972 | struct device_node *shmem = of_parse_phandle(np, "shmem", idx); | 973 | struct device_node *shmem = of_parse_phandle(np, "shmem", idx); |
973 | 974 | ||
@@ -975,15 +976,14 @@ static int scpi_probe(struct platform_device *pdev) | |||
975 | of_node_put(shmem); | 976 | of_node_put(shmem); |
976 | if (ret) { | 977 | if (ret) { |
977 | dev_err(dev, "failed to get SCPI payload mem resource\n"); | 978 | dev_err(dev, "failed to get SCPI payload mem resource\n"); |
978 | goto err; | 979 | return ret; |
979 | } | 980 | } |
980 | 981 | ||
981 | size = resource_size(&res); | 982 | size = resource_size(&res); |
982 | pchan->rx_payload = devm_ioremap(dev, res.start, size); | 983 | pchan->rx_payload = devm_ioremap(dev, res.start, size); |
983 | if (!pchan->rx_payload) { | 984 | if (!pchan->rx_payload) { |
984 | dev_err(dev, "failed to ioremap SCPI payload\n"); | 985 | dev_err(dev, "failed to ioremap SCPI payload\n"); |
985 | ret = -EADDRNOTAVAIL; | 986 | return -EADDRNOTAVAIL; |
986 | goto err; | ||
987 | } | 987 | } |
988 | pchan->tx_payload = pchan->rx_payload + (size >> 1); | 988 | pchan->tx_payload = pchan->rx_payload + (size >> 1); |
989 | 989 | ||
@@ -1009,14 +1009,9 @@ static int scpi_probe(struct platform_device *pdev) | |||
1009 | dev_err(dev, "failed to get channel%d err %d\n", | 1009 | dev_err(dev, "failed to get channel%d err %d\n", |
1010 | idx, ret); | 1010 | idx, ret); |
1011 | } | 1011 | } |
1012 | err: | ||
1013 | scpi_free_channels(dev, scpi_chan, idx); | ||
1014 | scpi_info = NULL; | ||
1015 | return ret; | 1012 | return ret; |
1016 | } | 1013 | } |
1017 | 1014 | ||
1018 | scpi_info->channels = scpi_chan; | ||
1019 | scpi_info->num_chans = count; | ||
1020 | scpi_info->commands = scpi_std_commands; | 1015 | scpi_info->commands = scpi_std_commands; |
1021 | scpi_info->scpi_ops = &scpi_ops; | 1016 | scpi_info->scpi_ops = &scpi_ops; |
1022 | 1017 | ||