aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/soc/qcom/smd.c25
-rw-r--r--include/linux/soc/qcom/smd.h4
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 */
383static 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 */
383static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) 396static 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)
831err: 843err:
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
29typedef 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
48int qcom_smd_driver_register(struct qcom_smd_driver *drv); 50int qcom_smd_driver_register(struct qcom_smd_driver *drv);