aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc/qcom
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-17 19:26:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-17 19:26:30 -0400
commita7fd20d1c476af4563e66865213474a2f9f473a4 (patch)
treefb1399e2f82842450245fb058a8fb23c52865f43 /drivers/soc/qcom
parentb80fed9595513384424cd141923c9161c4b5021b (diff)
parent917fa5353da05e8a0045b8acacba8d50400d5b12 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Highlights: 1) Support SPI based w5100 devices, from Akinobu Mita. 2) Partial Segmentation Offload, from Alexander Duyck. 3) Add GMAC4 support to stmmac driver, from Alexandre TORGUE. 4) Allow cls_flower stats offload, from Amir Vadai. 5) Implement bpf blinding, from Daniel Borkmann. 6) Optimize _ASYNC_ bit twiddling on sockets, unless the socket is actually using FASYNC these atomics are superfluous. From Eric Dumazet. 7) Run TCP more preemptibly, also from Eric Dumazet. 8) Support LED blinking, EEPROM dumps, and rxvlan offloading in mlx5e driver, from Gal Pressman. 9) Allow creating ppp devices via rtnetlink, from Guillaume Nault. 10) Improve BPF usage documentation, from Jesper Dangaard Brouer. 11) Support tunneling offloads in qed, from Manish Chopra. 12) aRFS offloading in mlx5e, from Maor Gottlieb. 13) Add RFS and RPS support to SCTP protocol, from Marcelo Ricardo Leitner. 14) Add MSG_EOR support to TCP, this allows controlling packet coalescing on application record boundaries for more accurate socket timestamp sampling. From Martin KaFai Lau. 15) Fix alignment of 64-bit netlink attributes across the board, from Nicolas Dichtel. 16) Per-vlan stats in bridging, from Nikolay Aleksandrov. 17) Several conversions of drivers to ethtool ksettings, from Philippe Reynes. 18) Checksum neutral ILA in ipv6, from Tom Herbert. 19) Factorize all of the various marvell dsa drivers into one, from Vivien Didelot 20) Add VF support to qed driver, from Yuval Mintz" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1649 commits) Revert "phy dp83867: Fix compilation with CONFIG_OF_MDIO=m" Revert "phy dp83867: Make rgmii parameters optional" r8169: default to 64-bit DMA on recent PCIe chips phy dp83867: Make rgmii parameters optional phy dp83867: Fix compilation with CONFIG_OF_MDIO=m bpf: arm64: remove callee-save registers use for tmp registers asix: Fix offset calculation in asix_rx_fixup() causing slow transmissions switchdev: pass pointer to fib_info instead of copy net_sched: close another race condition in tcf_mirred_release() tipc: fix nametable publication field in nl compat drivers: net: Don't print unpopulated net_device name qed: add support for dcbx. ravb: Add missing free_irq() calls to ravb_close() qed: Remove a stray tab net: ethernet: fec-mpc52xx: use phy_ethtool_{get|set}_link_ksettings net: ethernet: fec-mpc52xx: use phydev from struct net_device bpf, doc: fix typo on bpf_asm descriptions stmmac: hardware TX COE doesn't work when force_thresh_dma_mode is set net: ethernet: fs-enet: use phy_ethtool_{get|set}_link_ksettings net: ethernet: fs-enet: use phydev from struct net_device ...
Diffstat (limited to 'drivers/soc/qcom')
-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
5 files changed, 202 insertions, 73 deletions
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 1fcbb22a4a1c..f9d7a85b2822 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}