All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jarkko Sakkinen <jarkko@kernel.org>
To: "Rob Herring (Arm)" <robh@kernel.org>,
	Peter Huewe <peterhuewe@gmx.de>,  Jason Gunthorpe <jgg@ziepe.ca>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Nicholas Piggin <npiggin@gmail.com>,
	Christophe Leroy <christophe.leroy@csgroup.eu>,
	"Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org,
	 linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH] tpm: atmel: Drop PPC64 specific MMIO setup
Date: Wed, 03 Jul 2024 02:52:02 +0300	[thread overview]
Message-ID: <e72dba1639fd6b68bb2fd392910ac8a61b99d65d.camel@kernel.org> (raw)
In-Reply-To: <20240702161052.3563599-1-robh@kernel.org>

On Tue, 2024-07-02 at 10:10 -0600, Rob Herring (Arm) wrote:
> The PPC64 specific MMIO setup open codes DT address functions rather
> than using standard address parsing functions. The open-coded version
> fails to handle any address translation and is not endian safe.
> 
> I haven't found any evidence of what platform used this. The only thing
> that turned up was a PPC405 platform, but that is 32-bit and PPC405
> support is being removed as well. CONFIG_TCG_ATMEL is not enabled for
> any powerpc config and never was. The support was added in 2005 and
> hasn't been touched since.
> 
> Rather than try to modernize and fix this code, just remove it.
> 
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
>  drivers/char/tpm/Kconfig     |   2 +-
>  drivers/char/tpm/tpm_atmel.c |  64 +++++++++++++++-
>  drivers/char/tpm/tpm_atmel.h | 140 -----------------------------------
>  3 files changed, 62 insertions(+), 144 deletions(-)
>  delete mode 100644 drivers/char/tpm/tpm_atmel.h
> 
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index e63a6a17793c..9b655e9fc7ab 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -162,7 +162,7 @@ config TCG_NSC
>  
>  config TCG_ATMEL
>  	tristate "Atmel TPM Interface"
> -	depends on PPC64 || HAS_IOPORT_MAP
> +	depends on HAS_IOPORT_MAP
>  	depends on HAS_IOPORT
>  	help
>  	  If you have a TPM security chip from Atmel say Yes and it 
> diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
> index 9fb2defa9dc4..622c4abe8cb3 100644
> --- a/drivers/char/tpm/tpm_atmel.c
> +++ b/drivers/char/tpm/tpm_atmel.c
> @@ -15,7 +15,67 @@
>   */
>  
>  #include "tpm.h"
> -#include "tpm_atmel.h"
> +
> +struct tpm_atmel_priv {
> +	int region_size;
> +	int have_region;
> +	unsigned long base;
> +	void __iomem *iobase;
> +};
> +
> +#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
> +#define atmel_putb(val, chip, offset) \
> +	outb(val, atmel_get_priv(chip)->base + offset)
> +#define atmel_request_region request_region
> +#define atmel_release_region release_region
> +/* Atmel definitions */
> +enum tpm_atmel_addr {
> +	TPM_ATMEL_BASE_ADDR_LO = 0x08,
> +	TPM_ATMEL_BASE_ADDR_HI = 0x09
> +};
> +
> +static inline int tpm_read_index(int base, int index)
> +{
> +	outb(index, base);
> +	return inb(base+1) & 0xFF;
> +}
> +
> +/* Verify this is a 1.1 Atmel TPM */
> +static int atmel_verify_tpm11(void)
> +{
> +
> +	/* verify that it is an Atmel part */
> +	if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
> +	    tpm_read_index(TPM_ADDR, 5) != 'T' ||
> +	    tpm_read_index(TPM_ADDR, 6) != 'M' ||
> +	    tpm_read_index(TPM_ADDR, 7) != 'L')
> +		return 1;
> +
> +	/* query chip for its version number */
> +	if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
> +	    tpm_read_index(TPM_ADDR, 0x01) != 1)
> +		return 1;
> +
> +	/* This is an atmel supported part */
> +	return 0;
> +}
> +
> +/* Determine where to talk to device */
> +static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
> +{
> +	int lo, hi;
> +
> +	if (atmel_verify_tpm11() != 0)
> +		return NULL;
> +
> +	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
> +	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
> +
> +	*base = (hi << 8) | lo;
> +	*region_size = 2;
> +
> +	return ioport_map(*base, *region_size);
> +}
>  
>  /* write status bits */
>  enum tpm_atmel_write_status {
> @@ -142,7 +202,6 @@ static void atml_plat_remove(void)
>  	tpm_chip_unregister(chip);
>  	if (priv->have_region)
>  		atmel_release_region(priv->base, priv->region_size);
> -	atmel_put_base_addr(priv->iobase);
>  	platform_device_unregister(pdev);
>  }
>  
> @@ -211,7 +270,6 @@ static int __init init_atmel(void)
>  err_unreg_dev:
>  	platform_device_unregister(pdev);
>  err_rel_reg:
> -	atmel_put_base_addr(iobase);
>  	if (have_region)
>  		atmel_release_region(base,
>  				     region_size);
> diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
> deleted file mode 100644
> index 7ac3f69dcf0f..000000000000
> --- a/drivers/char/tpm/tpm_atmel.h
> +++ /dev/null
> @@ -1,140 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2005 IBM Corporation
> - *
> - * Authors:
> - * Kylene Hall <kjhall@us.ibm.com>
> - *
> - * Maintained by: <tpmdd-devel@lists.sourceforge.net>
> - *
> - * Device driver for TCG/TCPA TPM (trusted platform module).
> - * Specifications at www.trustedcomputinggroup.org
> - *
> - * These difference are required on power because the device must be
> - * discovered through the device tree and iomap must be used to get
> - * around the need for holes in the io_page_mask.  This does not happen
> - * automatically because the tpm is not a normal pci device and lives
> - * under the root node.
> - */
> -
> -struct tpm_atmel_priv {
> -	int region_size;
> -	int have_region;
> -	unsigned long base;
> -	void __iomem *iobase;
> -};
> -
> -#ifdef CONFIG_PPC64
> -
> -#include <linux/of.h>
> -
> -#define atmel_getb(priv, offset) readb(priv->iobase + offset)
> -#define atmel_putb(val, priv, offset) writeb(val, priv->iobase + offset)
> -#define atmel_request_region request_mem_region
> -#define atmel_release_region release_mem_region
> -
> -static inline void atmel_put_base_addr(void __iomem *iobase)
> -{
> -	iounmap(iobase);
> -}
> -
> -static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
> -{
> -	struct device_node *dn;
> -	unsigned long address, size;
> -	const unsigned int *reg;
> -	int reglen;
> -	int naddrc;
> -	int nsizec;
> -
> -	dn = of_find_node_by_name(NULL, "tpm");
> -
> -	if (!dn)
> -		return NULL;
> -
> -	if (!of_device_is_compatible(dn, "AT97SC3201")) {
> -		of_node_put(dn);
> -		return NULL;
> -	}
> -
> -	reg = of_get_property(dn, "reg", &reglen);
> -	naddrc = of_n_addr_cells(dn);
> -	nsizec = of_n_size_cells(dn);
> -
> -	of_node_put(dn);
> -
> -
> -	if (naddrc == 2)
> -		address = ((unsigned long) reg[0] << 32) | reg[1];
> -	else
> -		address = reg[0];
> -
> -	if (nsizec == 2)
> -		size =
> -		    ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
> -	else
> -		size = reg[naddrc];
> -
> -	*base = address;
> -	*region_size = size;
> -	return ioremap(*base, *region_size);
> -}
> -#else
> -#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
> -#define atmel_putb(val, chip, offset) \
> -	outb(val, atmel_get_priv(chip)->base + offset)
> -#define atmel_request_region request_region
> -#define atmel_release_region release_region
> -/* Atmel definitions */
> -enum tpm_atmel_addr {
> -	TPM_ATMEL_BASE_ADDR_LO = 0x08,
> -	TPM_ATMEL_BASE_ADDR_HI = 0x09
> -};
> -
> -static inline int tpm_read_index(int base, int index)
> -{
> -	outb(index, base);
> -	return inb(base+1) & 0xFF;
> -}
> -
> -/* Verify this is a 1.1 Atmel TPM */
> -static int atmel_verify_tpm11(void)
> -{
> -
> -	/* verify that it is an Atmel part */
> -	if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
> -	    tpm_read_index(TPM_ADDR, 5) != 'T' ||
> -	    tpm_read_index(TPM_ADDR, 6) != 'M' ||
> -	    tpm_read_index(TPM_ADDR, 7) != 'L')
> -		return 1;
> -
> -	/* query chip for its version number */
> -	if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
> -	    tpm_read_index(TPM_ADDR, 0x01) != 1)
> -		return 1;
> -
> -	/* This is an atmel supported part */
> -	return 0;
> -}
> -
> -static inline void atmel_put_base_addr(void __iomem *iobase)
> -{
> -}
> -
> -/* Determine where to talk to device */
> -static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
> -{
> -	int lo, hi;
> -
> -	if (atmel_verify_tpm11() != 0)
> -		return NULL;
> -
> -	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
> -	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
> -
> -	*base = (hi << 8) | lo;
> -	*region_size = 2;
> -
> -	return ioport_map(*base, *region_size);
> -}
> -#endif


