@@ -88,6 +88,8 @@ void ssi_waketest(struct hsi_client *cl, unsigned int enable);
88
88
#define SSIP_READY_CMD SSIP_CMD(SSIP_READY, 0)
89
89
#define SSIP_SWBREAK_CMD SSIP_CMD(SSIP_SW_BREAK, 0)
90
90
91
+ #define SSIP_WAKETEST_FLAG 0
92
+
91
93
/* Main state machine states */
92
94
enum {
93
95
INIT ,
@@ -116,7 +118,7 @@ enum {
116
118
* @main_state: Main state machine
117
119
* @send_state: TX state machine
118
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
122
* @rxid: RX data id
121
123
* @txid: TX data id
122
124
* @txqueue_len: TX queue length
@@ -137,7 +139,7 @@ struct ssi_protocol {
137
139
unsigned int main_state ;
138
140
unsigned int send_state ;
139
141
unsigned int recv_state ;
140
- unsigned int waketest : 1 ;
142
+ unsigned long flags ;
141
143
u8 rxid ;
142
144
u8 txid ;
143
145
unsigned int txqueue_len ;
@@ -148,6 +150,7 @@ struct ssi_protocol {
148
150
struct net_device * netdev ;
149
151
struct list_head txqueue ;
150
152
struct list_head cmdqueue ;
153
+ struct work_struct work ;
151
154
struct hsi_client * cl ;
152
155
struct list_head link ;
153
156
atomic_t tx_usecnt ;
@@ -405,15 +408,17 @@ static void ssip_reset(struct hsi_client *cl)
405
408
spin_lock_bh (& ssi -> lock );
406
409
if (ssi -> send_state != SEND_IDLE )
407
410
hsi_stop_tx (cl );
408
- if (ssi -> waketest )
409
- ssi_waketest (cl , 0 );
411
+ spin_unlock_bh (& ssi -> lock );
412
+ if (test_and_clear_bit (SSIP_WAKETEST_FLAG , & ssi -> flags ))
413
+ ssi_waketest (cl , 0 ); /* FIXME: To be removed */
414
+ spin_lock_bh (& ssi -> lock );
410
415
del_timer (& ssi -> rx_wd );
411
416
del_timer (& ssi -> tx_wd );
412
417
del_timer (& ssi -> keep_alive );
413
418
ssi -> main_state = 0 ;
414
419
ssi -> send_state = 0 ;
415
420
ssi -> recv_state = 0 ;
416
- ssi -> waketest = 0 ;
421
+ ssi -> flags = 0 ;
417
422
ssi -> rxid = 0 ;
418
423
ssi -> txid = 0 ;
419
424
list_for_each_safe (head , tmp , & ssi -> txqueue ) {
@@ -437,7 +442,8 @@ static void ssip_dump_state(struct hsi_client *cl)
437
442
dev_err (& cl -> device , "Send state: %d\n" , ssi -> send_state );
438
443
dev_err (& cl -> device , "CMT %s\n" , (ssi -> main_state == ACTIVE ) ?
439
444
"Online" : "Offline" );
440
- dev_err (& cl -> device , "Wake test %d\n" , ssi -> waketest );
445
+ dev_err (& cl -> device , "Wake test %d\n" ,
446
+ test_bit (SSIP_WAKETEST_FLAG , & ssi -> flags ));
441
447
dev_err (& cl -> device , "Data RX id: %d\n" , ssi -> rxid );
442
448
dev_err (& cl -> device , "Data TX id: %d\n" , ssi -> txid );
443
449
@@ -515,17 +521,17 @@ static void ssip_start_rx(struct hsi_client *cl)
515
521
516
522
dev_dbg (& cl -> device , "RX start M(%d) R(%d)\n" , ssi -> main_state ,
517
523
ssi -> recv_state );
518
- spin_lock (& ssi -> lock );
524
+ spin_lock_bh (& ssi -> lock );
519
525
/*
520
526
* We can have two UP events in a row due to a short low
521
527
* high transition. Therefore we need to ignore the sencond UP event.
522
528
*/
523
529
if ((ssi -> main_state != ACTIVE ) || (ssi -> recv_state == RECV_READY )) {
524
- spin_unlock (& ssi -> lock );
530
+ spin_unlock_bh (& ssi -> lock );
525
531
return ;
526
532
}
527
533
ssip_set_rxstate (ssi , RECV_READY );
528
- spin_unlock (& ssi -> lock );
534
+ spin_unlock_bh (& ssi -> lock );
529
535
530
536
msg = ssip_claim_cmd (ssi );
531
537
ssip_set_cmd (msg , SSIP_READY_CMD );
@@ -539,10 +545,10 @@ static void ssip_stop_rx(struct hsi_client *cl)
539
545
struct ssi_protocol * ssi = hsi_client_drvdata (cl );
540
546
541
547
dev_dbg (& cl -> device , "RX stop M(%d)\n" , ssi -> main_state );
542
- spin_lock (& ssi -> lock );
548
+ spin_lock_bh (& ssi -> lock );
543
549
if (likely (ssi -> main_state == ACTIVE ))
544
550
ssip_set_rxstate (ssi , RECV_IDLE );
545
- spin_unlock (& ssi -> lock );
551
+ spin_unlock_bh (& ssi -> lock );
546
552
}
547
553
548
554
static void ssip_free_strans (struct hsi_msg * msg )
@@ -559,9 +565,9 @@ static void ssip_strans_complete(struct hsi_msg *msg)
559
565
560
566
data = msg -> context ;
561
567
ssip_release_cmd (msg );
562
- spin_lock (& ssi -> lock );
568
+ spin_lock_bh (& ssi -> lock );
563
569
ssip_set_txstate (ssi , SENDING );
564
- spin_unlock (& ssi -> lock );
570
+ spin_unlock_bh (& ssi -> lock );
565
571
hsi_async_write (cl , data );
566
572
}
567
573
@@ -666,15 +672,17 @@ static void ssip_rx_bootinforeq(struct hsi_client *cl, u32 cmd)
666
672
/* Fall through */
667
673
case INIT :
668
674
case HANDSHAKE :
669
- spin_lock (& ssi -> lock );
675
+ spin_lock_bh (& ssi -> lock );
670
676
ssi -> main_state = HANDSHAKE ;
671
- if (!ssi -> waketest ) {
672
- ssi -> waketest = 1 ;
677
+ spin_unlock_bh (& ssi -> lock );
678
+
679
+ if (!test_and_set_bit (SSIP_WAKETEST_FLAG , & ssi -> flags ))
673
680
ssi_waketest (cl , 1 ); /* FIXME: To be removed */
674
- }
681
+
682
+ spin_lock_bh (& ssi -> lock );
675
683
/* Start boot handshake watchdog */
676
684
mod_timer (& ssi -> tx_wd , jiffies + msecs_to_jiffies (SSIP_WDTOUT ));
677
- spin_unlock (& ssi -> lock );
685
+ spin_unlock_bh (& ssi -> lock );
678
686
dev_dbg (& cl -> device , "Send BOOTINFO_RESP\n" );
679
687
if (SSIP_DATA_VERSION (cmd ) != SSIP_LOCAL_VERID )
680
688
dev_warn (& cl -> device , "boot info req verid mismatch\n" );
@@ -696,35 +704,37 @@ static void ssip_rx_bootinforesp(struct hsi_client *cl, u32 cmd)
696
704
if (SSIP_DATA_VERSION (cmd ) != SSIP_LOCAL_VERID )
697
705
dev_warn (& cl -> device , "boot info resp verid mismatch\n" );
698
706
699
- spin_lock (& ssi -> lock );
707
+ spin_lock_bh (& ssi -> lock );
700
708
if (ssi -> main_state != ACTIVE )
701
709
/* Use tx_wd as a boot watchdog in non ACTIVE state */
702
710
mod_timer (& ssi -> tx_wd , jiffies + msecs_to_jiffies (SSIP_WDTOUT ));
703
711
else
704
712
dev_dbg (& cl -> device , "boot info resp ignored M(%d)\n" ,
705
713
ssi -> main_state );
706
- spin_unlock (& ssi -> lock );
714
+ spin_unlock_bh (& ssi -> lock );
707
715
}
708
716
709
717
static void ssip_rx_waketest (struct hsi_client * cl , u32 cmd )
710
718
{
711
719
struct ssi_protocol * ssi = hsi_client_drvdata (cl );
712
720
unsigned int wkres = SSIP_PAYLOAD (cmd );
713
721
714
- spin_lock (& ssi -> lock );
722
+ spin_lock_bh (& ssi -> lock );
715
723
if (ssi -> main_state != HANDSHAKE ) {
716
724
dev_dbg (& cl -> device , "wake lines test ignored M(%d)\n" ,
717
725
ssi -> main_state );
718
- spin_unlock (& ssi -> lock );
726
+ spin_unlock_bh (& ssi -> lock );
719
727
return ;
720
728
}
721
- if (ssi -> waketest ) {
722
- ssi -> waketest = 0 ;
729
+ spin_unlock_bh (& ssi -> lock );
730
+
731
+ if (test_and_clear_bit (SSIP_WAKETEST_FLAG , & ssi -> flags ))
723
732
ssi_waketest (cl , 0 ); /* FIXME: To be removed */
724
- }
733
+
734
+ spin_lock_bh (& ssi -> lock );
725
735
ssi -> main_state = ACTIVE ;
726
736
del_timer (& ssi -> tx_wd ); /* Stop boot handshake timer */
727
- spin_unlock (& ssi -> lock );
737
+ spin_unlock_bh (& ssi -> lock );
728
738
729
739
dev_notice (& cl -> device , "WAKELINES TEST %s\n" ,
730
740
wkres & SSIP_WAKETEST_FAILED ? "FAILED" : "OK" );
@@ -741,20 +751,20 @@ static void ssip_rx_ready(struct hsi_client *cl)
741
751
{
742
752
struct ssi_protocol * ssi = hsi_client_drvdata (cl );
743
753
744
- spin_lock (& ssi -> lock );
754
+ spin_lock_bh (& ssi -> lock );
745
755
if (unlikely (ssi -> main_state != ACTIVE )) {
746
756
dev_dbg (& cl -> device , "READY on wrong state: S(%d) M(%d)\n" ,
747
757
ssi -> send_state , ssi -> main_state );
748
- spin_unlock (& ssi -> lock );
758
+ spin_unlock_bh (& ssi -> lock );
749
759
return ;
750
760
}
751
761
if (ssi -> send_state != WAIT4READY ) {
752
762
dev_dbg (& cl -> device , "Ignore spurious READY command\n" );
753
- spin_unlock (& ssi -> lock );
763
+ spin_unlock_bh (& ssi -> lock );
754
764
return ;
755
765
}
756
766
ssip_set_txstate (ssi , SEND_READY );
757
- spin_unlock (& ssi -> lock );
767
+ spin_unlock_bh (& ssi -> lock );
758
768
ssip_xmit (cl );
759
769
}
760
770
@@ -766,22 +776,22 @@ static void ssip_rx_strans(struct hsi_client *cl, u32 cmd)
766
776
int len = SSIP_PDU_LENGTH (cmd );
767
777
768
778
dev_dbg (& cl -> device , "RX strans: %d frames\n" , len );
769
- spin_lock (& ssi -> lock );
779
+ spin_lock_bh (& ssi -> lock );
770
780
if (unlikely (ssi -> main_state != ACTIVE )) {
771
781
dev_err (& cl -> device , "START TRANS wrong state: S(%d) M(%d)\n" ,
772
782
ssi -> send_state , ssi -> main_state );
773
- spin_unlock (& ssi -> lock );
783
+ spin_unlock_bh (& ssi -> lock );
774
784
return ;
775
785
}
776
786
ssip_set_rxstate (ssi , RECEIVING );
777
787
if (unlikely (SSIP_MSG_ID (cmd ) != ssi -> rxid )) {
778
788
dev_err (& cl -> device , "START TRANS id %d expected %d\n" ,
779
789
SSIP_MSG_ID (cmd ), ssi -> rxid );
780
- spin_unlock (& ssi -> lock );
790
+ spin_unlock_bh (& ssi -> lock );
781
791
goto out1 ;
782
792
}
783
793
ssi -> rxid ++ ;
784
- spin_unlock (& ssi -> lock );
794
+ spin_unlock_bh (& ssi -> lock );
785
795
skb = netdev_alloc_skb (ssi -> netdev , len * 4 );
786
796
if (unlikely (!skb )) {
787
797
dev_err (& cl -> device , "No memory for rx skb\n" );
@@ -849,17 +859,17 @@ static void ssip_swbreak_complete(struct hsi_msg *msg)
849
859
struct ssi_protocol * ssi = hsi_client_drvdata (cl );
850
860
851
861
ssip_release_cmd (msg );
852
- spin_lock (& ssi -> lock );
862
+ spin_lock_bh (& ssi -> lock );
853
863
if (list_empty (& ssi -> txqueue )) {
854
864
if (atomic_read (& ssi -> tx_usecnt )) {
855
865
ssip_set_txstate (ssi , SEND_READY );
856
866
} else {
857
867
ssip_set_txstate (ssi , SEND_IDLE );
858
868
hsi_stop_tx (cl );
859
869
}
860
- spin_unlock (& ssi -> lock );
870
+ spin_unlock_bh (& ssi -> lock );
861
871
} else {
862
- spin_unlock (& ssi -> lock );
872
+ spin_unlock_bh (& ssi -> lock );
863
873
ssip_xmit (cl );
864
874
}
865
875
netif_wake_queue (ssi -> netdev );
@@ -876,17 +886,17 @@ static void ssip_tx_data_complete(struct hsi_msg *msg)
876
886
ssip_error (cl );
877
887
goto out ;
878
888
}
879
- spin_lock (& ssi -> lock );
889
+ spin_lock_bh (& ssi -> lock );
880
890
if (list_empty (& ssi -> txqueue )) {
881
891
ssip_set_txstate (ssi , SENDING_SWBREAK );
882
- spin_unlock (& ssi -> lock );
892
+ spin_unlock_bh (& ssi -> lock );
883
893
cmsg = ssip_claim_cmd (ssi );
884
894
ssip_set_cmd (cmsg , SSIP_SWBREAK_CMD );
885
895
cmsg -> complete = ssip_swbreak_complete ;
886
896
dev_dbg (& cl -> device , "Send SWBREAK\n" );
887
897
hsi_async_write (cl , cmsg );
888
898
} else {
889
- spin_unlock (& ssi -> lock );
899
+ spin_unlock_bh (& ssi -> lock );
890
900
ssip_xmit (cl );
891
901
}
892
902
out :
@@ -926,11 +936,11 @@ static int ssip_pn_open(struct net_device *dev)
926
936
}
927
937
dev_dbg (& cl -> device , "Configuring SSI port\n" );
928
938
hsi_setup (cl );
929
- spin_lock_bh (& ssi -> lock );
930
- if (!ssi -> waketest ) {
931
- ssi -> waketest = 1 ;
939
+
940
+ if (!test_and_set_bit (SSIP_WAKETEST_FLAG , & ssi -> flags ))
932
941
ssi_waketest (cl , 1 ); /* FIXME: To be removed */
933
- }
942
+
943
+ spin_lock_bh (& ssi -> lock );
934
944
ssi -> main_state = HANDSHAKE ;
935
945
spin_unlock_bh (& ssi -> lock );
936
946
@@ -959,6 +969,15 @@ static int ssip_pn_set_mtu(struct net_device *dev, int new_mtu)
959
969
return 0 ;
960
970
}
961
971
972
+ static void ssip_xmit_work (struct work_struct * work )
973
+ {
974
+ struct ssi_protocol * ssi =
975
+ container_of (work , struct ssi_protocol , work );
976
+ struct hsi_client * cl = ssi -> cl ;
977
+
978
+ ssip_xmit (cl );
979
+ }
980
+
962
981
static int ssip_pn_xmit (struct sk_buff * skb , struct net_device * dev )
963
982
{
964
983
struct hsi_client * cl = to_hsi_client (dev -> dev .parent );
@@ -1011,7 +1030,7 @@ static int ssip_pn_xmit(struct sk_buff *skb, struct net_device *dev)
1011
1030
dev_dbg (& cl -> device , "Start TX on SEND READY qlen %d\n" ,
1012
1031
ssi -> txqueue_len );
1013
1032
spin_unlock_bh (& ssi -> lock );
1014
- ssip_xmit ( cl );
1033
+ schedule_work ( & ssi -> work );
1015
1034
} else {
1016
1035
spin_unlock_bh (& ssi -> lock );
1017
1036
}
@@ -1088,6 +1107,7 @@ static int ssi_protocol_probe(struct device *dev)
1088
1107
atomic_set (& ssi -> tx_usecnt , 0 );
1089
1108
hsi_client_set_drvdata (cl , ssi );
1090
1109
ssi -> cl = cl ;
1110
+ INIT_WORK (& ssi -> work , ssip_xmit_work );
1091
1111
1092
1112
ssi -> channel_id_cmd = hsi_get_channel_id_by_name (cl , "mcsaab-control" );
1093
1113
if (ssi -> channel_id_cmd < 0 ) {
0 commit comments