LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Conor Dooley <conor@kernel.org>
To: Vladimir Oltean <vladimir.oltean@nxp.com>
Cc: linux-phy@lists.infradead.org, devicetree@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org,
	Ioana Ciornei <ioana.ciornei@nxp.com>,
	Vinod Koul <vkoul@kernel.org>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Tanjeff Moos <tanjeff.moos@westermo.com>,
	"Christophe Leroy (CS GROUP)" <chleroy@kernel.org>,
	Michael Walle <mwalle@kernel.org>,
	Shawn Guo <shawnguo@kernel.org>, Frank Li <Frank.Li@nxp.com>,
	linux-kernel@vger.kernel.org,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Rob Herring <robh@kernel.org>
Subject: Re: [PATCH v1 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure
Date: Fri, 12 Jun 2026 16:44:30 +0100	[thread overview]
Message-ID: <20260612-twenty-diary-4aab5327f9c2@spud> (raw)
In-Reply-To: <20260611193940.44416-8-vladimir.oltean@nxp.com>

[-- Attachment #1: Type: text/plain, Size: 15588 bytes --]

On Thu, Jun 11, 2026 at 10:39:39PM +0300, Vladimir Oltean wrote:
> From: Ioana Ciornei <ioana.ciornei@nxp.com>
> 
> Add support for the RCW override procedure which enables runtime
> reconfiguration of the protocol running on a SerDes lane. The procedure
> is done through the DCFG DCSR space which now can be defined as the
> second memory region of the guts DT node.
> Support is added on the following SoCs: LS1046A, LS1088A, LS2088A.
> 
> The procedure is exported to the "client" driver - the Lynx10G SerDes
> PHY driver - through the following functions:
> - fsl_guts_lane_init() used to notify the initial / boot time lane mode
>   running on a SerDes lane.
> - fsl_guts_lane_validate() used to validate that changing the protocol
>   on a specific lane is supported.
> - fsl_guts_lane_set_mode() which can be used to request the RCW
>   procedure be executed for a specific lane.
> 
> Since the RCW override procedure is different depending on the SoC, the
> private fsl_soc_data structure is updated with two new per SoC callbacks
> (.serdes_get_rcw_override() and .serdes_init_rcwcr()) which get used
> from the generic fsl_guts_lane_set_mode() function. These two callbacks
> hide all the SoC specific register offsets, masks and values so that the
> _set_mode() procedure is straightforward.
> 
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Cc: Conor Dooley <conor@kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: devicetree@vger.kernel.org

Wrong CC list for this specific patch?

ta,
Conor.

> ---
>  drivers/soc/fsl/guts.c   | 286 ++++++++++++++++++++++++++++++++++++++-
>  include/linux/fsl/guts.h |  20 ++-
>  2 files changed, 299 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
> index 9f2aff07a274..23ec5750080c 100644
> --- a/drivers/soc/fsl/guts.c
> +++ b/drivers/soc/fsl/guts.c
> @@ -15,6 +15,30 @@
>  #include <linux/fsl/guts.h>
>  
>  #define DCFG_CCSR	0
> +#define DCFG_DCSR	1
> +
> +#define MAX_NUM_LANES	8
> +#define MAX_NUM_SERDES	2
> +
> +#define LS1088A_RCWSR29_SRDS_PRTCL_S1_LNn(lane)	\
> +	GENMASK(19 + 4 * (3 - lane), 16 + 4 * (3 - lane))
> +#define LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn(lane)	\
> +	GENMASK(3 + 4 * (3 - lane), 4 * (3 - lane))
> +
> +#define LS1046A_RCWSR5_SRDS_PRTCL_S1(lane)	\
> +	GENMASK(19 + 4 * (lane), 16 + 4 * (lane))
> +#define SRDS_PRTCL_NONE					0
> +#define SRDS_PRTCL_XFI					1
> +#define SRDS_PRTCL_2500BASEX				2
> +#define SRDS_PRTCL_100BASEX_SGMII			3
> +#define SRDS_PRTCL_QSGMII				4
> +#define SRDS_PRTCL_PCIE					5
> +
> +#define LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1	BIT(14)
> +#define LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(lane)	BIT(6 + (7 - (lane)))
> +#define LS2088A_RCWSR30_SRDS_CLK_SEL_MSK		GENMASK(13, 6)
> +#define SRDS_CLK_SEL_XGMII				1
> +#define SRDS_CLK_SEL_GMII				0
>  
>  struct fsl_soc_die_attr {
>  	char	*die;
> @@ -22,9 +46,19 @@ struct fsl_soc_die_attr {
>  	u32	mask;
>  };
>  
> +struct fsl_soc_serdes_rcw_override {
> +	int offset;
> +	int mask;
> +	int val;
> +};
> +
>  struct fsl_soc_data {
>  	const char *sfp_compat;
>  	u32 uid_offset;
> +	int (*serdes_get_rcw_override)(int index, int lane,
> +				       enum lynx_lane_mode lane_mode,
> +				       struct fsl_soc_serdes_rcw_override *override);
> +	void (*serdes_init_rcwcr)(int index);
>  };
>  
>  enum qoriq_die {
> @@ -138,9 +172,13 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
>  
>  static struct fsl_soc_guts {
>  	struct ccsr_guts __iomem *dcfg_ccsr;
> +	struct ccsr_guts __iomem *dcfg_dcsr;
>  	const struct fsl_soc_data *data;
>  	bool little_endian;
>  	u32 svr;
> +	enum lynx_lane_mode lane_mode[MAX_NUM_SERDES][MAX_NUM_LANES];
> +	bool rcwcr_init_done;
> +	spinlock_t rcwcr_lock; /* serializes concurrent writes to the RCWCR */
>  } soc;
>  
>  static unsigned int fsl_guts_read(const void __iomem *reg)
> @@ -151,6 +189,28 @@ static unsigned int fsl_guts_read(const void __iomem *reg)
>  	return ioread32be(reg);
>  }
>  
> +static void fsl_guts_write(void __iomem *reg, u32 val)
> +{
> +	if (soc.little_endian)
> +		iowrite32(val, reg);
> +	else
> +		iowrite32be(val, reg);
> +}
> +
> +/* Some fields of the Reset Configuration Word (RCW) can be overridden at
> + * runtime by writing to the RCWCRn registers contained within the DCSR space
> + * of the Device Configuration (DCFG) block. The layout of the RCWCRn registers
> + * is identical with the read-only RCWSRn from the CCSR space.
> + */
> +static void fsl_guts_rmw(int offset, u32 val, u32 mask)
> +{
> +	u32 tmp = fsl_guts_read(&soc.dcfg_ccsr->rcwsr[offset]);
> +
> +	tmp &= ~mask;
> +	tmp |= val;
> +	fsl_guts_write(&soc.dcfg_dcsr->rcwcr[offset], tmp);
> +}
> +
>  static bool fsl_soc_die_match_one(u32 svr, const struct fsl_soc_die_attr *match)
>  {
>  	return match->svr == (svr & match->mask);
> @@ -167,6 +227,97 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
>  	return NULL;
>  }
>  
> +static int
> +fsl_guts_serdes_get_rcw_override(int serdes_idx, int lane,
> +				 enum lynx_lane_mode lane_mode,
> +				 struct fsl_soc_serdes_rcw_override *override)
> +{
> +	if ((!fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS1088A]) &&
> +	     !fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS2088A]) &&
> +	     !fsl_soc_die_match_one(soc.svr, &fsl_soc_die[DIE_LS1046A])) ||
> +	    !soc.data || !soc.data->serdes_get_rcw_override) {
> +		pr_debug("RCW override not implemented for SoC\n");
> +		return -EINVAL;
> +	}
> +
> +	if (!soc.dcfg_dcsr) {
> +		pr_debug("Device tree does not define DCFG_DCSR region necessary for RCW override\n");
> +		return -EINVAL;
> +	}
> +
> +	return soc.data->serdes_get_rcw_override(serdes_idx, lane, lane_mode,
> +						 override);
> +}
> +
> +/**
> + * fsl_guts_lane_init() - Notify guts module of SerDes lane configuration
> + * @serdes_idx: zero-based SerDes block index
> + * @lane: zero-based lane index within SerDes
> + * @lane_mode: initial / boot time SerDes protocol for lane
> + *
> + * On the LS208xA SoC, the RCW override procedure needs to be aware of all link
> + * modes which are configured on a SerDes block.
> + */
> +void fsl_guts_lane_init(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> +	soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
> +}
> +EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_init, "FSL_GUTS");
> +
> +/**
> + * fsl_guts_lane_validate() - Validate that SerDes protocol is implemented and
> + *	supported on current SoC
> + * @serdes_idx: zero-based SerDes block index
> + * @lane: zero-based lane index within SerDes
> + * @lane_mode: requested SerDes protocol
> + *
> + * Should be called before actually requesting the RCW override procedure to be
> + * applied using %fsl_guts_lane_set_mode()
> + *
> + * Return: 0 if RCW override to protocol is possible, negative error otherwise
> + */
> +int fsl_guts_lane_validate(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> +	struct fsl_soc_serdes_rcw_override override;
> +
> +	return fsl_guts_serdes_get_rcw_override(serdes_idx, lane, lane_mode,
> +						&override);
> +}
> +EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_validate, "FSL_GUTS");
> +
> +/**
> + * fsl_guts_lane_set_mode() - apply RCW override procedure for SerDes lane
> + * @serdes_idx: zero-based SerDes block index
> + * @lane: zero-based lane index within SerDes
> + * @lane_mode: requested SerDes protocol
> + *
> + * Return: 0 on success, negative error otherwise
> + */
> +int fsl_guts_lane_set_mode(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> +	struct fsl_soc_serdes_rcw_override override;
> +	int err;
> +
> +	err = fsl_guts_serdes_get_rcw_override(serdes_idx, lane, lane_mode,
> +					       &override);
> +	if (err)
> +		return err;
> +
> +	spin_lock(&soc.rcwcr_lock);
> +
> +	if (soc.data->serdes_init_rcwcr)
> +		soc.data->serdes_init_rcwcr(serdes_idx);
> +
> +	fsl_guts_rmw(override.offset, override.val << __bf_shf(override.mask),
> +		     override.mask);
> +	soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
> +
> +	spin_unlock(&soc.rcwcr_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(fsl_guts_lane_set_mode, "FSL_GUTS");
> +
>  static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
>  {
>  	struct device_node *np;
> @@ -193,6 +344,128 @@ static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
>  	return uid;
>  }
>  
> +static int ls1088a_serdes_get_rcw_override(int index, int lane,
> +					   enum lynx_lane_mode lane_mode,
> +					   struct fsl_soc_serdes_rcw_override *override)
> +{
> +	/* The RCW override procedure has to write to different registers
> +	 * depending on the SerDes block index.
> +	 */
> +	switch (index) {
> +	case 1:
> +		override->offset = 28;
> +		override->mask = LS1088A_RCWSR29_SRDS_PRTCL_S1_LNn(lane);
> +		break;
> +	case 2:
> +		override->offset = 29;
> +		override->mask = LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn(lane);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
> +		override->val = SRDS_PRTCL_XFI;
> +	else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
> +		override->val = SRDS_PRTCL_100BASEX_SGMII;
> +	else
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int ls1046a_serdes_get_rcw_override(int index, int lane,
> +					   enum lynx_lane_mode lane_mode,
> +					   struct fsl_soc_serdes_rcw_override *override)
> +{
> +	/* The RCW override procedure has to write to different registers
> +	 * depending on the SerDes block index.
> +	 */
> +	switch (index) {
> +	case 1:
> +		override->offset = 4;
> +		override->mask = LS1046A_RCWSR5_SRDS_PRTCL_S1(lane);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
> +		override->val = SRDS_PRTCL_XFI;
> +	else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
> +		override->val = SRDS_PRTCL_100BASEX_SGMII;
> +	else
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int ls2088a_serdes_get_rcw_override(int index, int lane,
> +					   enum lynx_lane_mode lane_mode,
> +					   struct fsl_soc_serdes_rcw_override *override)
> +{
> +	switch (index) {
> +	case 1:
> +		override->offset = 29;
> +		override->mask = LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(lane);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (lynx_lane_mode_uses_xgmii_mac(lane_mode))
> +		override->val = SRDS_CLK_SEL_XGMII;
> +	else if (lynx_lane_mode_uses_gmii_mac(lane_mode))
> +		override->val = SRDS_CLK_SEL_GMII;
> +	else
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static void ls2088a_serdes_init_rcwcr(int serdes_idx)
> +{
> +	u32 reg;
> +	int i;
> +
> +	if (serdes_idx != 1)
> +		return;
> +	if (soc.rcwcr_init_done)
> +		return;
> +
> +	/* SRDS_CLK_EN_SEL_XGMII_S1: SerDes Clock Enable Select XGMII Serdes 1:
> +	 * Enables to select GMII/XGMII clock according to
> +	 * SRDS_CLK_SEL_XGMII_Ln_S1
> +	 */
> +	reg = LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1;
> +
> +	/* We need to configure the initial state of all lanes for
> +	 * the SerDes block #1
> +	 */
> +	for (i = 0; i < MAX_NUM_LANES; i++)
> +		if (lynx_lane_mode_uses_xgmii_mac(soc.lane_mode[serdes_idx - 1][i]))
> +			reg |= LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(i);
> +
> +	fsl_guts_rmw(29, reg,
> +		     LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1 |
> +		     LS2088A_RCWSR30_SRDS_CLK_SEL_MSK);
> +
> +	soc.rcwcr_init_done = true;
> +}
> +
> +static const struct fsl_soc_data ls1088a_data = {
> +	.serdes_get_rcw_override = ls1088a_serdes_get_rcw_override,
> +};
> +
> +static const struct fsl_soc_data ls1046a_data = {
> +	.serdes_get_rcw_override = ls1046a_serdes_get_rcw_override,
> +};
> +
> +static const struct fsl_soc_data ls2088a_data = {
> +	.serdes_get_rcw_override = ls2088a_serdes_get_rcw_override,
> +	.serdes_init_rcwcr = ls2088a_serdes_init_rcwcr,
> +};
> +
>  static const struct fsl_soc_data ls1028a_data = {
>  	.sfp_compat = "fsl,ls1028a-sfp",
>  	.uid_offset = 0x21c,
> @@ -221,10 +494,10 @@ static const struct of_device_id fsl_guts_of_match[] = {
>  	{ .compatible = "fsl,mpc8572-guts", },
>  	{ .compatible = "fsl,ls1021a-dcfg", },
>  	{ .compatible = "fsl,ls1043a-dcfg", },
> -	{ .compatible = "fsl,ls2080a-dcfg", },
> -	{ .compatible = "fsl,ls1088a-dcfg", },
> +	{ .compatible = "fsl,ls2080a-dcfg", .data = &ls2088a_data},
> +	{ .compatible = "fsl,ls1088a-dcfg", .data = &ls1088a_data},
>  	{ .compatible = "fsl,ls1012a-dcfg", },
> -	{ .compatible = "fsl,ls1046a-dcfg", },
> +	{ .compatible = "fsl,ls1046a-dcfg", .data = &ls1046a_data},
>  	{ .compatible = "fsl,lx2160a-dcfg", },
>  	{ .compatible = "fsl,ls1028a-dcfg", .data = &ls1028a_data},
>  	{}
> @@ -250,6 +523,8 @@ static int __init fsl_guts_init(void)
>  		of_node_put(np);
>  		return -ENOMEM;
>  	}
> +	/* DCFG_DCSR is optional */
> +	soc.dcfg_dcsr = of_iomap(np, DCFG_DCSR);
>  
>  	soc.little_endian = of_property_read_bool(np, "little-endian");
>  	soc.svr = fsl_guts_read(&soc.dcfg_ccsr->svr);
> @@ -296,6 +571,8 @@ static int __init fsl_guts_init(void)
>  		goto err;
>  	}
>  
> +	spin_lock_init(&soc.rcwcr_lock);
> +
>  	pr_info("Machine: %s\n", soc_dev_attr->machine);
>  	pr_info("SoC family: %s\n", soc_dev_attr->family);
>  	pr_info("SoC ID: %s, Revision: %s\n",
> @@ -305,7 +582,8 @@ static int __init fsl_guts_init(void)
>  
>  err_nomem:
>  	ret = -ENOMEM;
> -
> +	if (soc.dcfg_dcsr)
> +		iounmap(soc.dcfg_dcsr);
>  	iounmap(soc.dcfg_ccsr);
>  err:
>  	kfree(soc_dev_attr->family);
> diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h
> index fdb55ca47a4f..176842531241 100644
> --- a/include/linux/fsl/guts.h
> +++ b/include/linux/fsl/guts.h
> @@ -13,6 +13,7 @@
>  
>  #include <linux/types.h>
>  #include <linux/io.h>
> +#include <soc/fsl/phy-fsl-lynx.h>
>  
>  /*
>   * Global Utility Registers.
> @@ -91,9 +92,15 @@ struct ccsr_guts {
>  	u32	iovselsr;	/* 0x.00c0 - I/O voltage select status register
>  					     Called 'elbcvselcr' on 86xx SOCs */
>  	u8	res0c4[0x100 - 0xc4];
> -	u32	rcwsr[16];	/* 0x.0100 - Reset Control Word Status registers
> -					     There are 16 registers */
> -	u8	res140[0x224 - 0x140];
> +	/* 0x.0100 - read-only Reset Configuration Word Status registers in
> +	 * CCSR, or write-only Reset Configuration Word Control registers in
> +	 * DCSR. In both cases there are 32 registers.
> +	 */
> +	union {
> +		u32	rcwsr[32];
> +		u32	rcwcr[32];
> +	};
> +	u8	res180[0x224 - 0x180];
>  	u32	iodelay1;	/* 0x.0224 - IO delay control register 1 */
>  	u32	iodelay2;	/* 0x.0228 - IO delay control register 2 */
>  	u8	res22c[0x604 - 0x22c];
> @@ -131,6 +138,13 @@ struct ccsr_guts {
>  	u32	srds2cr1;	/* 0x.0f44 - SerDes2 Control Register 0 */
>  } __attribute__ ((packed));
>  
> +void fsl_guts_lane_init(int serdes_idx, int lane,
> +			enum lynx_lane_mode lane_mode);
> +int fsl_guts_lane_validate(int serdes_idx, int lane,
> +			   enum lynx_lane_mode lane_mode);
> +int fsl_guts_lane_set_mode(int serdes_idx, int lane,
> +			   enum lynx_lane_mode lane_mode);
> +
>  /* Alternate function signal multiplex control */
>  #define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
>  
> -- 
> 2.34.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

  reply	other threads:[~2026-06-12 15:44 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-11 19:39 [PATCH v1 phy-next 0/8] RCW override for 10G Lynx dynamic protocol reconfiguration Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 1/8] soc: fsl: guts: use a macro to encode the DCFG CCSR space Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 2/8] soc: fsl: guts: add a global structure to hold state Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 3/8] soc: fsl: guts: add a central fsl_guts_read() function Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 4/8] soc: fsl: guts: make it easier to determine on which SoC we are running Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 5/8] soc: fsl: guts: make fsl_soc_data available after fsl_guts_init() Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 6/8] dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region Vladimir Oltean
2026-06-12 15:44   ` Conor Dooley
2026-06-12 20:23     ` Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure Vladimir Oltean
2026-06-12 15:44   ` Conor Dooley [this message]
2026-06-12 20:25     ` Vladimir Oltean
2026-06-11 19:39 ` [PATCH v1 phy-next 8/8] phy: lynx-10g: use RCW override procedure for dynamic protocol change Vladimir Oltean

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=20260612-twenty-diary-4aab5327f9c2@spud \
    --to=conor@kernel.org \
    --cc=Frank.Li@nxp.com \
    --cc=chleroy@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=ioana.ciornei@nxp.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mwalle@kernel.org \
    --cc=neil.armstrong@linaro.org \
    --cc=robh@kernel.org \
    --cc=shawnguo@kernel.org \
    --cc=tanjeff.moos@westermo.com \
    --cc=vkoul@kernel.org \
    --cc=vladimir.oltean@nxp.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox