diff options
-rw-r--r-- | drivers/soc/qcom/smd.c | 34 | ||||
-rw-r--r-- | include/linux/soc/qcom/smd.h | 7 |
2 files changed, 23 insertions, 18 deletions
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index ac1957dfdf24..63e72eb9baa7 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c | |||
@@ -197,7 +197,6 @@ struct qcom_smd_channel { | |||
197 | void *drvdata; | 197 | void *drvdata; |
198 | 198 | ||
199 | struct list_head list; | 199 | struct list_head list; |
200 | struct list_head dev_list; | ||
201 | }; | 200 | }; |
202 | 201 | ||
203 | /** | 202 | /** |
@@ -891,8 +890,6 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
891 | struct qcom_smd_device *qsdev = to_smd_device(dev); | 890 | struct qcom_smd_device *qsdev = to_smd_device(dev); |
892 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); | 891 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); |
893 | struct qcom_smd_channel *channel = qsdev->channel; | 892 | struct qcom_smd_channel *channel = qsdev->channel; |
894 | struct qcom_smd_channel *tmp; | ||
895 | struct qcom_smd_channel *ch; | ||
896 | 893 | ||
897 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); | 894 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); |
898 | 895 | ||
@@ -911,15 +908,9 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
911 | if (qsdrv->remove) | 908 | if (qsdrv->remove) |
912 | qsdrv->remove(qsdev); | 909 | qsdrv->remove(qsdev); |
913 | 910 | ||
914 | /* | 911 | /* The client is now gone, close the primary channel */ |
915 | * The client is now gone, close and release all channels associated | 912 | qcom_smd_channel_close(channel); |
916 | * with this sdev | 913 | channel->qsdev = NULL; |
917 | */ | ||
918 | list_for_each_entry_safe(ch, tmp, &channel->dev_list, dev_list) { | ||
919 | qcom_smd_channel_close(ch); | ||
920 | list_del(&ch->dev_list); | ||
921 | ch->qsdev = NULL; | ||
922 | } | ||
923 | 914 | ||
924 | return 0; | 915 | return 0; |
925 | } | 916 | } |
@@ -1091,6 +1082,8 @@ qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name) | |||
1091 | * | 1082 | * |
1092 | * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't | 1083 | * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't |
1093 | * ready. | 1084 | * ready. |
1085 | * | ||
1086 | * Any channels returned must be closed with a call to qcom_smd_close_channel() | ||
1094 | */ | 1087 | */ |
1095 | struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent, | 1088 | struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent, |
1096 | const char *name, | 1089 | const char *name, |
@@ -1120,15 +1113,21 @@ struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent, | |||
1120 | return ERR_PTR(ret); | 1113 | return ERR_PTR(ret); |
1121 | } | 1114 | } |
1122 | 1115 | ||
1123 | /* | ||
1124 | * Append the list of channel to the channels associated with the sdev | ||
1125 | */ | ||
1126 | list_add_tail(&channel->dev_list, &sdev->channel->dev_list); | ||
1127 | |||
1128 | return channel; | 1116 | return channel; |
1129 | } | 1117 | } |
1130 | EXPORT_SYMBOL(qcom_smd_open_channel); | 1118 | EXPORT_SYMBOL(qcom_smd_open_channel); |
1131 | 1119 | ||
1120 | /** | ||
1121 | * qcom_smd_close_channel() - close an additionally opened channel | ||
1122 | * @channel: channel handle, returned by qcom_smd_open_channel() | ||
1123 | */ | ||
1124 | void qcom_smd_close_channel(struct qcom_smd_channel *channel) | ||
1125 | { | ||
1126 | qcom_smd_channel_close(channel); | ||
1127 | channel->qsdev = NULL; | ||
1128 | } | ||
1129 | EXPORT_SYMBOL(qcom_smd_close_channel); | ||
1130 | |||
1132 | /* | 1131 | /* |
1133 | * Allocate the qcom_smd_channel object for a newly found smd channel, | 1132 | * Allocate the qcom_smd_channel object for a newly found smd channel, |
1134 | * retrieving and validating the smem items involved. | 1133 | * retrieving and validating the smem items involved. |
@@ -1150,7 +1149,6 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed | |||
1150 | if (!channel) | 1149 | if (!channel) |
1151 | return ERR_PTR(-ENOMEM); | 1150 | return ERR_PTR(-ENOMEM); |
1152 | 1151 | ||
1153 | INIT_LIST_HEAD(&channel->dev_list); | ||
1154 | channel->edge = edge; | 1152 | channel->edge = edge; |
1155 | channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); | 1153 | channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); |
1156 | if (!channel->name) | 1154 | if (!channel->name) |
diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h index 910ce1d9ba89..324b1decfffb 100644 --- a/include/linux/soc/qcom/smd.h +++ b/include/linux/soc/qcom/smd.h | |||
@@ -55,6 +55,7 @@ void qcom_smd_driver_unregister(struct qcom_smd_driver *drv); | |||
55 | struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel, | 55 | struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel, |
56 | const char *name, | 56 | const char *name, |
57 | qcom_smd_cb_t cb); | 57 | qcom_smd_cb_t cb); |
58 | void qcom_smd_close_channel(struct qcom_smd_channel *channel); | ||
58 | void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel); | 59 | void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel); |
59 | void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data); | 60 | void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data); |
60 | int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len); | 61 | int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len); |
@@ -83,6 +84,12 @@ qcom_smd_open_channel(struct qcom_smd_channel *channel, | |||
83 | return NULL; | 84 | return NULL; |
84 | } | 85 | } |
85 | 86 | ||
87 | static inline void qcom_smd_close_channel(struct qcom_smd_channel *channel) | ||
88 | { | ||
89 | /* This shouldn't be possible */ | ||
90 | WARN_ON(1); | ||
91 | } | ||
92 | |||
86 | static inline void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel) | 93 | static inline void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel) |
87 | { | 94 | { |
88 | /* This shouldn't be possible */ | 95 | /* This shouldn't be possible */ |