diff options
author | Bjorn Andersson <bjorn.andersson@sonymobile.com> | 2015-10-20 10:42:56 +0800 |
---|---|---|
committer | Yin, Fengwei <fengwei.yin@linaro.org> | 2015-10-22 22:01:21 +0800 |
commit | 485c95edd5ab5d3e4bc51a58fad1220239da2600 (patch) | |
tree | 09f6b9aa1855e83839458b5430f0d216d78f536a | |
parent | 030cdd5788b20ae33a448aa765a32806e291a8dc (diff) |
soc: qcom: smd: Introduce callback setter
Introduce a setter for the callback function pointer to clarify the
locking around the operation and to reduce some duplication.
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-rw-r--r-- | drivers/soc/qcom/smd.c | 23 | ||||
-rw-r--r-- | include/linux/soc/qcom/smd.h | 6 |
2 files changed, 20 insertions, 9 deletions
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index 179415a8ace7..ab17e95783ba 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c @@ -279,6 +279,19 @@ static void qcom_smd_channel_reset(struct qcom_smd_channel *channel) } /* + * Set the callback for a channel, with appropriate locking + */ +static void qcom_smd_channel_set_callback(struct qcom_smd_channel *channel, + qcom_smd_cb_t cb) +{ + unsigned long flags; + + spin_lock_irqsave(&channel->recv_lock, flags); + channel->cb = cb; + spin_unlock_irqrestore(&channel->recv_lock, flags); +}; + +/* * Calculate the amount of data available in the rx fifo */ static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) @@ -705,8 +718,7 @@ static int qcom_smd_dev_probe(struct device *dev) if (!channel->bounce_buffer) return -ENOMEM; - channel->cb = qsdrv->callback; - + qcom_smd_channel_set_callback(channel, qsdrv->callback); qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING); qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED); @@ -722,7 +734,7 @@ static int qcom_smd_dev_probe(struct device *dev) err: dev_err(&qsdev->dev, "probe failed\n"); - channel->cb = NULL; + qcom_smd_channel_set_callback(channel, NULL); kfree(channel->bounce_buffer); channel->bounce_buffer = NULL; @@ -741,16 +753,13 @@ static int qcom_smd_dev_remove(struct device *dev) struct qcom_smd_device *qsdev = to_smd_device(dev); struct qcom_smd_driver *qsdrv = to_smd_driver(dev); struct qcom_smd_channel *channel = qsdev->channel; - unsigned long flags; qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); /* * Make sure we don't race with the code receiving data. */ - spin_lock_irqsave(&channel->recv_lock, flags); - channel->cb = NULL; - spin_unlock_irqrestore(&channel->recv_lock, flags); + qcom_smd_channel_set_callback(channel, NULL); /* Wake up any sleepers in qcom_smd_send() */ wake_up_interruptible(&channel->fblockread_event); diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h index a2fe0372d205..4013fd67338e 100644 --- a/include/linux/soc/qcom/smd.h +++ b/include/linux/soc/qcom/smd.h @@ -6,7 +6,9 @@ struct qcom_smd; struct qcom_smd_lookup; +struct qcom_smd_device; +typedef int (*qcom_smd_cb_t)(struct qcom_smd_device *, const void *, size_t); /* * SMD channel states. @@ -44,7 +46,7 @@ struct qcom_smd_channel { int fifo_size; void *bounce_buffer; - int (*cb)(struct qcom_smd_device *, const void *, size_t); + qcom_smd_cb_t cb; spinlock_t recv_lock; @@ -87,7 +89,7 @@ struct qcom_smd_driver { int (*probe)(struct qcom_smd_device *dev); void (*remove)(struct qcom_smd_device *dev); - int (*callback)(struct qcom_smd_device *, const void *, size_t); + qcom_smd_cb_t callback; }; int qcom_smd_driver_register(struct qcom_smd_driver *drv); |