Acknowledging that I noticed this but won't test
before week 31, when I'm back from holiday.

BR, Jarkko


WARNING: multiple messages have this Message-ID (diff)
From: Jarkko Sakkinen <jarkko@kernel.org>
To: "Rob Herring (Arm)" <robh@kernel.org>,
	Peter Huewe <peterhuewe@gmx.de>,  Jason Gunthorpe <jgg@ziepe.ca>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Nicholas Piggin <npiggin@gmail.com>,
	Christophe Leroy <christophe.leroy@csgroup.eu>,
	"Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
Cc: linux-integrity@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] tpm: atmel: Drop PPC64 specific MMIO setup
Date: Wed, 03 Jul 2024 02:52:02 +0300	[thread overview]
Message-ID: <e72dba1639fd6b68bb2fd392910ac8a61b99d65d.camel@kernel.org> (raw)
In-Reply-To: <20240702161052.3563599-1-robh@kernel.org>

On Tue, 2024-07-02 at 10:10 -0600, Rob Herring (Arm) wrote:
> The PPC64 specific MMIO setup open codes DT address functions rather
> than using standard address parsing functions. The open-coded version
> fails to handle any address translation and is not endian safe.
> 
> I haven't found any evidence of what platform used this. The only thing
> that turned up was a PPC405 platform, but that is 32-bit and PPC405
> support is being removed as well. CONFIG_TCG_ATMEL is not enabled for
> any powerpc config and never was. The support was added in 2005 and
> hasn't been touched since.
> 
> Rather than try to modernize and fix this code, just remove it.
> 
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
>  drivers/char/tpm/Kconfig     |   2 +-
>  drivers/char/tpm/tpm_atmel.c |  64 +++++++++++++++-
>  drivers/char/tpm/tpm_atmel.h | 140 -----------------------------------
>  3 files changed, 62 insertions(+), 144 deletions(-)
>  delete mode 100644 drivers/char/tpm/tpm_atmel.h
> 
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index e63a6a17793c..9b655e9fc7ab 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -162,7 +162,7 @@ config TCG_NSC
>  
>  config TCG_ATMEL
>  	tristate "Atmel TPM Interface"
> -	depends on PPC64 || HAS_IOPORT_MAP
> +	depends on HAS_IOPORT_MAP
>  	depends on HAS_IOPORT
>  	help
>  	  If you have a TPM security chip from Atmel say Yes and it 
> diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
> index 9fb2defa9dc4..622c4abe8cb3 100644
> --- a/drivers/char/tpm/tpm_atmel.c
> +++ b/drivers/char/tpm/tpm_atmel.c
> @@ -15,7 +15,67 @@
>   */
>  
>  #include "tpm.h"
> -#include "tpm_atmel.h"
> +
> +struct tpm_atmel_priv {
> +	int region_size;
> +	int have_region;
> +	unsigned long base;
> +	void __iomem *iobase;
> +};
> +
> +#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
> +#define atmel_putb(val, chip, offset) \
> +	outb(val, atmel_get_priv(chip)->base + offset)
> +#define atmel_request_region request_region
> +#define atmel_release_region release_region
> +/* Atmel definitions */
> +enum tpm_atmel_addr {
> +	TPM_ATMEL_BASE_ADDR_LO = 0x08,
> +	TPM_ATMEL_BASE_ADDR_HI = 0x09
> +};
> +
> +static inline int tpm_read_index(int base, int index)
> +{
> +	outb(index, base);
> +	return inb(base+1) & 0xFF;
> +}
> +
> +/* Verify this is a 1.1 Atmel TPM */
> +static int atmel_verify_tpm11(void)
> +{
> +
> +	/* verify that it is an Atmel part */
> +	if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
> +	    tpm_read_index(TPM_ADDR, 5) != 'T' ||
> +	    tpm_read_index(TPM_ADDR, 6) != 'M' ||
> +	    tpm_read_index(TPM_ADDR, 7) != 'L')
> +		return 1;
> +
> +	/* query chip for its version number */
> +	if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
> +	    tpm_read_index(TPM_ADDR, 0x01) != 1)
> +		return 1;
> +
> +	/* This is an atmel supported part */
> +	return 0;
> +}
> +
> +/* Determine where to talk to device */
> +static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
> +{
> +	int lo, hi;
> +
> +	if (atmel_verify_tpm11() != 0)
> +		return NULL;
> +
> +	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
> +	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
> +
> +	*base = (hi << 8) | lo;
> +	*region_size = 2;
> +
> +	return ioport_map(*base, *region_size);
> +}
>  
>  /* write status bits */
>  enum tpm_atmel_write_status {
> @@ -142,7 +202,6 @@ static void atml_plat_remove(void)
>  	tpm_chip_unregister(chip);
>  	if (priv->have_region)
>  		atmel_release_region(priv->base, priv->region_size);
> -	atmel_put_base_addr(priv->iobase);
>  	platform_device_unregister(pdev);
>  }
>  
> @@ -211,7 +270,6 @@ static int __init init_atmel(void)
>  err_unreg_dev:
>  	platform_device_unregister(pdev);
>  err_rel_reg:
> -	atmel_put_base_addr(iobase);
>  	if (have_region)
>  		atmel_release_region(base,
>  				     region_size);
> diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
> deleted file mode 100644
> index 7ac3f69dcf0f..000000000000
> --- a/drivers/char/tpm/tpm_atmel.h
> +++ /dev/null
> @@ -1,140 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) 2005 IBM Corporation
> - *
> - * Authors:
> - * Kylene Hall <kjhall@us.ibm.com>
> - *
> - * Maintained by: <tpmdd-devel@lists.sourceforge.net>
> - *
> - * Device driver for TCG/TCPA TPM (trusted platform module).
> - * Specifications at www.trustedcomputinggroup.org
> - *
> - * These difference are required on power because the device must be
> - * discovered through the device tree and iomap must be used to get
> - * around the need for holes in the io_page_mask.  This does not happen
> - * automatically because the tpm is not a normal pci device and lives
> - * under the root node.
> - */
> -
> -struct tpm_atmel_priv {
> -	int region_size;
> -	int have_region;
> -	unsigned long base;
> -	void __iomem *iobase;
> -};
> -
> -#ifdef CONFIG_PPC64
> -
> -#include <linux/of.h>
> -
> -#define atmel_getb(priv, offset) readb(priv->iobase + offset)
> -#define atmel_putb(val, priv, offset) writeb(val, priv->iobase + offset)
> -#define atmel_request_region request_mem_region
> -#define atmel_release_region release_mem_region
> -
> -static inline void atmel_put_base_addr(void __iomem *iobase)
> -{
> -	iounmap(iobase);
> -}
> -
> -static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
> -{
> -	struct device_node *dn;
> -	unsigned long address, size;
> -	const unsigned int *reg;
> -	int reglen;
> -	int naddrc;
> -	int nsizec;
> -
> -	dn = of_find_node_by_name(NULL, "tpm");
> -
> -	if (!dn)
> -		return NULL;
> -
> -	if (!of_device_is_compatible(dn, "AT97SC3201")) {
> -		of_node_put(dn);
> -		return NULL;
> -	}
> -
> -	reg = of_get_property(dn, "reg", &reglen);
> -	naddrc = of_n_addr_cells(dn);
> -	nsizec = of_n_size_cells(dn);
> -
> -	of_node_put(dn);
> -
> -
> -	if (naddrc == 2)
> -		address = ((unsigned long) reg[0] << 32) | reg[1];
> -	else
> -		address = reg[0];
> -
> -	if (nsizec == 2)
> -		size =
> -		    ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
> -	else
> -		size = reg[naddrc];
> -
> -	*base = address;
> -	*region_size = size;
> -	return ioremap(*base, *region_size);
> -}
> -#else
> -#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
> -#define atmel_putb(val, chip, offset) \
> -	outb(val, atmel_get_priv(chip)->base + offset)
> -#define atmel_request_region request_region
> -#define atmel_release_region release_region
> -/* Atmel definitions */
> -enum tpm_atmel_addr {
> -	TPM_ATMEL_BASE_ADDR_LO = 0x08,
> -	TPM_ATMEL_BASE_ADDR_HI = 0x09
> -};
> -
> -static inline int tpm_read_index(int base, int index)
> -{
> -	outb(index, base);
> -	return inb(base+1) & 0xFF;
> -}
> -
> -/* Verify this is a 1.1 Atmel TPM */
> -static int atmel_verify_tpm11(void)
> -{
> -
> -	/* verify that it is an Atmel part */
> -	if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
> -	    tpm_read_index(TPM_ADDR, 5) != 'T' ||
> -	    tpm_read_index(TPM_ADDR, 6) != 'M' ||
> -	    tpm_read_index(TPM_ADDR, 7) != 'L')
> -		return 1;
> -
> -	/* query chip for its version number */
> -	if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
> -	    tpm_read_index(TPM_ADDR, 0x01) != 1)
> -		return 1;
> -
> -	/* This is an atmel supported part */
> -	return 0;
> -}
> -
> -static inline void atmel_put_base_addr(void __iomem *iobase)
> -{
> -}
> -
> -/* Determine where to talk to device */
> -static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
> -{
> -	int lo, hi;
> -
> -	if (atmel_verify_tpm11() != 0)
> -		return NULL;
> -
> -	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
> -	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
> -
> -	*base = (hi << 8) | lo;
> -	*region_size = 2;
> -
> -	return ioport_map(*base, *region_size);
> -}
> -#endif


