@@ -165,16 +165,27 @@ static bool check_locality(struct tpm_chip *chip, int l)
165165 return false;
166166}
167167
168- static int release_locality (struct tpm_chip * chip , int l )
168+ static int __tpm_tis_relinquish_locality (struct tpm_tis_data * priv , int l )
169+ {
170+ tpm_tis_write8 (priv , TPM_ACCESS (l ), TPM_ACCESS_ACTIVE_LOCALITY );
171+
172+ return 0 ;
173+ }
174+
175+ static int tpm_tis_relinquish_locality (struct tpm_chip * chip , int l )
169176{
170177 struct tpm_tis_data * priv = dev_get_drvdata (& chip -> dev );
171178
172- tpm_tis_write8 (priv , TPM_ACCESS (l ), TPM_ACCESS_ACTIVE_LOCALITY );
179+ mutex_lock (& priv -> locality_count_mutex );
180+ priv -> locality_count -- ;
181+ if (priv -> locality_count == 0 )
182+ __tpm_tis_relinquish_locality (priv , l );
183+ mutex_unlock (& priv -> locality_count_mutex );
173184
174185 return 0 ;
175186}
176187
177- static int request_locality (struct tpm_chip * chip , int l )
188+ static int __tpm_tis_request_locality (struct tpm_chip * chip , int l )
178189{
179190 struct tpm_tis_data * priv = dev_get_drvdata (& chip -> dev );
180191 unsigned long stop , timeout ;
@@ -215,6 +226,20 @@ static int request_locality(struct tpm_chip *chip, int l)
215226 return -1 ;
216227}
217228
229+ static int tpm_tis_request_locality (struct tpm_chip * chip , int l )
230+ {
231+ struct tpm_tis_data * priv = dev_get_drvdata (& chip -> dev );
232+ int ret = 0 ;
233+
234+ mutex_lock (& priv -> locality_count_mutex );
235+ if (priv -> locality_count == 0 )
236+ ret = __tpm_tis_request_locality (chip , l );
237+ if (!ret )
238+ priv -> locality_count ++ ;
239+ mutex_unlock (& priv -> locality_count_mutex );
240+ return ret ;
241+ }
242+
218243static u8 tpm_tis_status (struct tpm_chip * chip )
219244{
220245 struct tpm_tis_data * priv = dev_get_drvdata (& chip -> dev );
@@ -668,7 +693,7 @@ static int probe_itpm(struct tpm_chip *chip)
668693 if (vendor != TPM_VID_INTEL )
669694 return 0 ;
670695
671- if (request_locality (chip , 0 ) != 0 )
696+ if (tpm_tis_request_locality (chip , 0 ) != 0 )
672697 return - EBUSY ;
673698
674699 rc = tpm_tis_send_data (chip , cmd_getticks , len );
@@ -689,7 +714,7 @@ static int probe_itpm(struct tpm_chip *chip)
689714
690715out :
691716 tpm_tis_ready (chip );
692- release_locality (chip , priv -> locality );
717+ tpm_tis_relinquish_locality (chip , priv -> locality );
693718
694719 return rc ;
695720}
@@ -774,14 +799,14 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
774799 }
775800 priv -> irq = irq ;
776801
777- rc = request_locality (chip , 0 );
802+ rc = tpm_tis_request_locality (chip , 0 );
778803 if (rc < 0 )
779804 return rc ;
780805
781806 rc = tpm_tis_read8 (priv , TPM_INT_VECTOR (priv -> locality ),
782807 & original_int_vec );
783808 if (rc < 0 ) {
784- release_locality (chip , priv -> locality );
809+ tpm_tis_relinquish_locality (chip , priv -> locality );
785810 return rc ;
786811 }
787812
@@ -820,7 +845,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
820845 rc = -1 ;
821846 }
822847
823- release_locality (chip , priv -> locality );
848+ tpm_tis_relinquish_locality (chip , priv -> locality );
824849
825850 return rc ;
826851}
@@ -936,8 +961,8 @@ static const struct tpm_class_ops tpm_tis = {
936961 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID ,
937962 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID ,
938963 .req_canceled = tpm_tis_req_canceled ,
939- .request_locality = request_locality ,
940- .relinquish_locality = release_locality ,
964+ .request_locality = tpm_tis_request_locality ,
965+ .relinquish_locality = tpm_tis_relinquish_locality ,
941966 .clk_enable = tpm_tis_clkrun_enable ,
942967};
943968
@@ -971,6 +996,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
971996 priv -> timeout_min = TPM_TIMEOUT_USECS_MIN ;
972997 priv -> timeout_max = TPM_TIMEOUT_USECS_MAX ;
973998 priv -> phy_ops = phy_ops ;
999+ priv -> locality_count = 0 ;
1000+ mutex_init (& priv -> locality_count_mutex );
9741001
9751002 dev_set_drvdata (& chip -> dev , priv );
9761003
@@ -1049,14 +1076,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10491076
10501077 intmask &= ~TPM_GLOBAL_INT_ENABLE ;
10511078
1052- rc = request_locality (chip , 0 );
1079+ rc = tpm_tis_request_locality (chip , 0 );
10531080 if (rc < 0 ) {
10541081 rc = - ENODEV ;
10551082 goto out_err ;
10561083 }
10571084
10581085 tpm_tis_write32 (priv , TPM_INT_ENABLE (priv -> locality ), intmask );
1059- release_locality (chip , 0 );
1086+ tpm_tis_relinquish_locality (chip , 0 );
10601087
10611088 rc = tpm_chip_start (chip );
10621089 if (rc )
@@ -1095,13 +1122,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10951122 * proper timeouts for the driver.
10961123 */
10971124
1098- rc = request_locality (chip , 0 );
1125+ rc = tpm_tis_request_locality (chip , 0 );
10991126 if (rc < 0 )
11001127 goto out_err ;
11011128
11021129 rc = tpm_get_timeouts (chip );
11031130
1104- release_locality (chip , 0 );
1131+ tpm_tis_relinquish_locality (chip , 0 );
11051132
11061133 if (rc ) {
11071134 dev_err (dev , "Could not get TPM timeouts and durations\n" );
@@ -1121,11 +1148,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
11211148 dev_err (& chip -> dev , FW_BUG
11221149 "TPM interrupt not working, polling instead\n" );
11231150
1124- rc = request_locality (chip , 0 );
1151+ rc = tpm_tis_request_locality (chip , 0 );
11251152 if (rc < 0 )
11261153 goto out_err ;
11271154 disable_interrupts (chip );
1128- release_locality (chip , 0 );
1155+ tpm_tis_relinquish_locality (chip , 0 );
11291156 }
11301157 }
11311158
@@ -1192,13 +1219,13 @@ int tpm_tis_resume(struct device *dev)
11921219 * an error code but for unknown reason it isn't handled.
11931220 */
11941221 if (!(chip -> flags & TPM_CHIP_FLAG_TPM2 )) {
1195- ret = request_locality (chip , 0 );
1222+ ret = tpm_tis_request_locality (chip , 0 );
11961223 if (ret < 0 )
11971224 return ret ;
11981225
11991226 tpm1_do_selftest (chip );
12001227
1201- release_locality (chip , 0 );
1228+ tpm_tis_relinquish_locality (chip , 0 );
12021229 }
12031230
12041231 return 0 ;
0 commit comments