diff options
-rw-r--r-- | drivers/soc/qcom/smd.c | 25 | ||||
-rw-r--r-- | include/linux/soc/qcom/smd.h | 4 |
2 files changed, 20 insertions, 9 deletions
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index 498fd0581a45..c357842b92e1 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c | |||
@@ -186,7 +186,7 @@ struct qcom_smd_channel { | |||
186 | int fifo_size; | 186 | int fifo_size; |
187 | 187 | ||
188 | void *bounce_buffer; | 188 | void *bounce_buffer; |
189 | int (*cb)(struct qcom_smd_device *, const void *, size_t); | 189 | qcom_smd_cb_t cb; |
190 | 190 | ||
191 | spinlock_t recv_lock; | 191 | spinlock_t recv_lock; |
192 | 192 | ||
@@ -378,6 +378,19 @@ static void qcom_smd_channel_reset(struct qcom_smd_channel *channel) | |||
378 | } | 378 | } |
379 | 379 | ||
380 | /* | 380 | /* |
381 | * Set the callback for a channel, with appropriate locking | ||
382 | */ | ||
383 | static void qcom_smd_channel_set_callback(struct qcom_smd_channel *channel, | ||
384 | qcom_smd_cb_t cb) | ||
385 | { | ||
386 | unsigned long flags; | ||
387 | |||
388 | spin_lock_irqsave(&channel->recv_lock, flags); | ||
389 | channel->cb = cb; | ||
390 | spin_unlock_irqrestore(&channel->recv_lock, flags); | ||
391 | }; | ||
392 | |||
393 | /* | ||
381 | * Calculate the amount of data available in the rx fifo | 394 | * Calculate the amount of data available in the rx fifo |
382 | */ | 395 | */ |
383 | static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) | 396 | static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) |
@@ -814,8 +827,7 @@ static int qcom_smd_dev_probe(struct device *dev) | |||
814 | if (!channel->bounce_buffer) | 827 | if (!channel->bounce_buffer) |
815 | return -ENOMEM; | 828 | return -ENOMEM; |
816 | 829 | ||
817 | channel->cb = qsdrv->callback; | 830 | qcom_smd_channel_set_callback(channel, qsdrv->callback); |
818 | |||
819 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING); | 831 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING); |
820 | 832 | ||
821 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED); | 833 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED); |
@@ -831,7 +843,7 @@ static int qcom_smd_dev_probe(struct device *dev) | |||
831 | err: | 843 | err: |
832 | dev_err(&qsdev->dev, "probe failed\n"); | 844 | dev_err(&qsdev->dev, "probe failed\n"); |
833 | 845 | ||
834 | channel->cb = NULL; | 846 | qcom_smd_channel_set_callback(channel, NULL); |
835 | kfree(channel->bounce_buffer); | 847 | kfree(channel->bounce_buffer); |
836 | channel->bounce_buffer = NULL; | 848 | channel->bounce_buffer = NULL; |
837 | 849 | ||
@@ -850,16 +862,13 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
850 | struct qcom_smd_device *qsdev = to_smd_device(dev); | 862 | struct qcom_smd_device *qsdev = to_smd_device(dev); |
851 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); | 863 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); |
852 | struct qcom_smd_channel *channel = qsdev->channel; | 864 | struct qcom_smd_channel *channel = qsdev->channel; |
853 | unsigned long flags; | ||
854 | 865 | ||
855 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); | 866 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); |
856 | 867 | ||
857 | /* | 868 | /* |
858 | * Make sure we don't race with the code receiving data. | 869 | * Make sure we don't race with the code receiving data. |
859 | */ | 870 | */ |
860 | spin_lock_irqsave(&channel->recv_lock, flags); | 871 | qcom_smd_channel_set_callback(channel, NULL); |
861 | channel->cb = NULL; | ||
862 | spin_unlock_irqrestore(&channel->recv_lock, flags); | ||
863 | 872 | ||
864 | /* Wake up any sleepers in qcom_smd_send() */ | 873 | /* Wake up any sleepers in qcom_smd_send() */ |
865 | wake_up_interruptible(&channel->fblockread_event); | 874 | wake_up_interruptible(&channel->fblockread_event); |
diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h index d0cb6d189a0a..65a64fcdb1aa 100644 --- a/include/linux/soc/qcom/smd.h +++ b/include/linux/soc/qcom/smd.h | |||
@@ -26,6 +26,8 @@ struct qcom_smd_device { | |||
26 | struct qcom_smd_channel *channel; | 26 | struct qcom_smd_channel *channel; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | typedef int (*qcom_smd_cb_t)(struct qcom_smd_device *, const void *, size_t); | ||
30 | |||
29 | /** | 31 | /** |
30 | * struct qcom_smd_driver - smd driver struct | 32 | * struct qcom_smd_driver - smd driver struct |
31 | * @driver: underlying device driver | 33 | * @driver: underlying device driver |
@@ -42,7 +44,7 @@ struct qcom_smd_driver { | |||
42 | 44 | ||
43 | int (*probe)(struct qcom_smd_device *dev); | 45 | int (*probe)(struct qcom_smd_device *dev); |
44 | void (*remove)(struct qcom_smd_device *dev); | 46 | void (*remove)(struct qcom_smd_device *dev); |
45 | int (*callback)(struct qcom_smd_device *, const void *, size_t); | 47 | qcom_smd_cb_t callback; |
46 | }; | 48 | }; |
47 | 49 | ||
48 | int qcom_smd_driver_register(struct qcom_smd_driver *drv); | 50 | int qcom_smd_driver_register(struct qcom_smd_driver *drv); |