@@ -755,17 +755,18 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
755755
756756static irqreturn_t tis_int_handler (int dummy , void * dev_id )
757757{
758+ const unsigned int MAX_UNHANDLED_IRQS = 1000 ;
758759 struct tpm_chip * chip = dev_id ;
759760 struct tpm_tis_data * priv = dev_get_drvdata (& chip -> dev );
760761 u32 interrupt ;
761762 int rc ;
762763
763764 rc = tpm_tis_read32 (priv , TPM_INT_STATUS (priv -> locality ), & interrupt );
764765 if (rc < 0 )
765- return IRQ_NONE ;
766+ goto unhandled ;
766767
767768 if (interrupt == 0 )
768- return IRQ_NONE ;
769+ goto unhandled ;
769770
770771 set_bit (TPM_TIS_IRQ_TESTED , & priv -> flags );
771772 if (interrupt & TPM_INTF_DATA_AVAIL_INT )
@@ -781,10 +782,37 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
781782 rc = tpm_tis_write32 (priv , TPM_INT_STATUS (priv -> locality ), interrupt );
782783 tpm_tis_relinquish_locality (chip , 0 );
783784 if (rc < 0 )
784- return IRQ_NONE ;
785+ goto unhandled ;
785786
786787 tpm_tis_read32 (priv , TPM_INT_STATUS (priv -> locality ), & interrupt );
787788 return IRQ_HANDLED ;
789+
790+ unhandled :
791+ if (time_after (jiffies , priv -> last_unhandled_irq + HZ /10 ))
792+ priv -> unhandled_irqs = 1 ;
793+ else
794+ priv -> unhandled_irqs ++ ;
795+
796+ priv -> last_unhandled_irq = jiffies ;
797+
798+ if ((priv -> unhandled_irqs > MAX_UNHANDLED_IRQS ) &&
799+ (chip -> flags & TPM_CHIP_FLAG_IRQ )) {
800+ int intmask ;
801+
802+ tpm_tis_request_locality (chip , 0 );
803+ rc = tpm_tis_read32 (priv , TPM_INT_ENABLE (priv -> locality ), & intmask );
804+ if (rc < 0 )
805+ intmask = 0 ;
806+
807+ intmask &= ~TPM_GLOBAL_INT_ENABLE ;
808+ rc = tpm_tis_write32 (priv , TPM_INT_ENABLE (priv -> locality ), intmask );
809+ tpm_tis_relinquish_locality (chip , 0 );
810+
811+ chip -> flags &= ~TPM_CHIP_FLAG_IRQ ;
812+
813+ schedule_work (& priv -> free_irq_work );
814+ }
815+ return IRQ_HANDLED ;
788816}
789817
790818static void tpm_tis_gen_interrupt (struct tpm_chip * chip )
@@ -805,6 +833,15 @@ static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
805833 chip -> flags &= ~TPM_CHIP_FLAG_IRQ ;
806834}
807835
836+ static void tpm_tis_free_irq_func (struct work_struct * work )
837+ {
838+ struct tpm_tis_data * priv = container_of (work , typeof (* priv ), free_irq_work );
839+ struct tpm_chip * chip = priv -> chip ;
840+
841+ devm_free_irq (chip -> dev .parent , priv -> irq , chip );
842+ priv -> irq = 0 ;
843+ }
844+
808845/* Register the IRQ and issue a command that will cause an interrupt. If an
809846 * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
810847 * everything and leave in polling mode. Returns 0 on success.
@@ -817,6 +854,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
817854 int rc ;
818855 u32 int_status ;
819856
857+ INIT_WORK (& priv -> free_irq_work , tpm_tis_free_irq_func );
820858
821859 rc = devm_request_threaded_irq (chip -> dev .parent , irq , NULL ,
822860 tis_int_handler , IRQF_ONESHOT | flags ,
@@ -919,6 +957,7 @@ void tpm_tis_remove(struct tpm_chip *chip)
919957 interrupt = 0 ;
920958
921959 tpm_tis_write32 (priv , reg , ~TPM_GLOBAL_INT_ENABLE & interrupt );
960+ flush_work (& priv -> free_irq_work );
922961
923962 tpm_tis_clkrun_enable (chip , false);
924963
@@ -1023,6 +1062,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10231062 chip -> timeout_b = msecs_to_jiffies (TIS_TIMEOUT_B_MAX );
10241063 chip -> timeout_c = msecs_to_jiffies (TIS_TIMEOUT_C_MAX );
10251064 chip -> timeout_d = msecs_to_jiffies (TIS_TIMEOUT_D_MAX );
1065+ priv -> chip = chip ;
10261066 priv -> timeout_min = TPM_TIMEOUT_USECS_MIN ;
10271067 priv -> timeout_max = TPM_TIMEOUT_USECS_MAX ;
10281068 priv -> phy_ops = phy_ops ;
0 commit comments