diff options
author | Bjorn Andersson <bjorn.andersson@sonymobile.com> | 2016-02-18 01:39:05 -0500 |
---|---|---|
committer | Andy Gross <andy.gross@linaro.org> | 2016-03-30 18:21:03 -0400 |
commit | d5933855c0eb0a4103cf5db784cfdd4d7a85cd56 (patch) | |
tree | a3004a2200976d6447fa1454e54783d15108e781 /drivers/soc | |
parent | 3fd3f2fd86478614fecbe261b201779b4fc6abd2 (diff) |
soc: qcom: smd: Support multiple channels per sdev
This patch allows chaining additional channels to a SMD device, enabling
implementation of multi-channel SMD devies - like Bluetooth.
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/qcom/smd.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index d253e5cc233f..c3fa0fd724f7 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c | |||
@@ -193,6 +193,7 @@ struct qcom_smd_channel { | |||
193 | int pkt_size; | 193 | int pkt_size; |
194 | 194 | ||
195 | struct list_head list; | 195 | struct list_head list; |
196 | struct list_head dev_list; | ||
196 | }; | 197 | }; |
197 | 198 | ||
198 | /** | 199 | /** |
@@ -887,6 +888,8 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
887 | struct qcom_smd_device *qsdev = to_smd_device(dev); | 888 | struct qcom_smd_device *qsdev = to_smd_device(dev); |
888 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); | 889 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); |
889 | struct qcom_smd_channel *channel = qsdev->channel; | 890 | struct qcom_smd_channel *channel = qsdev->channel; |
891 | struct qcom_smd_channel *tmp; | ||
892 | struct qcom_smd_channel *ch; | ||
890 | 893 | ||
891 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); | 894 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); |
892 | 895 | ||
@@ -906,10 +909,14 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
906 | qsdrv->remove(qsdev); | 909 | qsdrv->remove(qsdev); |
907 | 910 | ||
908 | /* | 911 | /* |
909 | * The client is now gone, cleanup and reset the channel state. | 912 | * The client is now gone, close and release all channels associated |
913 | * with this sdev | ||
910 | */ | 914 | */ |
911 | channel->qsdev = NULL; | 915 | list_for_each_entry_safe(ch, tmp, &channel->dev_list, dev_list) { |
912 | qcom_smd_channel_close(channel); | 916 | qcom_smd_channel_close(ch); |
917 | list_del(&ch->dev_list); | ||
918 | ch->qsdev = NULL; | ||
919 | } | ||
913 | 920 | ||
914 | return 0; | 921 | return 0; |
915 | } | 922 | } |
@@ -1056,6 +1063,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed | |||
1056 | if (!channel) | 1063 | if (!channel) |
1057 | return ERR_PTR(-ENOMEM); | 1064 | return ERR_PTR(-ENOMEM); |
1058 | 1065 | ||
1066 | INIT_LIST_HEAD(&channel->dev_list); | ||
1059 | channel->edge = edge; | 1067 | channel->edge = edge; |
1060 | channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); | 1068 | channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); |
1061 | if (!channel->name) | 1069 | if (!channel->name) |