@@ -53,41 +53,63 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
5353 long rc ;
5454 u8 status ;
5555 bool canceled = false;
56+ u8 sts_mask = 0 ;
57+ int ret = 0 ;
5658
5759 /* check current status */
5860 status = chip -> ops -> status (chip );
5961 if ((status & mask ) == mask )
6062 return 0 ;
6163
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 ;
6367
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 ;
6580again :
6681 timeout = stop - jiffies ;
6782 if ((long )timeout <= 0 )
6883 return - ETIME ;
6984 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 ,
7186 & canceled ),
7287 timeout );
7388 if (rc > 0 ) {
7489 if (canceled )
7590 return - ECANCELED ;
76- return 0 ;
91+ ret = 0 ;
7792 }
7893 if (rc == - ERESTARTSYS && freezing (current )) {
7994 clear_thread_flag (TIF_SIGPENDING );
8095 goto again ;
8196 }
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 ));
9097 }
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 ));
91113 return - ETIME ;
92114}
93115
@@ -1005,8 +1027,40 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10051027 if (rc < 0 )
10061028 goto out_err ;
10071029
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+
10101064 intmask &= ~TPM_GLOBAL_INT_ENABLE ;
10111065
10121066 rc = request_locality (chip , 0 );
@@ -1040,32 +1094,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10401094 goto out_err ;
10411095 }
10421096
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-
10691097 /* INTERRUPT Setup */
10701098 init_waitqueue_head (& priv -> read_queue );
10711099 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,
10961124 else
10971125 tpm_tis_probe_irq (chip , intmask );
10981126
1099- if (!(chip -> flags & TPM_CHIP_FLAG_IRQ )) {
1127+ if (chip -> flags & TPM_CHIP_FLAG_IRQ ) {
1128+ priv -> int_mask = intmask ;
1129+ } else {
11001130 dev_err (& chip -> dev , FW_BUG
11011131 "TPM interrupt not working, polling instead\n" );
11021132
@@ -1143,13 +1173,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
11431173 if (rc < 0 )
11441174 goto out ;
11451175
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 ;
11531177
11541178 tpm_tis_write32 (priv , TPM_INT_ENABLE (priv -> locality ), intmask );
11551179
0 commit comments