[tpmdd-devel,5/7] tpm_tis: Get rid of the duplicate IRQ probing code
diff mbox

Message ID 1448485536-7282-6-git-send-email-jgunthorpe@obsidianresearch.com
State New
Headers show

Commit Message

Jason Gunthorpe Nov. 25, 2015, 9:05 p.m. UTC
The new code that works directly in tpm_tis_send is able to handle
IRQ probing duties as well, so just use it for everything.

Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
---
 drivers/char/tpm/tpm.h     |  1 -
 drivers/char/tpm/tpm_tis.c | 67 ++++++++++++++--------------------------------
 2 files changed, 20 insertions(+), 48 deletions(-)

Comments

Jarkko Sakkinen Nov. 30, 2015, 3:50 p.m. UTC | #1
On Wed, Nov 25, 2015 at 02:05:34PM -0700, Jason Gunthorpe wrote:
> The new code that works directly in tpm_tis_send is able to handle
> IRQ probing duties as well, so just use it for everything.

Doesn't this patch implement also new IRQ probing? Couldn't you replace
irq_probing and irq_tested with a variable 'flags' and have an enum?

I'm not a huge fan of boolean variables. They make the code look a mess
and you cannot print them all with a single printk nor you can change
the state with a single assign statement.

> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>

/Jarkko

