On Sun, Jun 26, 2022 at 09:40:43AM +0300, Jarkko Sakkinen wrote: > On Tue, Jun 21, 2022 at 03:24:43PM +0200, Lino Sanfilippo wrote: > > From: Lino Sanfilippo <l.sanfilippo@xxxxxxxxxx> > > > > According to the TPM Interface Specification (TIS) support for "stsValid" > > and "commandReady" interrupts is only optional. > > This has to be taken into account when handling the interrupts in functions > > like wait_for_tpm_stat(). To determine the supported interrupts use the > > capability query. > > > > Also adjust wait_for_tpm_stat() to only wait for interrupt reported status > > changes. After that process all the remaining status changes by polling > > the status register. > > > > Signed-off-by: Lino Sanfilippo <l.sanfilippo@xxxxxxxxxx> > > --- > > drivers/char/tpm/tpm_tis_core.c | 119 +++++++++++++++++++------------- > > drivers/char/tpm/tpm_tis_core.h | 1 + > > 2 files changed, 72 insertions(+), 48 deletions(-) > > > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c > > index 09d8f04cbc81..cb469591373a 100644 > > --- a/drivers/char/tpm/tpm_tis_core.c > > +++ b/drivers/char/tpm/tpm_tis_core.c > > @@ -53,41 +53,63 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, > > long rc; > > u8 status; > > bool canceled = false; > > + u8 sts_mask = 0; > > + int ret = 0; > > > > /* check current status */ > > status = chip->ops->status(chip); > > if ((status & mask) == mask) > > return 0; > > > > - stop = jiffies + timeout; > > + /* check what status changes can be handled by irqs */ > > + if (priv->int_mask & TPM_INTF_STS_VALID_INT) > > + sts_mask |= TPM_STS_VALID; > > > > - if (chip->flags & TPM_CHIP_FLAG_IRQ) { > > + if (priv->int_mask & TPM_INTF_DATA_AVAIL_INT) > > + sts_mask |= TPM_STS_DATA_AVAIL; > > + > > + if (priv->int_mask & TPM_INTF_CMD_READY_INT) > > + sts_mask |= TPM_STS_COMMAND_READY; > > + > > + sts_mask &= mask; > > I would instead mask out bits and write a helper function > taking care of this: > > static u8 tpm_tis_filter_sts_mask(u8 int_mask, u8 sts_mask) > { > struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); Ignore this line (wrote this out of top of my head). > if (!(int_mask & TPM_INTF_STS_VALID_INT)) > sts_mask &= ~TPM_STS_VALID; > > if (!(int_mask & TPM_INTF_DATA_AVAIL_INT)) > sts_mask &= ~TPM_STS_DATA_AVAIL; > > if (!(int_mask & TPM_INTF_CMD_READY_INT)) > sts_mask &= ~TPM_STS_COMMAND_READY; > > return sts_mask; > } > > Less operations and imho somewhat cleaner structure. > > Add suggested-by if you want. > > BR, Jarkko