Acknowledging that I noticed this but won't test
before week 31, when I'm back from holiday.

BR, Jarkko


  reply	other threads:[~2024-07-02 23:52 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-02 16:10 [PATCH] tpm: atmel: Drop PPC64 specific MMIO setup Rob Herring (Arm)
2024-07-02 16:10 ` Rob Herring (Arm)
2024-07-02 23:52 ` Jarkko Sakkinen [this message]
2024-07-02 23:52   ` Jarkko Sakkinen
2024-07-03 12:14 ` Michael Ellerman
2024-07-03 12:14   ` Michael Ellerman
2024-07-17 12:08 ` Jarkko Sakkinen
2024-07-17 12:08   ` Jarkko Sakkinen
2024-07-17 12:13   ` Jarkko Sakkinen
2024-07-17 12:13     ` Jarkko Sakkinen
2024-07-18 14:57     ` Rob Herring
2024-07-18 14:57       ` Rob Herring
2024-07-18 16:01       ` Jarkko Sakkinen
2024-07-18 16:01         ` Jarkko Sakkinen
2024-11-06 14:50         ` Rob Herring
2024-11-06 18:17           ` Jarkko Sakkinen
2024-11-06 18:19             ` Jarkko Sakkinen
2024-11-06 18:32               ` Rob Herring
2024-11-06 18:38                 ` Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e72dba1639fd6b68bb2fd392910ac8a61b99d65d.camel@kernel.org \
    --to=jarkko@kernel.org \
    --cc=christophe.leroy@csgroup.eu \
    --cc=jgg@ziepe.ca \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=naveen.n.rao@linux.ibm.com \
    --cc=npiggin@gmail.com \
    --cc=peterhuewe@gmx.de \
    --cc=robh@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.