> ---
>  drivers/char/tpm/tpm.h     |  1 -
>  drivers/char/tpm/tpm_tis.c | 67 ++++++++++++++--------------------------------
>  2 files changed, 20 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index cdd49cd51dc1..542a80cbfd9c 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -142,7 +142,6 @@ struct tpm_vendor_specific {
>  	unsigned long base;		/* TPM base address */
>  
>  	int irq;
> -	int probed_irq;
>  
>  	int region_size;
>  	int have_region;
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index 65a252c7ec5f..2580893de023 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -99,6 +99,7 @@ static struct tpm_info tis_default_info = {
>  #define	TPM_RID(l)			(0x0F04 | ((l) << 12))
>  
>  struct priv_data {
> +	bool irq_probing;
>  	bool irq_tested;
>  };
>  
> @@ -463,8 +464,9 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  		msleep(1);
>  	if (!priv->irq_tested) {
>  		disable_interrupts(chip);
> -		dev_err(chip->pdev,
> -			FW_BUG "TPM interrupt not working, polling instead\n");
> +		if (!priv->irq_probing)
> +			dev_err(chip->pdev, FW_BUG
> +				"TPM interrupt not working, polling instead\n");
>  	}
>  	priv->irq_tested = true;
>  	return rc;
> @@ -570,26 +572,6 @@ static const struct tpm_class_ops tpm_tis = {
>  	.req_canceled = tpm_tis_req_canceled,
>  };
>  
> -static irqreturn_t tis_int_probe(int irq, void *dev_id)
> -{
> -	struct tpm_chip *chip = dev_id;
> -	u32 interrupt;
> -
> -	interrupt = ioread32(chip->vendor.iobase +
> -			     TPM_INT_STATUS(chip->vendor.locality));
> -
> -	if (interrupt == 0)
> -		return IRQ_NONE;
> -
> -	chip->vendor.probed_irq = irq;
> -
> -	/* Clear interrupts handled with TPM_EOI */
> -	iowrite32(interrupt,
> -		  chip->vendor.iobase +
> -		  TPM_INT_STATUS(chip->vendor.locality));
> -	return IRQ_HANDLED;
> -}
> -
>  static irqreturn_t tis_int_handler(int dummy, void *dev_id)
>  {
>  	struct tpm_chip *chip = dev_id;
> @@ -772,13 +754,14 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
>  			iowrite8(i, chip->vendor.iobase +
>  				 TPM_INT_VECTOR(chip->vendor.locality));
>  			if (devm_request_irq
> -			    (dev, i, tis_int_probe, IRQF_SHARED,
> +			    (dev, i, tis_int_handler, IRQF_SHARED,
>  			     chip->devname, chip) != 0) {
>  				dev_info(chip->pdev,
>  					 "Unable to request irq: %d for probe\n",
>  					 i);
>  				continue;
>  			}
> +			chip->vendor.irq = i;
>  
>  			/* Clear all existing */
>  			iowrite32(ioread32
> @@ -792,7 +775,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
>  				  chip->vendor.iobase +
>  				  TPM_INT_ENABLE(chip->vendor.locality));
>  
> -			chip->vendor.probed_irq = 0;
> +			priv->irq_tested = false;
> +			priv->irq_probing = true;
>  
>  			/* Generate Interrupts */
>  			if (chip->flags & TPM_CHIP_FLAG_TPM2)
> @@ -800,29 +784,20 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
>  			else
>  				tpm_gen_interrupt(chip);
>  
> -			if (!chip->vendor.probed_irq)
> -				msleep(1);
> -
> -			chip->vendor.irq = chip->vendor.probed_irq;
> -
> -			/* free_irq will call into tis_int_probe;
> -			   clear all irqs we haven't seen while doing
> -			   tpm_gen_interrupt */
> -			iowrite32(ioread32
> -				  (chip->vendor.iobase +
> -				   TPM_INT_STATUS(chip->vendor.locality)),
> -				  chip->vendor.iobase +
> -				  TPM_INT_STATUS(chip->vendor.locality));
> -
> -			/* Turn off */
> -			iowrite32(intmask,
> -				  chip->vendor.iobase +
> -				  TPM_INT_ENABLE(chip->vendor.locality));
> +			priv->irq_probing = false;
>  
> -			devm_free_irq(dev, i, chip);
> +			/* tpm_tis_send will either confirm the interrupt is
> +			 * working or it will call disable_irq which undoes
> +			 * all of the above.
> +			 */
> +			if (chip->vendor.irq)
> +				break;
>  		}
> +		if (!chip->vendor.irq)
> +			iowrite8(irq_r, chip->vendor.iobase +
> +				 TPM_INT_VECTOR(chip->vendor.locality));
>  	}
> -	if (chip->vendor.irq) {
> +	if (chip->vendor.irq && !priv->irq_tested) {
>  		iowrite8(chip->vendor.irq,
>  			 chip->vendor.iobase +
>  			 TPM_INT_VECTOR(chip->vendor.locality));
> @@ -846,9 +821,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
>  				  chip->vendor.iobase +
>  				  TPM_INT_ENABLE(chip->vendor.locality));
>  		}
> -	} else if (irq_r != -1)
> -		iowrite8(irq_r, chip->vendor.iobase +
> -			 TPM_INT_VECTOR(chip->vendor.locality));
> +	}
>  
>  	if (tpm_get_timeouts(chip)) {
>  		dev_err(dev, "Could not get TPM timeouts and durations\n");
> -- 
> 2.1.4
> 

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
Jason Gunthorpe Nov. 30, 2015, 5:24 p.m. UTC | #2
On Mon, Nov 30, 2015 at 05:50:00PM +0200, Jarkko Sakkinen wrote:
> On Wed, Nov 25, 2015 at 02:05:34PM -0700, Jason Gunthorpe wrote:
> > The new code that works directly in tpm_tis_send is able to handle
> > IRQ probing duties as well, so just use it for everything.
> 
> Doesn't this patch implement also new IRQ probing? Couldn't you replace
> irq_probing and irq_tested with a variable 'flags' and have an enum?

irq_probing is just a temporary thing, it is removed in a later patch
once enough steps have been done to rework the entire flow

> I'm not a huge fan of boolean variables. They make the code look a mess
> and you cannot print them all with a single printk nor you can change
> the state with a single assign statement.

There is no sense to change to a flags for the one boolean.

Jason

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
Jarkko Sakkinen Nov. 30, 2015, 9:12 p.m. UTC | #3
On Mon, Nov 30, 2015 at 10:24:23AM -0700, Jason Gunthorpe wrote:
> On Mon, Nov 30, 2015 at 05:50:00PM +0200, Jarkko Sakkinen wrote:
> > On Wed, Nov 25, 2015 at 02:05:34PM -0700, Jason Gunthorpe wrote:
> > > The new code that works directly in tpm_tis_send is able to handle
> > > IRQ probing duties as well, so just use it for everything.
> > 
> > Doesn't this patch implement also new IRQ probing? Couldn't you replace
> > irq_probing and irq_tested with a variable 'flags' and have an enum?
> 
> irq_probing is just a temporary thing, it is removed in a later patch
> once enough steps have been done to rework the entire flow
> 
> > I'm not a huge fan of boolean variables. They make the code look a mess
> > and you cannot print them all with a single printk nor you can change
> > the state with a single assign statement.
> 
> There is no sense to change to a flags for the one boolean.

It makes the code easier to follow when you don't have to backtrace what
some true/false parameter meant (i.e. self-documenting). I'll create a
patch to top of these series. It's a separate clean up.

/Jarkko

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
Jarkko Sakkinen Nov. 30, 2015, 9:16 p.m. UTC | #4
On Mon, Nov 30, 2015 at 11:12:00PM +0200, Jarkko Sakkinen wrote:
> On Mon, Nov 30, 2015 at 10:24:23AM -0700, Jason Gunthorpe wrote:
> > On Mon, Nov 30, 2015 at 05:50:00PM +0200, Jarkko Sakkinen wrote:
> > > On Wed, Nov 25, 2015 at 02:05:34PM -0700, Jason Gunthorpe wrote:
> > > > The new code that works directly in tpm_tis_send is able to handle
> > > > IRQ probing duties as well, so just use it for everything.
> > > 
> > > Doesn't this patch implement also new IRQ probing? Couldn't you replace
> > > irq_probing and irq_tested with a variable 'flags' and have an enum?
> > 
> > irq_probing is just a temporary thing, it is removed in a later patch
> > once enough steps have been done to rework the entire flow
> > 
> > > I'm not a huge fan of boolean variables. They make the code look a mess
> > > and you cannot print them all with a single printk nor you can change
> > > the state with a single assign statement.
> > 
> > There is no sense to change to a flags for the one boolean.
> 
> It makes the code easier to follow when you don't have to backtrace what
> some true/false parameter meant (i.e. self-documenting). I'll create a
> patch to top of these series. It's a separate clean up.

Actually no. I'll create it post-v4.5. It's something I saw that makes
sense but there are already so many high priority patches that it's better
to postpone it.

/Jarkko

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140

Patch
diff mbox

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index cdd49cd51dc1..542a80cbfd9c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -142,7 +142,6 @@  struct tpm_vendor_specific {
 	unsigned long base;		/* TPM base address */
 
 	int irq;
-	int probed_irq;
 
 	int region_size;
 	int have_region;
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 65a252c7ec5f..2580893de023 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -99,6 +99,7 @@  static struct tpm_info tis_default_info = {
 #define	TPM_RID(l)			(0x0F04 | ((l) << 12))
 
 struct priv_data {
+	bool irq_probing;
 	bool irq_tested;
 };
 
@@ -463,8 +464,9 @@  static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
 		msleep(1);
 	if (!priv->irq_tested) {
 		disable_interrupts(chip);
-		dev_err(chip->pdev,
-			FW_BUG "TPM interrupt not working, polling instead\n");
+		if (!priv->irq_probing)
+			dev_err(chip->pdev, FW_BUG
+				"TPM interrupt not working, polling instead\n");
 	}
 	priv->irq_tested = true;
 	return rc;
@@ -570,26 +572,6 @@  static const struct tpm_class_ops tpm_tis = {
 	.req_canceled = tpm_tis_req_canceled,
 };
 
-static irqreturn_t tis_int_probe(int irq, void *dev_id)
-{
-	struct tpm_chip *chip = dev_id;
-	u32 interrupt;
-
-	interrupt = ioread32(chip->vendor.iobase +
-			     TPM_INT_STATUS(chip->vendor.locality));
-
-	if (interrupt == 0)
-		return IRQ_NONE;
-
-	chip->vendor.probed_irq = irq;
-
-	/* Clear interrupts handled with TPM_EOI */
-	iowrite32(interrupt,
-		  chip->vendor.iobase +
-		  TPM_INT_STATUS(chip->vendor.locality));
-	return IRQ_HANDLED;
-}
-
 static irqreturn_t tis_int_handler(int dummy, void *dev_id)
 {
 	struct tpm_chip *chip = dev_id;
@@ -772,13 +754,14 @@  static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 			iowrite8(i, chip->vendor.iobase +
 				 TPM_INT_VECTOR(chip->vendor.locality));
 			if (devm_request_irq
-			    (dev, i, tis_int_probe, IRQF_SHARED,
+			    (dev, i, tis_int_handler, IRQF_SHARED,
 			     chip->devname, chip) != 0) {
 				dev_info(chip->pdev,
 					 "Unable to request irq: %d for probe\n",
 					 i);
 				continue;
 			}
+			chip->vendor.irq = i;
 
 			/* Clear all existing */
 			iowrite32(ioread32
@@ -792,7 +775,8 @@  static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 				  chip->vendor.iobase +
 				  TPM_INT_ENABLE(chip->vendor.locality));
 
-			chip->vendor.probed_irq = 0;
+			priv->irq_tested = false;
+			priv->irq_probing = true;
 
 			/* Generate Interrupts */
 			if (chip->flags & TPM_CHIP_FLAG_TPM2)
@@ -800,29 +784,20 @@  static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 			else
 				tpm_gen_interrupt(chip);
 
-			if (!chip->vendor.probed_irq)
-				msleep(1);
-
-			chip->vendor.irq = chip->vendor.probed_irq;
-
-			/* free_irq will call into tis_int_probe;
-			   clear all irqs we haven't seen while doing
-			   tpm_gen_interrupt */
-			iowrite32(ioread32
-				  (chip->vendor.iobase +
-				   TPM_INT_STATUS(chip->vendor.locality)),
-				  chip->vendor.iobase +
-				  TPM_INT_STATUS(chip->vendor.locality));
-
-			/* Turn off */
-			iowrite32(intmask,
-				  chip->vendor.iobase +
-				  TPM_INT_ENABLE(chip->vendor.locality));
+			priv->irq_probing = false;
 
-			devm_free_irq(dev, i, chip);
+			/* tpm_tis_send will either confirm the interrupt is
+			 * working or it will call disable_irq which undoes
+			 * all of the above.
+			 */
+			if (chip->vendor.irq)
+				break;
 		}
+		if (!chip->vendor.irq)
+			iowrite8(irq_r, chip->vendor.iobase +
+				 TPM_INT_VECTOR(chip->vendor.locality));
 	}
-	if (chip->vendor.irq) {
+	if (chip->vendor.irq && !priv->irq_tested) {
 		iowrite8(chip->vendor.irq,
 			 chip->vendor.iobase +
 			 TPM_INT_VECTOR(chip->vendor.locality));
@@ -846,9 +821,7 @@  static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 				  chip->vendor.iobase +
 				  TPM_INT_ENABLE(chip->vendor.locality));
 		}
-	} else if (irq_r != -1)
-		iowrite8(irq_r, chip->vendor.iobase +
-			 TPM_INT_VECTOR(chip->vendor.locality));
+	}
 
 	if (tpm_get_timeouts(chip)) {
 		dev_err(dev, "Could not get TPM timeouts and durations\n");