diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-05-13 17:36:11 -0400 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-05-13 17:42:23 -0400 |
commit | f79a917e69e1f5cd86e864b67f06147f1b0340f4 (patch) | |
tree | 561675103ee8a220365e7c907e51d6c362727ff7 | |
parent | ed7cbbce544856b20e5811de373cf92e92499771 (diff) | |
parent | b853cb9628bfbcc4017da46d5f5b46e3eba9d8c6 (diff) |
Merge tag 'qcom-soc-for-4.7-2' into net-next
This merges the Qualcomm SOC tree with the net-next, solving the
merge conflict in the SMD API between the two.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r-- | MAINTAINERS | 3 | ||||
-rw-r--r-- | drivers/soc/qcom/smd-rpm.c | 9 | ||||
-rw-r--r-- | drivers/soc/qcom/smd.c | 247 | ||||
-rw-r--r-- | drivers/soc/qcom/smem.c | 3 | ||||
-rw-r--r-- | drivers/soc/qcom/spm.c | 8 | ||||
-rw-r--r-- | drivers/soc/qcom/wcnss_ctrl.c | 8 | ||||
-rw-r--r-- | include/linux/soc/qcom/smd.h | 33 | ||||
-rw-r--r-- | include/linux/soc/qcom/smem_state.h | 35 | ||||
-rw-r--r-- | net/qrtr/smd.c | 9 |
9 files changed, 278 insertions, 77 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index b57df66532d2..1e13db350d50 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1470,7 +1470,10 @@ F: arch/arm/boot/dts/qcom-*.dts | |||
1470 | F: arch/arm/boot/dts/qcom-*.dtsi | 1470 | F: arch/arm/boot/dts/qcom-*.dtsi |
1471 | F: arch/arm/mach-qcom/ | 1471 | F: arch/arm/mach-qcom/ |
1472 | F: arch/arm64/boot/dts/qcom/* | 1472 | F: arch/arm64/boot/dts/qcom/* |
1473 | F: drivers/i2c/busses/i2c-qup.c | ||
1474 | F: drivers/clk/qcom/ | ||
1473 | F: drivers/soc/qcom/ | 1475 | F: drivers/soc/qcom/ |
1476 | F: drivers/spi/spi-qup.c | ||
1474 | F: drivers/tty/serial/msm_serial.h | 1477 | F: drivers/tty/serial/msm_serial.h |
1475 | F: drivers/tty/serial/msm_serial.c | 1478 | F: drivers/tty/serial/msm_serial.c |
1476 | F: drivers/*/pm8???-* | 1479 | F: drivers/*/pm8???-* |
diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c index 731fa066f712..6609d7e0edb0 100644 --- a/drivers/soc/qcom/smd-rpm.c +++ b/drivers/soc/qcom/smd-rpm.c | |||
@@ -33,6 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | struct qcom_smd_rpm { | 34 | struct qcom_smd_rpm { |
35 | struct qcom_smd_channel *rpm_channel; | 35 | struct qcom_smd_channel *rpm_channel; |
36 | struct device *dev; | ||
36 | 37 | ||
37 | struct completion ack; | 38 | struct completion ack; |
38 | struct mutex lock; | 39 | struct mutex lock; |
@@ -149,14 +150,14 @@ out: | |||
149 | } | 150 | } |
150 | EXPORT_SYMBOL(qcom_rpm_smd_write); | 151 | EXPORT_SYMBOL(qcom_rpm_smd_write); |
151 | 152 | ||
152 | static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev, | 153 | static int qcom_smd_rpm_callback(struct qcom_smd_channel *channel, |
153 | const void *data, | 154 | const void *data, |
154 | size_t count) | 155 | size_t count) |
155 | { | 156 | { |
156 | const struct qcom_rpm_header *hdr = data; | 157 | const struct qcom_rpm_header *hdr = data; |
157 | size_t hdr_length = le32_to_cpu(hdr->length); | 158 | size_t hdr_length = le32_to_cpu(hdr->length); |
158 | const struct qcom_rpm_message *msg; | 159 | const struct qcom_rpm_message *msg; |
159 | struct qcom_smd_rpm *rpm = dev_get_drvdata(&qsdev->dev); | 160 | struct qcom_smd_rpm *rpm = qcom_smd_get_drvdata(channel); |
160 | const u8 *buf = data + sizeof(struct qcom_rpm_header); | 161 | const u8 *buf = data + sizeof(struct qcom_rpm_header); |
161 | const u8 *end = buf + hdr_length; | 162 | const u8 *end = buf + hdr_length; |
162 | char msgbuf[32]; | 163 | char msgbuf[32]; |
@@ -165,7 +166,7 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev, | |||
165 | 166 | ||
166 | if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST || | 167 | if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST || |
167 | hdr_length < sizeof(struct qcom_rpm_message)) { | 168 | hdr_length < sizeof(struct qcom_rpm_message)) { |
168 | dev_err(&qsdev->dev, "invalid request\n"); | 169 | dev_err(rpm->dev, "invalid request\n"); |
169 | return 0; | 170 | return 0; |
170 | } | 171 | } |
171 | 172 | ||
@@ -206,7 +207,9 @@ static int qcom_smd_rpm_probe(struct qcom_smd_device *sdev) | |||
206 | mutex_init(&rpm->lock); | 207 | mutex_init(&rpm->lock); |
207 | init_completion(&rpm->ack); | 208 | init_completion(&rpm->ack); |
208 | 209 | ||
210 | rpm->dev = &sdev->dev; | ||
209 | rpm->rpm_channel = sdev->channel; | 211 | rpm->rpm_channel = sdev->channel; |
212 | qcom_smd_set_drvdata(sdev->channel, rpm); | ||
210 | 213 | ||
211 | dev_set_drvdata(&sdev->dev, rpm); | 214 | dev_set_drvdata(&sdev->dev, rpm); |
212 | 215 | ||
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index 498fd0581a45..ac1957dfdf24 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c | |||
@@ -106,9 +106,9 @@ static const struct { | |||
106 | * @channels: list of all channels detected on this edge | 106 | * @channels: list of all channels detected on this edge |
107 | * @channels_lock: guard for modifications of @channels | 107 | * @channels_lock: guard for modifications of @channels |
108 | * @allocated: array of bitmaps representing already allocated channels | 108 | * @allocated: array of bitmaps representing already allocated channels |
109 | * @need_rescan: flag that the @work needs to scan smem for new channels | ||
110 | * @smem_available: last available amount of smem triggering a channel scan | 109 | * @smem_available: last available amount of smem triggering a channel scan |
111 | * @work: work item for edge house keeping | 110 | * @scan_work: work item for discovering new channels |
111 | * @state_work: work item for edge state changes | ||
112 | */ | 112 | */ |
113 | struct qcom_smd_edge { | 113 | struct qcom_smd_edge { |
114 | struct qcom_smd *smd; | 114 | struct qcom_smd *smd; |
@@ -127,10 +127,12 @@ struct qcom_smd_edge { | |||
127 | 127 | ||
128 | DECLARE_BITMAP(allocated[SMD_ALLOC_TBL_COUNT], SMD_ALLOC_TBL_SIZE); | 128 | DECLARE_BITMAP(allocated[SMD_ALLOC_TBL_COUNT], SMD_ALLOC_TBL_SIZE); |
129 | 129 | ||
130 | bool need_rescan; | ||
131 | unsigned smem_available; | 130 | unsigned smem_available; |
132 | 131 | ||
133 | struct work_struct work; | 132 | wait_queue_head_t new_channel_event; |
133 | |||
134 | struct work_struct scan_work; | ||
135 | struct work_struct state_work; | ||
134 | }; | 136 | }; |
135 | 137 | ||
136 | /* | 138 | /* |
@@ -186,13 +188,16 @@ struct qcom_smd_channel { | |||
186 | int fifo_size; | 188 | int fifo_size; |
187 | 189 | ||
188 | void *bounce_buffer; | 190 | void *bounce_buffer; |
189 | int (*cb)(struct qcom_smd_device *, const void *, size_t); | 191 | qcom_smd_cb_t cb; |
190 | 192 | ||
191 | spinlock_t recv_lock; | 193 | spinlock_t recv_lock; |
192 | 194 | ||
193 | int pkt_size; | 195 | int pkt_size; |
194 | 196 | ||
197 | void *drvdata; | ||
198 | |||
195 | struct list_head list; | 199 | struct list_head list; |
200 | struct list_head dev_list; | ||
196 | }; | 201 | }; |
197 | 202 | ||
198 | /** | 203 | /** |
@@ -378,6 +383,19 @@ static void qcom_smd_channel_reset(struct qcom_smd_channel *channel) | |||
378 | } | 383 | } |
379 | 384 | ||
380 | /* | 385 | /* |
386 | * Set the callback for a channel, with appropriate locking | ||
387 | */ | ||
388 | static void qcom_smd_channel_set_callback(struct qcom_smd_channel *channel, | ||
389 | qcom_smd_cb_t cb) | ||
390 | { | ||
391 | unsigned long flags; | ||
392 | |||
393 | spin_lock_irqsave(&channel->recv_lock, flags); | ||
394 | channel->cb = cb; | ||
395 | spin_unlock_irqrestore(&channel->recv_lock, flags); | ||
396 | }; | ||
397 | |||
398 | /* | ||
381 | * Calculate the amount of data available in the rx fifo | 399 | * Calculate the amount of data available in the rx fifo |
382 | */ | 400 | */ |
383 | static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) | 401 | static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) |
@@ -497,7 +515,6 @@ static void qcom_smd_channel_advance(struct qcom_smd_channel *channel, | |||
497 | */ | 515 | */ |
498 | static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) | 516 | static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) |
499 | { | 517 | { |
500 | struct qcom_smd_device *qsdev = channel->qsdev; | ||
501 | unsigned tail; | 518 | unsigned tail; |
502 | size_t len; | 519 | size_t len; |
503 | void *ptr; | 520 | void *ptr; |
@@ -517,7 +534,7 @@ static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) | |||
517 | len = channel->pkt_size; | 534 | len = channel->pkt_size; |
518 | } | 535 | } |
519 | 536 | ||
520 | ret = channel->cb(qsdev, ptr, len); | 537 | ret = channel->cb(channel, ptr, len); |
521 | if (ret < 0) | 538 | if (ret < 0) |
522 | return ret; | 539 | return ret; |
523 | 540 | ||
@@ -601,7 +618,8 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data) | |||
601 | struct qcom_smd_edge *edge = data; | 618 | struct qcom_smd_edge *edge = data; |
602 | struct qcom_smd_channel *channel; | 619 | struct qcom_smd_channel *channel; |
603 | unsigned available; | 620 | unsigned available; |
604 | bool kick_worker = false; | 621 | bool kick_scanner = false; |
622 | bool kick_state = false; | ||
605 | 623 | ||
606 | /* | 624 | /* |
607 | * Handle state changes or data on each of the channels on this edge | 625 | * Handle state changes or data on each of the channels on this edge |
@@ -609,7 +627,7 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data) | |||
609 | spin_lock(&edge->channels_lock); | 627 | spin_lock(&edge->channels_lock); |
610 | list_for_each_entry(channel, &edge->channels, list) { | 628 | list_for_each_entry(channel, &edge->channels, list) { |
611 | spin_lock(&channel->recv_lock); | 629 | spin_lock(&channel->recv_lock); |
612 | kick_worker |= qcom_smd_channel_intr(channel); | 630 | kick_state |= qcom_smd_channel_intr(channel); |
613 | spin_unlock(&channel->recv_lock); | 631 | spin_unlock(&channel->recv_lock); |
614 | } | 632 | } |
615 | spin_unlock(&edge->channels_lock); | 633 | spin_unlock(&edge->channels_lock); |
@@ -622,12 +640,13 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data) | |||
622 | available = qcom_smem_get_free_space(edge->remote_pid); | 640 | available = qcom_smem_get_free_space(edge->remote_pid); |
623 | if (available != edge->smem_available) { | 641 | if (available != edge->smem_available) { |
624 | edge->smem_available = available; | 642 | edge->smem_available = available; |
625 | edge->need_rescan = true; | 643 | kick_scanner = true; |
626 | kick_worker = true; | ||
627 | } | 644 | } |
628 | 645 | ||
629 | if (kick_worker) | 646 | if (kick_scanner) |
630 | schedule_work(&edge->work); | 647 | schedule_work(&edge->scan_work); |
648 | if (kick_state) | ||
649 | schedule_work(&edge->state_work); | ||
631 | 650 | ||
632 | return IRQ_HANDLED; | 651 | return IRQ_HANDLED; |
633 | } | 652 | } |
@@ -793,18 +812,12 @@ static int qcom_smd_dev_match(struct device *dev, struct device_driver *drv) | |||
793 | } | 812 | } |
794 | 813 | ||
795 | /* | 814 | /* |
796 | * Probe the smd client. | 815 | * Helper for opening a channel |
797 | * | ||
798 | * The remote side have indicated that it want the channel to be opened, so | ||
799 | * complete the state handshake and probe our client driver. | ||
800 | */ | 816 | */ |
801 | static int qcom_smd_dev_probe(struct device *dev) | 817 | static int qcom_smd_channel_open(struct qcom_smd_channel *channel, |
818 | qcom_smd_cb_t cb) | ||
802 | { | 819 | { |
803 | struct qcom_smd_device *qsdev = to_smd_device(dev); | ||
804 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); | ||
805 | struct qcom_smd_channel *channel = qsdev->channel; | ||
806 | size_t bb_size; | 820 | size_t bb_size; |
807 | int ret; | ||
808 | 821 | ||
809 | /* | 822 | /* |
810 | * Packets are maximum 4k, but reduce if the fifo is smaller | 823 | * Packets are maximum 4k, but reduce if the fifo is smaller |
@@ -814,12 +827,44 @@ 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, cb); |
818 | |||
819 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING); | 831 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING); |
820 | |||
821 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED); | 832 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED); |
822 | 833 | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | /* | ||
838 | * Helper for closing and resetting a channel | ||
839 | */ | ||
840 | static void qcom_smd_channel_close(struct qcom_smd_channel *channel) | ||
841 | { | ||
842 | qcom_smd_channel_set_callback(channel, NULL); | ||
843 | |||
844 | kfree(channel->bounce_buffer); | ||
845 | channel->bounce_buffer = NULL; | ||
846 | |||
847 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSED); | ||
848 | qcom_smd_channel_reset(channel); | ||
849 | } | ||
850 | |||
851 | /* | ||
852 | * Probe the smd client. | ||
853 | * | ||
854 | * The remote side have indicated that it want the channel to be opened, so | ||
855 | * complete the state handshake and probe our client driver. | ||
856 | */ | ||
857 | static int qcom_smd_dev_probe(struct device *dev) | ||
858 | { | ||
859 | struct qcom_smd_device *qsdev = to_smd_device(dev); | ||
860 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); | ||
861 | struct qcom_smd_channel *channel = qsdev->channel; | ||
862 | int ret; | ||
863 | |||
864 | ret = qcom_smd_channel_open(channel, qsdrv->callback); | ||
865 | if (ret) | ||
866 | return ret; | ||
867 | |||
823 | ret = qsdrv->probe(qsdev); | 868 | ret = qsdrv->probe(qsdev); |
824 | if (ret) | 869 | if (ret) |
825 | goto err; | 870 | goto err; |
@@ -831,11 +876,7 @@ static int qcom_smd_dev_probe(struct device *dev) | |||
831 | err: | 876 | err: |
832 | dev_err(&qsdev->dev, "probe failed\n"); | 877 | dev_err(&qsdev->dev, "probe failed\n"); |
833 | 878 | ||
834 | channel->cb = NULL; | 879 | qcom_smd_channel_close(channel); |
835 | kfree(channel->bounce_buffer); | ||
836 | channel->bounce_buffer = NULL; | ||
837 | |||
838 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSED); | ||
839 | return ret; | 880 | return ret; |
840 | } | 881 | } |
841 | 882 | ||
@@ -850,16 +891,15 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
850 | struct qcom_smd_device *qsdev = to_smd_device(dev); | 891 | struct qcom_smd_device *qsdev = to_smd_device(dev); |
851 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); | 892 | struct qcom_smd_driver *qsdrv = to_smd_driver(dev); |
852 | struct qcom_smd_channel *channel = qsdev->channel; | 893 | struct qcom_smd_channel *channel = qsdev->channel; |
853 | unsigned long flags; | 894 | struct qcom_smd_channel *tmp; |
895 | struct qcom_smd_channel *ch; | ||
854 | 896 | ||
855 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); | 897 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSING); |
856 | 898 | ||
857 | /* | 899 | /* |
858 | * Make sure we don't race with the code receiving data. | 900 | * Make sure we don't race with the code receiving data. |
859 | */ | 901 | */ |
860 | spin_lock_irqsave(&channel->recv_lock, flags); | 902 | qcom_smd_channel_set_callback(channel, NULL); |
861 | channel->cb = NULL; | ||
862 | spin_unlock_irqrestore(&channel->recv_lock, flags); | ||
863 | 903 | ||
864 | /* Wake up any sleepers in qcom_smd_send() */ | 904 | /* Wake up any sleepers in qcom_smd_send() */ |
865 | wake_up_interruptible(&channel->fblockread_event); | 905 | wake_up_interruptible(&channel->fblockread_event); |
@@ -872,15 +912,14 @@ static int qcom_smd_dev_remove(struct device *dev) | |||
872 | qsdrv->remove(qsdev); | 912 | qsdrv->remove(qsdev); |
873 | 913 | ||
874 | /* | 914 | /* |
875 | * The client is now gone, cleanup and reset the channel state. | 915 | * The client is now gone, close and release all channels associated |
916 | * with this sdev | ||
876 | */ | 917 | */ |
877 | channel->qsdev = NULL; | 918 | list_for_each_entry_safe(ch, tmp, &channel->dev_list, dev_list) { |
878 | kfree(channel->bounce_buffer); | 919 | qcom_smd_channel_close(ch); |
879 | channel->bounce_buffer = NULL; | 920 | list_del(&ch->dev_list); |
880 | 921 | ch->qsdev = NULL; | |
881 | qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSED); | 922 | } |
882 | |||
883 | qcom_smd_channel_reset(channel); | ||
884 | 923 | ||
885 | return 0; | 924 | return 0; |
886 | } | 925 | } |
@@ -996,6 +1035,18 @@ int qcom_smd_driver_register(struct qcom_smd_driver *qsdrv) | |||
996 | } | 1035 | } |
997 | EXPORT_SYMBOL(qcom_smd_driver_register); | 1036 | EXPORT_SYMBOL(qcom_smd_driver_register); |
998 | 1037 | ||
1038 | void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel) | ||
1039 | { | ||
1040 | return channel->drvdata; | ||
1041 | } | ||
1042 | EXPORT_SYMBOL(qcom_smd_get_drvdata); | ||
1043 | |||
1044 | void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data) | ||
1045 | { | ||
1046 | channel->drvdata = data; | ||
1047 | } | ||
1048 | EXPORT_SYMBOL(qcom_smd_set_drvdata); | ||
1049 | |||
999 | /** | 1050 | /** |
1000 | * qcom_smd_driver_unregister - unregister a smd driver | 1051 | * qcom_smd_driver_unregister - unregister a smd driver |
1001 | * @qsdrv: qcom_smd_driver struct | 1052 | * @qsdrv: qcom_smd_driver struct |
@@ -1006,6 +1057,78 @@ void qcom_smd_driver_unregister(struct qcom_smd_driver *qsdrv) | |||
1006 | } | 1057 | } |
1007 | EXPORT_SYMBOL(qcom_smd_driver_unregister); | 1058 | EXPORT_SYMBOL(qcom_smd_driver_unregister); |
1008 | 1059 | ||
1060 | static struct qcom_smd_channel * | ||
1061 | qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name) | ||
1062 | { | ||
1063 | struct qcom_smd_channel *channel; | ||
1064 | struct qcom_smd_channel *ret = NULL; | ||
1065 | unsigned long flags; | ||
1066 | unsigned state; | ||
1067 | |||
1068 | spin_lock_irqsave(&edge->channels_lock, flags); | ||
1069 | list_for_each_entry(channel, &edge->channels, list) { | ||
1070 | if (strcmp(channel->name, name)) | ||
1071 | continue; | ||
1072 | |||
1073 | state = GET_RX_CHANNEL_INFO(channel, state); | ||
1074 | if (state != SMD_CHANNEL_OPENING && | ||
1075 | state != SMD_CHANNEL_OPENED) | ||
1076 | continue; | ||
1077 | |||
1078 | ret = channel; | ||
1079 | break; | ||
1080 | } | ||
1081 | spin_unlock_irqrestore(&edge->channels_lock, flags); | ||
1082 | |||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | /** | ||
1087 | * qcom_smd_open_channel() - claim additional channels on the same edge | ||
1088 | * @sdev: smd_device handle | ||
1089 | * @name: channel name | ||
1090 | * @cb: callback method to use for incoming data | ||
1091 | * | ||
1092 | * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't | ||
1093 | * ready. | ||
1094 | */ | ||
1095 | struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent, | ||
1096 | const char *name, | ||
1097 | qcom_smd_cb_t cb) | ||
1098 | { | ||
1099 | struct qcom_smd_channel *channel; | ||
1100 | struct qcom_smd_device *sdev = parent->qsdev; | ||
1101 | struct qcom_smd_edge *edge = parent->edge; | ||
1102 | int ret; | ||
1103 | |||
1104 | /* Wait up to HZ for the channel to appear */ | ||
1105 | ret = wait_event_interruptible_timeout(edge->new_channel_event, | ||
1106 | (channel = qcom_smd_find_channel(edge, name)) != NULL, | ||
1107 | HZ); | ||
1108 | if (!ret) | ||
1109 | return ERR_PTR(-ETIMEDOUT); | ||
1110 | |||
1111 | if (channel->state != SMD_CHANNEL_CLOSED) { | ||
1112 | dev_err(&sdev->dev, "channel %s is busy\n", channel->name); | ||
1113 | return ERR_PTR(-EBUSY); | ||
1114 | } | ||
1115 | |||
1116 | channel->qsdev = sdev; | ||
1117 | ret = qcom_smd_channel_open(channel, cb); | ||
1118 | if (ret) { | ||
1119 | channel->qsdev = NULL; | ||
1120 | return ERR_PTR(ret); | ||
1121 | } | ||
1122 | |||
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; | ||
1129 | } | ||
1130 | EXPORT_SYMBOL(qcom_smd_open_channel); | ||
1131 | |||
1009 | /* | 1132 | /* |
1010 | * Allocate the qcom_smd_channel object for a newly found smd channel, | 1133 | * Allocate the qcom_smd_channel object for a newly found smd channel, |
1011 | * retrieving and validating the smem items involved. | 1134 | * retrieving and validating the smem items involved. |
@@ -1027,6 +1150,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed | |||
1027 | if (!channel) | 1150 | if (!channel) |
1028 | return ERR_PTR(-ENOMEM); | 1151 | return ERR_PTR(-ENOMEM); |
1029 | 1152 | ||
1153 | INIT_LIST_HEAD(&channel->dev_list); | ||
1030 | channel->edge = edge; | 1154 | channel->edge = edge; |
1031 | channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); | 1155 | channel->name = devm_kstrdup(smd->dev, name, GFP_KERNEL); |
1032 | if (!channel->name) | 1156 | if (!channel->name) |
@@ -1089,8 +1213,9 @@ free_name_and_channel: | |||
1089 | * qcom_smd_create_channel() to create representations of these and add | 1213 | * qcom_smd_create_channel() to create representations of these and add |
1090 | * them to the edge's list of channels. | 1214 | * them to the edge's list of channels. |
1091 | */ | 1215 | */ |
1092 | static void qcom_discover_channels(struct qcom_smd_edge *edge) | 1216 | static void qcom_channel_scan_worker(struct work_struct *work) |
1093 | { | 1217 | { |
1218 | struct qcom_smd_edge *edge = container_of(work, struct qcom_smd_edge, scan_work); | ||
1094 | struct qcom_smd_alloc_entry *alloc_tbl; | 1219 | struct qcom_smd_alloc_entry *alloc_tbl; |
1095 | struct qcom_smd_alloc_entry *entry; | 1220 | struct qcom_smd_alloc_entry *entry; |
1096 | struct qcom_smd_channel *channel; | 1221 | struct qcom_smd_channel *channel; |
@@ -1140,10 +1265,12 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge) | |||
1140 | 1265 | ||
1141 | dev_dbg(smd->dev, "new channel found: '%s'\n", channel->name); | 1266 | dev_dbg(smd->dev, "new channel found: '%s'\n", channel->name); |
1142 | set_bit(i, edge->allocated[tbl]); | 1267 | set_bit(i, edge->allocated[tbl]); |
1268 | |||
1269 | wake_up_interruptible(&edge->new_channel_event); | ||
1143 | } | 1270 | } |
1144 | } | 1271 | } |
1145 | 1272 | ||
1146 | schedule_work(&edge->work); | 1273 | schedule_work(&edge->state_work); |
1147 | } | 1274 | } |
1148 | 1275 | ||
1149 | /* | 1276 | /* |
@@ -1151,29 +1278,23 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge) | |||
1151 | * then scans all registered channels for state changes that should be handled | 1278 | * then scans all registered channels for state changes that should be handled |
1152 | * by creating or destroying smd client devices for the registered channels. | 1279 | * by creating or destroying smd client devices for the registered channels. |
1153 | * | 1280 | * |
1154 | * LOCKING: edge->channels_lock is not needed to be held during the traversal | 1281 | * LOCKING: edge->channels_lock only needs to cover the list operations, as the |
1155 | * of the channels list as it's done synchronously with the only writer. | 1282 | * worker is killed before any channels are deallocated |
1156 | */ | 1283 | */ |
1157 | static void qcom_channel_state_worker(struct work_struct *work) | 1284 | static void qcom_channel_state_worker(struct work_struct *work) |
1158 | { | 1285 | { |
1159 | struct qcom_smd_channel *channel; | 1286 | struct qcom_smd_channel *channel; |
1160 | struct qcom_smd_edge *edge = container_of(work, | 1287 | struct qcom_smd_edge *edge = container_of(work, |
1161 | struct qcom_smd_edge, | 1288 | struct qcom_smd_edge, |
1162 | work); | 1289 | state_work); |
1163 | unsigned remote_state; | 1290 | unsigned remote_state; |
1164 | 1291 | unsigned long flags; | |
1165 | /* | ||
1166 | * Rescan smem if we have reason to belive that there are new channels. | ||
1167 | */ | ||
1168 | if (edge->need_rescan) { | ||
1169 | edge->need_rescan = false; | ||
1170 | qcom_discover_channels(edge); | ||
1171 | } | ||
1172 | 1292 | ||
1173 | /* | 1293 | /* |
1174 | * Register a device for any closed channel where the remote processor | 1294 | * Register a device for any closed channel where the remote processor |
1175 | * is showing interest in opening the channel. | 1295 | * is showing interest in opening the channel. |
1176 | */ | 1296 | */ |
1297 | spin_lock_irqsave(&edge->channels_lock, flags); | ||
1177 | list_for_each_entry(channel, &edge->channels, list) { | 1298 | list_for_each_entry(channel, &edge->channels, list) { |
1178 | if (channel->state != SMD_CHANNEL_CLOSED) | 1299 | if (channel->state != SMD_CHANNEL_CLOSED) |
1179 | continue; | 1300 | continue; |
@@ -1183,7 +1304,9 @@ static void qcom_channel_state_worker(struct work_struct *work) | |||
1183 | remote_state != SMD_CHANNEL_OPENED) | 1304 | remote_state != SMD_CHANNEL_OPENED) |
1184 | continue; | 1305 | continue; |
1185 | 1306 | ||
1307 | spin_unlock_irqrestore(&edge->channels_lock, flags); | ||
1186 | qcom_smd_create_device(channel); | 1308 | qcom_smd_create_device(channel); |
1309 | spin_lock_irqsave(&edge->channels_lock, flags); | ||
1187 | } | 1310 | } |
1188 | 1311 | ||
1189 | /* | 1312 | /* |
@@ -1200,8 +1323,11 @@ static void qcom_channel_state_worker(struct work_struct *work) | |||
1200 | remote_state == SMD_CHANNEL_OPENED) | 1323 | remote_state == SMD_CHANNEL_OPENED) |
1201 | continue; | 1324 | continue; |
1202 | 1325 | ||
1326 | spin_unlock_irqrestore(&edge->channels_lock, flags); | ||
1203 | qcom_smd_destroy_device(channel); | 1327 | qcom_smd_destroy_device(channel); |
1328 | spin_lock_irqsave(&edge->channels_lock, flags); | ||
1204 | } | 1329 | } |
1330 | spin_unlock_irqrestore(&edge->channels_lock, flags); | ||
1205 | } | 1331 | } |
1206 | 1332 | ||
1207 | /* | 1333 | /* |
@@ -1219,7 +1345,8 @@ static int qcom_smd_parse_edge(struct device *dev, | |||
1219 | INIT_LIST_HEAD(&edge->channels); | 1345 | INIT_LIST_HEAD(&edge->channels); |
1220 | spin_lock_init(&edge->channels_lock); | 1346 | spin_lock_init(&edge->channels_lock); |
1221 | 1347 | ||
1222 | INIT_WORK(&edge->work, qcom_channel_state_worker); | 1348 | INIT_WORK(&edge->scan_work, qcom_channel_scan_worker); |
1349 | INIT_WORK(&edge->state_work, qcom_channel_state_worker); | ||
1223 | 1350 | ||
1224 | edge->of_node = of_node_get(node); | 1351 | edge->of_node = of_node_get(node); |
1225 | 1352 | ||
@@ -1303,13 +1430,13 @@ static int qcom_smd_probe(struct platform_device *pdev) | |||
1303 | for_each_available_child_of_node(pdev->dev.of_node, node) { | 1430 | for_each_available_child_of_node(pdev->dev.of_node, node) { |
1304 | edge = &smd->edges[i++]; | 1431 | edge = &smd->edges[i++]; |
1305 | edge->smd = smd; | 1432 | edge->smd = smd; |
1433 | init_waitqueue_head(&edge->new_channel_event); | ||
1306 | 1434 | ||
1307 | ret = qcom_smd_parse_edge(&pdev->dev, node, edge); | 1435 | ret = qcom_smd_parse_edge(&pdev->dev, node, edge); |
1308 | if (ret) | 1436 | if (ret) |
1309 | continue; | 1437 | continue; |
1310 | 1438 | ||
1311 | edge->need_rescan = true; | 1439 | schedule_work(&edge->scan_work); |
1312 | schedule_work(&edge->work); | ||
1313 | } | 1440 | } |
1314 | 1441 | ||
1315 | platform_set_drvdata(pdev, smd); | 1442 | platform_set_drvdata(pdev, smd); |
@@ -1332,8 +1459,10 @@ static int qcom_smd_remove(struct platform_device *pdev) | |||
1332 | edge = &smd->edges[i]; | 1459 | edge = &smd->edges[i]; |
1333 | 1460 | ||
1334 | disable_irq(edge->irq); | 1461 | disable_irq(edge->irq); |
1335 | cancel_work_sync(&edge->work); | 1462 | cancel_work_sync(&edge->scan_work); |
1463 | cancel_work_sync(&edge->state_work); | ||
1336 | 1464 | ||
1465 | /* No need to lock here, because the writer is gone */ | ||
1337 | list_for_each_entry(channel, &edge->channels, list) { | 1466 | list_for_each_entry(channel, &edge->channels, list) { |
1338 | if (!channel->qsdev) | 1467 | if (!channel->qsdev) |
1339 | continue; | 1468 | continue; |
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 19019aa092e8..2e1aa9f130f4 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c | |||
@@ -684,8 +684,7 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev, | |||
684 | 684 | ||
685 | smem->regions[i].aux_base = (u32)r.start; | 685 | smem->regions[i].aux_base = (u32)r.start; |
686 | smem->regions[i].size = resource_size(&r); | 686 | smem->regions[i].size = resource_size(&r); |
687 | smem->regions[i].virt_base = devm_ioremap_nocache(dev, r.start, | 687 | smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, resource_size(&r)); |
688 | resource_size(&r)); | ||
689 | if (!smem->regions[i].virt_base) | 688 | if (!smem->regions[i].virt_base) |
690 | return -ENOMEM; | 689 | return -ENOMEM; |
691 | 690 | ||
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c index 5548a31e1a39..f324451e0940 100644 --- a/drivers/soc/qcom/spm.c +++ b/drivers/soc/qcom/spm.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. | 2 | * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. |
3 | * Copyright (c) 2014,2015, Linaro Ltd. | 3 | * Copyright (c) 2014,2015, Linaro Ltd. |
4 | * | 4 | * |
5 | * SAW power controller driver | ||
6 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 and | 8 | * it under the terms of the GNU General Public License version 2 and |
7 | * only version 2 as published by the Free Software Foundation. | 9 | * only version 2 as published by the Free Software Foundation. |
@@ -12,7 +14,6 @@ | |||
12 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
13 | */ | 15 | */ |
14 | 16 | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -378,8 +379,5 @@ static struct platform_driver spm_driver = { | |||
378 | .of_match_table = spm_match_table, | 379 | .of_match_table = spm_match_table, |
379 | }, | 380 | }, |
380 | }; | 381 | }; |
381 | module_platform_driver(spm_driver); | ||
382 | 382 | ||
383 | MODULE_LICENSE("GPL v2"); | 383 | builtin_platform_driver(spm_driver); |
384 | MODULE_DESCRIPTION("SAW power controller driver"); | ||
385 | MODULE_ALIAS("platform:saw"); | ||
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c index 7a986f881d5c..c544f3d2c6ee 100644 --- a/drivers/soc/qcom/wcnss_ctrl.c +++ b/drivers/soc/qcom/wcnss_ctrl.c | |||
@@ -100,17 +100,17 @@ struct wcnss_download_nv_resp { | |||
100 | 100 | ||
101 | /** | 101 | /** |
102 | * wcnss_ctrl_smd_callback() - handler from SMD responses | 102 | * wcnss_ctrl_smd_callback() - handler from SMD responses |
103 | * @qsdev: smd device handle | 103 | * @channel: smd channel handle |
104 | * @data: pointer to the incoming data packet | 104 | * @data: pointer to the incoming data packet |
105 | * @count: size of the incoming data packet | 105 | * @count: size of the incoming data packet |
106 | * | 106 | * |
107 | * Handles any incoming packets from the remote WCNSS_CTRL service. | 107 | * Handles any incoming packets from the remote WCNSS_CTRL service. |
108 | */ | 108 | */ |
109 | static int wcnss_ctrl_smd_callback(struct qcom_smd_device *qsdev, | 109 | static int wcnss_ctrl_smd_callback(struct qcom_smd_channel *channel, |
110 | const void *data, | 110 | const void *data, |
111 | size_t count) | 111 | size_t count) |
112 | { | 112 | { |
113 | struct wcnss_ctrl *wcnss = dev_get_drvdata(&qsdev->dev); | 113 | struct wcnss_ctrl *wcnss = qcom_smd_get_drvdata(channel); |
114 | const struct wcnss_download_nv_resp *nvresp; | 114 | const struct wcnss_download_nv_resp *nvresp; |
115 | const struct wcnss_version_resp *version; | 115 | const struct wcnss_version_resp *version; |
116 | const struct wcnss_msg_hdr *hdr = data; | 116 | const struct wcnss_msg_hdr *hdr = data; |
@@ -246,7 +246,7 @@ static int wcnss_ctrl_probe(struct qcom_smd_device *sdev) | |||
246 | init_completion(&wcnss->ack); | 246 | init_completion(&wcnss->ack); |
247 | INIT_WORK(&wcnss->download_nv_work, wcnss_download_nv); | 247 | INIT_WORK(&wcnss->download_nv_work, wcnss_download_nv); |
248 | 248 | ||
249 | dev_set_drvdata(&sdev->dev, wcnss); | 249 | qcom_smd_set_drvdata(sdev->channel, wcnss); |
250 | 250 | ||
251 | return wcnss_request_version(wcnss); | 251 | return wcnss_request_version(wcnss); |
252 | } | 252 | } |
diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h index 46a984f5e3a3..cbb0f06c41b2 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_channel *, 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 | #if IS_ENABLED(CONFIG_QCOM_SMD) | 50 | #if IS_ENABLED(CONFIG_QCOM_SMD) |
@@ -50,8 +52,14 @@ struct qcom_smd_driver { | |||
50 | int qcom_smd_driver_register(struct qcom_smd_driver *drv); | 52 | int qcom_smd_driver_register(struct qcom_smd_driver *drv); |
51 | void qcom_smd_driver_unregister(struct qcom_smd_driver *drv); | 53 | void qcom_smd_driver_unregister(struct qcom_smd_driver *drv); |
52 | 54 | ||
55 | struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel, | ||
56 | const char *name, | ||
57 | qcom_smd_cb_t cb); | ||
58 | void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel); | ||
59 | void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data); | ||
53 | int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len); | 60 | int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len); |
54 | 61 | ||
62 | |||
55 | #else | 63 | #else |
56 | 64 | ||
57 | static inline int qcom_smd_driver_register(struct qcom_smd_driver *drv) | 65 | static inline int qcom_smd_driver_register(struct qcom_smd_driver *drv) |
@@ -65,6 +73,29 @@ static inline void qcom_smd_driver_unregister(struct qcom_smd_driver *drv) | |||
65 | WARN_ON(1); | 73 | WARN_ON(1); |
66 | } | 74 | } |
67 | 75 | ||
76 | static inline struct qcom_smd_channel * | ||
77 | qcom_smd_open_channel(struct qcom_smd_channel *channel, | ||
78 | const char *name, | ||
79 | qcom_smd_cb_t cb) | ||
80 | { | ||
81 | /* This shouldn't be possible */ | ||
82 | WARN_ON(1); | ||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel) | ||
87 | { | ||
88 | /* This shouldn't be possible */ | ||
89 | WARN_ON(1); | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
93 | void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data) | ||
94 | { | ||
95 | /* This shouldn't be possible */ | ||
96 | WARN_ON(1); | ||
97 | } | ||
98 | |||
68 | static inline int qcom_smd_send(struct qcom_smd_channel *channel, | 99 | static inline int qcom_smd_send(struct qcom_smd_channel *channel, |
69 | const void *data, int len) | 100 | const void *data, int len) |
70 | { | 101 | { |
diff --git a/include/linux/soc/qcom/smem_state.h b/include/linux/soc/qcom/smem_state.h index f35e1512fcaa..7b88697929e9 100644 --- a/include/linux/soc/qcom/smem_state.h +++ b/include/linux/soc/qcom/smem_state.h | |||
@@ -1,12 +1,17 @@ | |||
1 | #ifndef __QCOM_SMEM_STATE__ | 1 | #ifndef __QCOM_SMEM_STATE__ |
2 | #define __QCOM_SMEM_STATE__ | 2 | #define __QCOM_SMEM_STATE__ |
3 | 3 | ||
4 | #include <linux/errno.h> | ||
5 | |||
6 | struct device_node; | ||
4 | struct qcom_smem_state; | 7 | struct qcom_smem_state; |
5 | 8 | ||
6 | struct qcom_smem_state_ops { | 9 | struct qcom_smem_state_ops { |
7 | int (*update_bits)(void *, u32, u32); | 10 | int (*update_bits)(void *, u32, u32); |
8 | }; | 11 | }; |
9 | 12 | ||
13 | #ifdef CONFIG_QCOM_SMEM_STATE | ||
14 | |||
10 | struct qcom_smem_state *qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit); | 15 | struct qcom_smem_state *qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit); |
11 | void qcom_smem_state_put(struct qcom_smem_state *); | 16 | void qcom_smem_state_put(struct qcom_smem_state *); |
12 | 17 | ||
@@ -15,4 +20,34 @@ int qcom_smem_state_update_bits(struct qcom_smem_state *state, u32 mask, u32 val | |||
15 | struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, const struct qcom_smem_state_ops *ops, void *data); | 20 | struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, const struct qcom_smem_state_ops *ops, void *data); |
16 | void qcom_smem_state_unregister(struct qcom_smem_state *state); | 21 | void qcom_smem_state_unregister(struct qcom_smem_state *state); |
17 | 22 | ||
23 | #else | ||
24 | |||
25 | static inline struct qcom_smem_state *qcom_smem_state_get(struct device *dev, | ||
26 | const char *con_id, unsigned *bit) | ||
27 | { | ||
28 | return ERR_PTR(-EINVAL); | ||
29 | } | ||
30 | |||
31 | static inline void qcom_smem_state_put(struct qcom_smem_state *state) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | static inline int qcom_smem_state_update_bits(struct qcom_smem_state *state, | ||
36 | u32 mask, u32 value) | ||
37 | { | ||
38 | return -EINVAL; | ||
39 | } | ||
40 | |||
41 | static inline struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, | ||
42 | const struct qcom_smem_state_ops *ops, void *data) | ||
43 | { | ||
44 | return ERR_PTR(-EINVAL); | ||
45 | } | ||
46 | |||
47 | static inline void qcom_smem_state_unregister(struct qcom_smem_state *state) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | #endif | ||
52 | |||
18 | #endif | 53 | #endif |
diff --git a/net/qrtr/smd.c b/net/qrtr/smd.c index 84ebce73aa23..0d11132b3370 100644 --- a/net/qrtr/smd.c +++ b/net/qrtr/smd.c | |||
@@ -21,13 +21,14 @@ | |||
21 | struct qrtr_smd_dev { | 21 | struct qrtr_smd_dev { |
22 | struct qrtr_endpoint ep; | 22 | struct qrtr_endpoint ep; |
23 | struct qcom_smd_channel *channel; | 23 | struct qcom_smd_channel *channel; |
24 | struct device *dev; | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | /* from smd to qrtr */ | 27 | /* from smd to qrtr */ |
27 | static int qcom_smd_qrtr_callback(struct qcom_smd_device *sdev, | 28 | static int qcom_smd_qrtr_callback(struct qcom_smd_channel *channel, |
28 | const void *data, size_t len) | 29 | const void *data, size_t len) |
29 | { | 30 | { |
30 | struct qrtr_smd_dev *qdev = dev_get_drvdata(&sdev->dev); | 31 | struct qrtr_smd_dev *qdev = qcom_smd_get_drvdata(channel); |
31 | int rc; | 32 | int rc; |
32 | 33 | ||
33 | if (!qdev) | 34 | if (!qdev) |
@@ -35,7 +36,7 @@ static int qcom_smd_qrtr_callback(struct qcom_smd_device *sdev, | |||
35 | 36 | ||
36 | rc = qrtr_endpoint_post(&qdev->ep, data, len); | 37 | rc = qrtr_endpoint_post(&qdev->ep, data, len); |
37 | if (rc == -EINVAL) { | 38 | if (rc == -EINVAL) { |
38 | dev_err(&sdev->dev, "invalid ipcrouter packet\n"); | 39 | dev_err(qdev->dev, "invalid ipcrouter packet\n"); |
39 | /* return 0 to let smd drop the packet */ | 40 | /* return 0 to let smd drop the packet */ |
40 | rc = 0; | 41 | rc = 0; |
41 | } | 42 | } |
@@ -73,12 +74,14 @@ static int qcom_smd_qrtr_probe(struct qcom_smd_device *sdev) | |||
73 | return -ENOMEM; | 74 | return -ENOMEM; |
74 | 75 | ||
75 | qdev->channel = sdev->channel; | 76 | qdev->channel = sdev->channel; |
77 | qdev->dev = &sdev->dev; | ||
76 | qdev->ep.xmit = qcom_smd_qrtr_send; | 78 | qdev->ep.xmit = qcom_smd_qrtr_send; |
77 | 79 | ||
78 | rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); | 80 | rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); |
79 | if (rc) | 81 | if (rc) |
80 | return rc; | 82 | return rc; |
81 | 83 | ||
84 | qcom_smd_set_drvdata(sdev->channel, qdev); | ||
82 | dev_set_drvdata(&sdev->dev, qdev); | 85 | dev_set_drvdata(&sdev->dev, qdev); |
83 | 86 | ||
84 | dev_dbg(&sdev->dev, "Qualcomm SMD QRTR driver probed\n"); | 87 | dev_dbg(&sdev->dev, "Qualcomm SMD QRTR driver probed\n"); |