On Fri, Jun 10, 2022 at 01:08:43PM +0200, LinoSanfilippo@xxxxxx wrote: > From: Lino Sanfilippo <l.sanfilippo@xxxxxxxxxx> > > Implement a usage counter for the (default) locality used by the TPM TIS > driver: > Request the locality from the TPM if it has not been claimed yet, otherwise > only increment the counter. Also release the locality if the counter is 0 > otherwise only decrement the counter. Ensure thread-safety by protecting > the counter with a mutex. > > This allows to request and release the locality from a thread and the > interrupt handler at the same time without the danger to interfere with > each other. > > Signed-off-by: Lino Sanfilippo <l.sanfilippo@xxxxxxxxxx> > --- > drivers/char/tpm/tpm_tis_core.c | 30 ++++++++++++++++++++++++++++-- > drivers/char/tpm/tpm_tis_core.h | 2 ++ > 2 files changed, 30 insertions(+), 2 deletions(-) > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c > index 028bec44362d..0ef74979bc2c 100644 > --- a/drivers/char/tpm/tpm_tis_core.c > +++ b/drivers/char/tpm/tpm_tis_core.c > @@ -158,16 +158,26 @@ static bool check_locality(struct tpm_chip *chip, int l) > return false; > } > > +static int release_locality_locked(struct tpm_tis_data *priv, int l) > +{ > + tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); nit: empty line here Also it would not hurt to prefix it with tpm_tis. This is for simple and practical reasons, like grepping. I don't mind if you do that also for other functions (if you want to). > + return 0; > +} > + > static int release_locality(struct tpm_chip *chip, int l) > { > struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); > > - tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); > + mutex_lock(&priv->locality_count_mutex); > + priv->locality_count--; > + if (priv->locality_count == 0) > + release_locality_locked(priv, l); > + mutex_unlock(&priv->locality_count_mutex); > > return 0; > } > > -static int request_locality(struct tpm_chip *chip, int l) > +static int request_locality_locked(struct tpm_chip *chip, int l) > { > struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); > unsigned long stop, timeout; > @@ -208,6 +218,20 @@ static int request_locality(struct tpm_chip *chip, int l) > return -1; > } > > +static int request_locality(struct tpm_chip *chip, int l) > +{ > + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); > + int ret = 0; > + > + mutex_lock(&priv->locality_count_mutex); > + if (priv->locality_count == 0) > + ret = request_locality_locked(chip, l); > + if (!ret) > + priv->locality_count++; > + mutex_unlock(&priv->locality_count_mutex); > + return ret; > +} > + > static u8 tpm_tis_status(struct tpm_chip *chip) > { > struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); > @@ -987,6 +1011,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, > priv->timeout_min = TPM_TIMEOUT_USECS_MIN; > priv->timeout_max = TPM_TIMEOUT_USECS_MAX; > priv->phy_ops = phy_ops; > + priv->locality_count = 0; > + mutex_init(&priv->locality_count_mutex); > > dev_set_drvdata(&chip->dev, priv); > > diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h > index 8e02faa4079d..e1871c482da2 100644 > --- a/drivers/char/tpm/tpm_tis_core.h > +++ b/drivers/char/tpm/tpm_tis_core.h > @@ -94,6 +94,8 @@ enum tpm_tis_irqtest_flags { > > struct tpm_tis_data { > u16 manufacturer_id; > + struct mutex locality_count_mutex; > + unsigned int locality_count; > int locality; > int irq; > unsigned int irqs_in_use; > -- > 2.36.1 > BR, Jarkko