aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2016-05-13 17:36:11 -0400
committerBjorn Andersson <bjorn.andersson@linaro.org>2016-05-13 17:42:23 -0400
commitf79a917e69e1f5cd86e864b67f06147f1b0340f4 (patch)
tree561675103ee8a220365e7c907e51d6c362727ff7
parented7cbbce544856b20e5811de373cf92e92499771 (diff)
parentb853cb9628bfbcc4017da46d5f5b46e3eba9d8c6 (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--MAINTAINERS3
-rw-r--r--drivers/soc/qcom/smd-rpm.c9
-rw-r--r--drivers/soc/qcom/smd.c247
-rw-r--r--drivers/soc/qcom/smem.c3
-rw-r--r--drivers/soc/qcom/spm.c8
-rw-r--r--drivers/soc/qcom/wcnss_ctrl.c8
-rw-r--r--include/linux/soc/qcom/smd.h33
-rw-r--r--include/linux/soc/qcom/smem_state.h35
-rw-r--r--net/qrtr/smd.c9
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
1470F: arch/arm/boot/dts/qcom-*.dtsi 1470F: arch/arm/boot/dts/qcom-*.dtsi
1471F: arch/arm/mach-qcom/ 1471F: arch/arm/mach-qcom/
1472F: arch/arm64/boot/dts/qcom/* 1472F: arch/arm64/boot/dts/qcom/*
1473F: drivers/i2c/busses/i2c-qup.c
1474F: drivers/clk/qcom/
1473F: drivers/soc/qcom/ 1475F: drivers/soc/qcom/
1476F: drivers/spi/spi-qup.c
1474F: drivers/tty/serial/msm_serial.h 1477F: drivers/tty/serial/msm_serial.h
1475F: drivers/tty/serial/msm_serial.c 1478F: drivers/tty/serial/msm_serial.c
1476F: drivers/*/pm8???-* 1479F: 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 */
34struct qcom_smd_rpm { 34struct 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}
150EXPORT_SYMBOL(qcom_rpm_smd_write); 151EXPORT_SYMBOL(qcom_rpm_smd_write);
151 152
152static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev, 153static 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 */
113struct qcom_smd_edge { 113struct 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 */
388static 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 */
383static size_t qcom_smd_channel_get_rx_avail(struct qcom_smd_channel *channel) 401static 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 */
498static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) 516static 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 */
801static int qcom_smd_dev_probe(struct device *dev) 817static 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 */
840static 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 */
857static 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)
831err: 876err:
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}
997EXPORT_SYMBOL(qcom_smd_driver_register); 1036EXPORT_SYMBOL(qcom_smd_driver_register);
998 1037
1038void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel)
1039{
1040 return channel->drvdata;
1041}
1042EXPORT_SYMBOL(qcom_smd_get_drvdata);
1043
1044void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data)
1045{
1046 channel->drvdata = data;
1047}
1048EXPORT_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}
1007EXPORT_SYMBOL(qcom_smd_driver_unregister); 1058EXPORT_SYMBOL(qcom_smd_driver_unregister);
1008 1059
1060static struct qcom_smd_channel *
1061qcom_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 */
1095struct 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}
1130EXPORT_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 */
1092static void qcom_discover_channels(struct qcom_smd_edge *edge) 1216static 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 */
1157static void qcom_channel_state_worker(struct work_struct *work) 1284static 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};
381module_platform_driver(spm_driver);
382 382
383MODULE_LICENSE("GPL v2"); 383builtin_platform_driver(spm_driver);
384MODULE_DESCRIPTION("SAW power controller driver");
385MODULE_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 */
109static int wcnss_ctrl_smd_callback(struct qcom_smd_device *qsdev, 109static 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
29typedef 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 {
50int qcom_smd_driver_register(struct qcom_smd_driver *drv); 52int qcom_smd_driver_register(struct qcom_smd_driver *drv);
51void qcom_smd_driver_unregister(struct qcom_smd_driver *drv); 53void qcom_smd_driver_unregister(struct qcom_smd_driver *drv);
52 54
55struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel,
56 const char *name,
57 qcom_smd_cb_t cb);
58void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel);
59void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data);
53int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len); 60int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len);
54 61
62
55#else 63#else
56 64
57static inline int qcom_smd_driver_register(struct qcom_smd_driver *drv) 65static 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
76static inline struct qcom_smd_channel *
77qcom_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
86void *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
93void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data)
94{
95 /* This shouldn't be possible */
96 WARN_ON(1);
97}
98
68static inline int qcom_smd_send(struct qcom_smd_channel *channel, 99static 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
6struct device_node;
4struct qcom_smem_state; 7struct qcom_smem_state;
5 8
6struct qcom_smem_state_ops { 9struct 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
10struct qcom_smem_state *qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit); 15struct qcom_smem_state *qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit);
11void qcom_smem_state_put(struct qcom_smem_state *); 16void 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
15struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, const struct qcom_smem_state_ops *ops, void *data); 20struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, const struct qcom_smem_state_ops *ops, void *data);
16void qcom_smem_state_unregister(struct qcom_smem_state *state); 21void qcom_smem_state_unregister(struct qcom_smem_state *state);
17 22
23#else
24
25static 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
31static inline void qcom_smem_state_put(struct qcom_smem_state *state)
32{
33}
34
35static inline int qcom_smem_state_update_bits(struct qcom_smem_state *state,
36 u32 mask, u32 value)
37{
38 return -EINVAL;
39}
40
41static 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
47static 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 @@
21struct qrtr_smd_dev { 21struct 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 */
27static int qcom_smd_qrtr_callback(struct qcom_smd_device *sdev, 28static 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");