summaryrefslogtreecommitdiffstats
path: root/drivers/hsi
diff options
context:
space:
mode:
authorSebastian Reichel <sre@kernel.org>2016-06-17 18:55:22 -0400
committerSebastian Reichel <sre@kernel.org>2016-06-27 18:37:58 -0400
commit6d6c30973b62f1979e39f5e768b3b31c6dc81c4e (patch)
tree66af0939f8d48fdbdc0841af1fcc00b84a904014 /drivers/hsi
parentb6616be32412a4c9a0f04aec247d2760fcad8cfd (diff)
HSI: ssi_protocol: avoid ssi_waketest call with held spinlock
This avoids calling ssi_waketest(), while a spinlock is being hold, since ssi_waketest may sleep once irq_safe runtime pm is disabled. Signed-off-by: Sebastian Reichel <sre@kernel.org> Tested-by: Pavel Machek <pavel@ucw.cz>
Diffstat (limited to 'drivers/hsi')
-rw-r--r--drivers/hsi/clients/ssi_protocol.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
index 6595d2091268..8534efda8140 100644
--- a/drivers/hsi/clients/ssi_protocol.c
+++ b/drivers/hsi/clients/ssi_protocol.c
@@ -88,6 +88,8 @@ void ssi_waketest(struct hsi_client *cl, unsigned int enable);
88#define SSIP_READY_CMD SSIP_CMD(SSIP_READY, 0) 88#define SSIP_READY_CMD SSIP_CMD(SSIP_READY, 0)
89#define SSIP_SWBREAK_CMD SSIP_CMD(SSIP_SW_BREAK, 0) 89#define SSIP_SWBREAK_CMD SSIP_CMD(SSIP_SW_BREAK, 0)
90 90
91#define SSIP_WAKETEST_FLAG 0
92
91/* Main state machine states */ 93/* Main state machine states */
92enum { 94enum {
93 INIT, 95 INIT,
@@ -116,7 +118,7 @@ enum {
116 * @main_state: Main state machine 118 * @main_state: Main state machine
117 * @send_state: TX state machine 119 * @send_state: TX state machine
118 * @recv_state: RX state machine 120 * @recv_state: RX state machine
119 * @waketest: Flag to follow wake line test 121 * @flags: Flags, currently only used to follow wake line test
120 * @rxid: RX data id 122 * @rxid: RX data id
121 * @txid: TX data id 123 * @txid: TX data id
122 * @txqueue_len: TX queue length 124 * @txqueue_len: TX queue length
@@ -137,7 +139,7 @@ struct ssi_protocol {
137 unsigned int main_state; 139 unsigned int main_state;
138 unsigned int send_state; 140 unsigned int send_state;
139 unsigned int recv_state; 141 unsigned int recv_state;
140 unsigned int waketest:1; 142 unsigned long flags;
141 u8 rxid; 143 u8 rxid;
142 u8 txid; 144 u8 txid;
143 unsigned int txqueue_len; 145 unsigned int txqueue_len;
@@ -405,15 +407,17 @@ static void ssip_reset(struct hsi_client *cl)
405 spin_lock_bh(&ssi->lock); 407 spin_lock_bh(&ssi->lock);
406 if (ssi->send_state != SEND_IDLE) 408 if (ssi->send_state != SEND_IDLE)
407 hsi_stop_tx(cl); 409 hsi_stop_tx(cl);
408 if (ssi->waketest) 410 spin_unlock_bh(&ssi->lock);
409 ssi_waketest(cl, 0); 411 if (test_and_clear_bit(SSIP_WAKETEST_FLAG, &ssi->flags))
412 ssi_waketest(cl, 0); /* FIXME: To be removed */
413 spin_lock_bh(&ssi->lock);
410 del_timer(&ssi->rx_wd); 414 del_timer(&ssi->rx_wd);
411 del_timer(&ssi->tx_wd); 415 del_timer(&ssi->tx_wd);
412 del_timer(&ssi->keep_alive); 416 del_timer(&ssi->keep_alive);
413 ssi->main_state = 0; 417 ssi->main_state = 0;
414 ssi->send_state = 0; 418 ssi->send_state = 0;
415 ssi->recv_state = 0; 419 ssi->recv_state = 0;
416 ssi->waketest = 0; 420 ssi->flags = 0;
417 ssi->rxid = 0; 421 ssi->rxid = 0;
418 ssi->txid = 0; 422 ssi->txid = 0;
419 list_for_each_safe(head, tmp, &ssi->txqueue) { 423 list_for_each_safe(head, tmp, &ssi->txqueue) {
@@ -437,7 +441,8 @@ static void ssip_dump_state(struct hsi_client *cl)
437 dev_err(&cl->device, "Send state: %d\n", ssi->send_state); 441 dev_err(&cl->device, "Send state: %d\n", ssi->send_state);
438 dev_err(&cl->device, "CMT %s\n", (ssi->main_state == ACTIVE) ? 442 dev_err(&cl->device, "CMT %s\n", (ssi->main_state == ACTIVE) ?
439 "Online" : "Offline"); 443 "Online" : "Offline");
440 dev_err(&cl->device, "Wake test %d\n", ssi->waketest); 444 dev_err(&cl->device, "Wake test %d\n",
445 test_bit(SSIP_WAKETEST_FLAG, &ssi->flags));
441 dev_err(&cl->device, "Data RX id: %d\n", ssi->rxid); 446 dev_err(&cl->device, "Data RX id: %d\n", ssi->rxid);
442 dev_err(&cl->device, "Data TX id: %d\n", ssi->txid); 447 dev_err(&cl->device, "Data TX id: %d\n", ssi->txid);
443 448
@@ -668,10 +673,12 @@ static void ssip_rx_bootinforeq(struct hsi_client *cl, u32 cmd)
668 case HANDSHAKE: 673 case HANDSHAKE:
669 spin_lock(&ssi->lock); 674 spin_lock(&ssi->lock);
670 ssi->main_state = HANDSHAKE; 675 ssi->main_state = HANDSHAKE;
671 if (!ssi->waketest) { 676 spin_unlock(&ssi->lock);
672 ssi->waketest = 1; 677
678 if (!test_and_set_bit(SSIP_WAKETEST_FLAG, &ssi->flags))
673 ssi_waketest(cl, 1); /* FIXME: To be removed */ 679 ssi_waketest(cl, 1); /* FIXME: To be removed */
674 } 680
681 spin_lock(&ssi->lock);
675 /* Start boot handshake watchdog */ 682 /* Start boot handshake watchdog */
676 mod_timer(&ssi->tx_wd, jiffies + msecs_to_jiffies(SSIP_WDTOUT)); 683 mod_timer(&ssi->tx_wd, jiffies + msecs_to_jiffies(SSIP_WDTOUT));
677 spin_unlock(&ssi->lock); 684 spin_unlock(&ssi->lock);
@@ -718,10 +725,12 @@ static void ssip_rx_waketest(struct hsi_client *cl, u32 cmd)
718 spin_unlock(&ssi->lock); 725 spin_unlock(&ssi->lock);
719 return; 726 return;
720 } 727 }
721 if (ssi->waketest) { 728 spin_unlock(&ssi->lock);
722 ssi->waketest = 0; 729
730 if (test_and_clear_bit(SSIP_WAKETEST_FLAG, &ssi->flags))
723 ssi_waketest(cl, 0); /* FIXME: To be removed */ 731 ssi_waketest(cl, 0); /* FIXME: To be removed */
724 } 732
733 spin_lock(&ssi->lock);
725 ssi->main_state = ACTIVE; 734 ssi->main_state = ACTIVE;
726 del_timer(&ssi->tx_wd); /* Stop boot handshake timer */ 735 del_timer(&ssi->tx_wd); /* Stop boot handshake timer */
727 spin_unlock(&ssi->lock); 736 spin_unlock(&ssi->lock);
@@ -926,11 +935,11 @@ static int ssip_pn_open(struct net_device *dev)
926 } 935 }
927 dev_dbg(&cl->device, "Configuring SSI port\n"); 936 dev_dbg(&cl->device, "Configuring SSI port\n");
928 hsi_setup(cl); 937 hsi_setup(cl);
929 spin_lock_bh(&ssi->lock); 938
930 if (!ssi->waketest) { 939 if (!test_and_set_bit(SSIP_WAKETEST_FLAG, &ssi->flags))
931 ssi->waketest = 1;
932 ssi_waketest(cl, 1); /* FIXME: To be removed */ 940 ssi_waketest(cl, 1); /* FIXME: To be removed */
933 } 941
942 spin_lock_bh(&ssi->lock);
934 ssi->main_state = HANDSHAKE; 943 ssi->main_state = HANDSHAKE;
935 spin_unlock_bh(&ssi->lock); 944 spin_unlock_bh(&ssi->lock);
936 945