@@ -53,41 +53,63 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
53
53
long rc ;
54
54
u8 status ;
55
55
bool canceled = false;
56
+ u8 sts_mask = 0 ;
57
+ int ret = 0 ;
56
58
57
59
/* check current status */
58
60
status = chip -> ops -> status (chip );
59
61
if ((status & mask ) == mask )
60
62
return 0 ;
61
63
62
- stop = jiffies + timeout ;
64
+ /* check what status changes can be handled by irqs */
65
+ if (priv -> int_mask & TPM_INTF_STS_VALID_INT )
66
+ sts_mask |= TPM_STS_VALID ;
63
67
64
- if (chip -> flags & TPM_CHIP_FLAG_IRQ ) {
68
+ if (priv -> int_mask & TPM_INTF_DATA_AVAIL_INT )
69
+ sts_mask |= TPM_STS_DATA_AVAIL ;
70
+
71
+ if (priv -> int_mask & TPM_INTF_CMD_READY_INT )
72
+ sts_mask |= TPM_STS_COMMAND_READY ;
73
+
74
+ sts_mask &= mask ;
75
+
76
+ stop = jiffies + timeout ;
77
+ /* process status changes with irq support */
78
+ if (sts_mask ) {
79
+ ret = - ETIME ;
65
80
again :
66
81
timeout = stop - jiffies ;
67
82
if ((long )timeout <= 0 )
68
83
return - ETIME ;
69
84
rc = wait_event_interruptible_timeout (* queue ,
70
- wait_for_tpm_stat_cond (chip , mask , check_cancel ,
85
+ wait_for_tpm_stat_cond (chip , sts_mask , check_cancel ,
71
86
& canceled ),
72
87
timeout );
73
88
if (rc > 0 ) {
74
89
if (canceled )
75
90
return - ECANCELED ;
76
- return 0 ;
91
+ ret = 0 ;
77
92
}
78
93
if (rc == - ERESTARTSYS && freezing (current )) {
79
94
clear_thread_flag (TIF_SIGPENDING );
80
95
goto again ;
81
96
}
82
- } else {
83
- do {
84
- usleep_range (priv -> timeout_min ,
85
- priv -> timeout_max );
86
- status = chip -> ops -> status (chip );
87
- if ((status & mask ) == mask )
88
- return 0 ;
89
- } while (time_before (jiffies , stop ));
90
97
}
98
+
99
+ if (ret )
100
+ return ret ;
101
+
102
+ mask &= ~sts_mask ;
103
+ if (!mask ) /* all done */
104
+ return 0 ;
105
+ /* process status changes without irq support */
106
+ do {
107
+ status = chip -> ops -> status (chip );
108
+ if ((status & mask ) == mask )
109
+ return 0 ;
110
+ usleep_range (priv -> timeout_min ,
111
+ priv -> timeout_max );
112
+ } while (time_before (jiffies , stop ));
91
113
return - ETIME ;
92
114
}
93
115
@@ -1005,8 +1027,40 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
1005
1027
if (rc < 0 )
1006
1028
goto out_err ;
1007
1029
1008
- intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
1009
- TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT ;
1030
+ /* Figure out the capabilities */
1031
+ rc = tpm_tis_read32 (priv , TPM_INTF_CAPS (priv -> locality ), & intfcaps );
1032
+ if (rc < 0 )
1033
+ goto out_err ;
1034
+
1035
+ dev_dbg (dev , "TPM interface capabilities (0x%x):\n" ,
1036
+ intfcaps );
1037
+ if (intfcaps & TPM_INTF_BURST_COUNT_STATIC )
1038
+ dev_dbg (dev , "\tBurst Count Static\n" );
1039
+ if (intfcaps & TPM_INTF_CMD_READY_INT ) {
1040
+ intmask |= TPM_INTF_CMD_READY_INT ;
1041
+ dev_dbg (dev , "\tCommand Ready Int Support\n" );
1042
+ }
1043
+ if (intfcaps & TPM_INTF_INT_EDGE_FALLING )
1044
+ dev_dbg (dev , "\tInterrupt Edge Falling\n" );
1045
+ if (intfcaps & TPM_INTF_INT_EDGE_RISING )
1046
+ dev_dbg (dev , "\tInterrupt Edge Rising\n" );
1047
+ if (intfcaps & TPM_INTF_INT_LEVEL_LOW )
1048
+ dev_dbg (dev , "\tInterrupt Level Low\n" );
1049
+ if (intfcaps & TPM_INTF_INT_LEVEL_HIGH )
1050
+ dev_dbg (dev , "\tInterrupt Level High\n" );
1051
+ if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT ) {
1052
+ intmask |= TPM_INTF_LOCALITY_CHANGE_INT ;
1053
+ dev_dbg (dev , "\tLocality Change Int Support\n" );
1054
+ }
1055
+ if (intfcaps & TPM_INTF_STS_VALID_INT ) {
1056
+ intmask |= TPM_INTF_STS_VALID_INT ;
1057
+ dev_dbg (dev , "\tSts Valid Int Support\n" );
1058
+ }
1059
+ if (intfcaps & TPM_INTF_DATA_AVAIL_INT ) {
1060
+ intmask |= TPM_INTF_DATA_AVAIL_INT ;
1061
+ dev_dbg (dev , "\tData Avail Int Support\n" );
1062
+ }
1063
+
1010
1064
intmask &= ~TPM_GLOBAL_INT_ENABLE ;
1011
1065
1012
1066
rc = request_locality (chip , 0 );
@@ -1040,32 +1094,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
1040
1094
goto out_err ;
1041
1095
}
1042
1096
1043
- /* Figure out the capabilities */
1044
- rc = tpm_tis_read32 (priv , TPM_INTF_CAPS (priv -> locality ), & intfcaps );
1045
- if (rc < 0 )
1046
- goto out_err ;
1047
-
1048
- dev_dbg (dev , "TPM interface capabilities (0x%x):\n" ,
1049
- intfcaps );
1050
- if (intfcaps & TPM_INTF_BURST_COUNT_STATIC )
1051
- dev_dbg (dev , "\tBurst Count Static\n" );
1052
- if (intfcaps & TPM_INTF_CMD_READY_INT )
1053
- dev_dbg (dev , "\tCommand Ready Int Support\n" );
1054
- if (intfcaps & TPM_INTF_INT_EDGE_FALLING )
1055
- dev_dbg (dev , "\tInterrupt Edge Falling\n" );
1056
- if (intfcaps & TPM_INTF_INT_EDGE_RISING )
1057
- dev_dbg (dev , "\tInterrupt Edge Rising\n" );
1058
- if (intfcaps & TPM_INTF_INT_LEVEL_LOW )
1059
- dev_dbg (dev , "\tInterrupt Level Low\n" );
1060
- if (intfcaps & TPM_INTF_INT_LEVEL_HIGH )
1061
- dev_dbg (dev , "\tInterrupt Level High\n" );
1062
- if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT )
1063
- dev_dbg (dev , "\tLocality Change Int Support\n" );
1064
- if (intfcaps & TPM_INTF_STS_VALID_INT )
1065
- dev_dbg (dev , "\tSts Valid Int Support\n" );
1066
- if (intfcaps & TPM_INTF_DATA_AVAIL_INT )
1067
- dev_dbg (dev , "\tData Avail Int Support\n" );
1068
-
1069
1097
/* INTERRUPT Setup */
1070
1098
init_waitqueue_head (& priv -> read_queue );
1071
1099
init_waitqueue_head (& priv -> int_queue );
@@ -1096,7 +1124,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
1096
1124
else
1097
1125
tpm_tis_probe_irq (chip , intmask );
1098
1126
1099
- if (!(chip -> flags & TPM_CHIP_FLAG_IRQ )) {
1127
+ if (chip -> flags & TPM_CHIP_FLAG_IRQ ) {
1128
+ priv -> int_mask = intmask ;
1129
+ } else {
1100
1130
dev_err (& chip -> dev , FW_BUG
1101
1131
"TPM interrupt not working, polling instead\n" );
1102
1132
@@ -1143,13 +1173,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
1143
1173
if (rc < 0 )
1144
1174
goto out ;
1145
1175
1146
- rc = tpm_tis_read32 (priv , TPM_INT_ENABLE (priv -> locality ), & intmask );
1147
- if (rc < 0 )
1148
- goto out ;
1149
-
1150
- intmask |= TPM_INTF_CMD_READY_INT
1151
- | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
1152
- | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE ;
1176
+ intmask = priv -> int_mask | TPM_GLOBAL_INT_ENABLE ;
1153
1177
1154
1178
tpm_tis_write32 (priv , TPM_INT_ENABLE (priv -> locality ), intmask );
1155
1179
0 commit comments