From: William Breathitt Gray <vilhelm.gray@gmail.com>
To: Syed Nayyar Waris <syednwaris@gmail.com>
Cc: jic23@kernel.org, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 1/3] counter: 104-quad-8: Add lock guards - generic interface
Date: Thu, 12 Mar 2020 11:29:01 -0400 [thread overview]
Message-ID: <20200312152901.GA3250@icarus> (raw)
In-Reply-To: <20200312112438.GA32462@syed>
[-- Attachment #1: Type: text/plain, Size: 21953 bytes --]
On Thu, Mar 12, 2020 at 04:54:38PM +0530, Syed Nayyar Waris wrote:
> Add lock protection from race conditions to 104-quad-8 counter
> driver generic interface code changes. There is no IRQ handling so spin_lock calls
> are used for protection.
>
> Fixes: f1d8a071d45b ("counter: 104-quad-8: Add Generic Counter interface
> support")
>
> Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
>
> Split the patch from filter clock prescaler and differential encoder
> cable status changes. Also, include more code statements for protection
> using spin_lock calls and remove protection from few code statements as
> they were unnecessary.
> ---
Hello Syed,
Text above the "---" line will be saved as part of the commit message,
which is not what we want for review comments. Move your comments to
below this line instead; this patch I submitted recently is a good
example of the format:
https://lore.kernel.org/linux-iio/20200301220719.25173-1-vilhelm.gray@gmail.com/
I have some more changes for this patch, but we're almost finished. :-)
> drivers/counter/104-quad-8.c | 174 ++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 149 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index 9dab190..7d42303 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -44,6 +44,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
> * @base: base port address of the IIO device
> */
> struct quad8_iio {
> + spinlock_t lock;
> struct counter_device counter;
> unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
> unsigned int preset[QUAD8_NUM_COUNTERS];
> @@ -123,6 +124,8 @@ static int quad8_read_raw(struct iio_dev *indio_dev,
> /* Borrow XOR Carry effectively doubles count range */
> *val = (borrow ^ carry) << 24;
>
> + spin_lock(&priv->lock);
> +
> /* Reset Byte Pointer; transfer Counter to Output Latch */
> outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
> base_offset + 1);
> @@ -130,6 +133,8 @@ static int quad8_read_raw(struct iio_dev *indio_dev,
> for (i = 0; i < 3; i++)
> *val |= (unsigned int)inb(base_offset) << (8 * i);
>
> + spin_unlock(&priv->lock);
> +
> return IIO_VAL_INT;
> case IIO_CHAN_INFO_ENABLE:
> *val = priv->ab_enable[chan->channel];
> @@ -160,6 +165,8 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
> if ((unsigned int)val > 0xFFFFFF)
> return -EINVAL;
>
> + spin_lock(&priv->lock);
> +
> /* Reset Byte Pointer */
> outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
>
> @@ -183,12 +190,16 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
> /* Reset Error flag */
> outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> case IIO_CHAN_INFO_ENABLE:
> /* only boolean values accepted */
> if (val < 0 || val > 1)
> return -EINVAL;
>
> + spin_lock(&priv->lock);
> +
> priv->ab_enable[chan->channel] = val;
>
> ior_cfg = val | priv->preset_enable[chan->channel] << 1;
> @@ -196,8 +207,12 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
> /* Load I/O control configuration */
> outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> case IIO_CHAN_INFO_SCALE:
> + spin_lock(&priv->lock);
> +
> /* Quadrature scaling only available in quadrature mode */
> if (!priv->quadrature_mode[chan->channel] && (val2 || val != 1))
> return -EINVAL;
We will need to careful here because there are some return statements;
we are bound to deadlock if we return without calling spin_unlock first.
There are a couple ways I can think of that allow you to resolve this:
for example you can call spin_unlock before every return statement, or
maybe create a goto that calls spin_unlock and then returns -EINVAL;
I'll leave it up for you to decide how to solve this.
> @@ -219,6 +234,8 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
> else
> return -EINVAL;
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -255,6 +272,8 @@ static ssize_t quad8_write_preset(struct iio_dev *indio_dev, uintptr_t private,
> if (preset > 0xFFFFFF)
> return -EINVAL;
>
> + spin_lock(&priv->lock);
> +
> priv->preset[chan->channel] = preset;
>
> /* Reset Byte Pointer */
> @@ -264,6 +283,8 @@ static ssize_t quad8_write_preset(struct iio_dev *indio_dev, uintptr_t private,
> for (i = 0; i < 3; i++)
> outb(preset >> (8 * i), base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return len;
> }
>
> @@ -293,6 +314,8 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
> /* Preset enable is active low in Input/Output Control register */
> preset_enable = !preset_enable;
>
> + spin_lock(&priv->lock);
> +
> priv->preset_enable[chan->channel] = preset_enable;
>
> ior_cfg = priv->ab_enable[chan->channel] |
> @@ -301,6 +324,8 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
> /* Load I/O control configuration to Input / Output Control Register */
> outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return len;
> }
>
> @@ -358,6 +383,8 @@ static int quad8_set_count_mode(struct iio_dev *indio_dev,
> unsigned int mode_cfg = cnt_mode << 1;
> const int base_offset = priv->base + 2 * chan->channel + 1;
>
> + spin_lock(&priv->lock);
> +
> priv->count_mode[chan->channel] = cnt_mode;
>
> /* Add quadrature mode configuration */
> @@ -367,6 +394,8 @@ static int quad8_set_count_mode(struct iio_dev *indio_dev,
> /* Load mode configuration to Counter Mode Register */
> outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -394,9 +423,13 @@ static int quad8_set_synchronous_mode(struct iio_dev *indio_dev,
> const struct iio_chan_spec *chan, unsigned int synchronous_mode)
> {
> struct quad8_iio *const priv = iio_priv(indio_dev);
> - const unsigned int idr_cfg = synchronous_mode |
> - priv->index_polarity[chan->channel] << 1;
> const int base_offset = priv->base + 2 * chan->channel + 1;
> + unsigned int idr_cfg;
The synchronous_mode parameter does not need protection so you can
initialize idr_cfg to it immediately:
unsigned int idr_cfg = synchronous_mode;
> +
> + spin_lock(&priv->lock);
> +
> + idr_cfg = synchronous_mode |
> + priv->index_polarity[chan->channel] << 1;
Since we set idr_cfg to synchronous_mode earlier, this line can become:
idr_cfg |= priv->index_polarity[chan->channel] << 1;
>
> /* Index function must be non-synchronous in non-quadrature mode */
> if (synchronous_mode && !priv->quadrature_mode[chan->channel])
There is a return statement here that could create a deadlock situation.
To resolve this, you can call spin_unlock before the return statement.
> @@ -407,6 +440,8 @@ static int quad8_set_synchronous_mode(struct iio_dev *indio_dev,
> /* Load Index Control configuration to Index Control Register */
> outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -434,8 +469,12 @@ static int quad8_set_quadrature_mode(struct iio_dev *indio_dev,
> const struct iio_chan_spec *chan, unsigned int quadrature_mode)
> {
> struct quad8_iio *const priv = iio_priv(indio_dev);
> - unsigned int mode_cfg = priv->count_mode[chan->channel] << 1;
> const int base_offset = priv->base + 2 * chan->channel + 1;
> + unsigned int mode_cfg;
> +
> + spin_lock(&priv->lock);
> +
> + mode_cfg = priv->count_mode[chan->channel] << 1;
>
> if (quadrature_mode)
> mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3;
> @@ -453,6 +492,8 @@ static int quad8_set_quadrature_mode(struct iio_dev *indio_dev,
> /* Load mode configuration to Counter Mode Register */
> outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -480,15 +521,21 @@ static int quad8_set_index_polarity(struct iio_dev *indio_dev,
> const struct iio_chan_spec *chan, unsigned int index_polarity)
> {
> struct quad8_iio *const priv = iio_priv(indio_dev);
> - const unsigned int idr_cfg = priv->synchronous_mode[chan->channel] |
> - index_polarity << 1;
> const int base_offset = priv->base + 2 * chan->channel + 1;
> + unsigned int idr_cfg;
The index_polarity parameter does not need protection so we can
initialize idr_cfg to it immediately:
unsigned int idr_cfg = index_polarity << 1;
> +
> + spin_lock(&priv->lock);
> +
> + idr_cfg = priv->synchronous_mode[chan->channel] |
> + index_polarity << 1;
Since we idr_cfg was set with index_polarity earlier, this line can
become:
idr_cfg |= priv->synchronous_mode[chan->channel];
>
> priv->index_polarity[chan->channel] = index_polarity;
>
> /* Load Index Control configuration to Index Control Register */
> outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -603,6 +650,8 @@ static int quad8_count_read(struct counter_device *counter,
> /* Borrow XOR Carry effectively doubles count range */
> *val = (unsigned long)(borrow ^ carry) << 24;
>
> + spin_lock(&((struct quad8_iio *)priv)->lock);
You can redeclare priv throughout your patch to drop the const qualifier
whenever needed so that you don't need to constantly cast these
spin_lock/spin_unlock calls everywhere:
struct quad8_iio *const priv = counter->priv;
...
spin_lock(&priv->lock);
...
spin_unlock(&priv->lock);
> +
> /* Reset Byte Pointer; transfer Counter to Output Latch */
> outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
> base_offset + 1);
> @@ -610,6 +659,8 @@ static int quad8_count_read(struct counter_device *counter,
> for (i = 0; i < 3; i++)
> *val |= (unsigned long)inb(base_offset) << (8 * i);
>
> + spin_unlock(&((struct quad8_iio *)priv)->lock);
> +
> return 0;
> }
>
> @@ -624,6 +675,8 @@ static int quad8_count_write(struct counter_device *counter,
> if (val > 0xFFFFFF)
> return -EINVAL;
>
> + spin_lock(&((struct quad8_iio *)priv)->lock);
> +
> /* Reset Byte Pointer */
> outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
>
> @@ -647,6 +700,8 @@ static int quad8_count_write(struct counter_device *counter,
> /* Reset Error flag */
> outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
>
> + spin_unlock(&((struct quad8_iio *)priv)->lock);
> +
> return 0;
> }
>
> @@ -669,11 +724,11 @@ static int quad8_function_get(struct counter_device *counter,
> {
> const struct quad8_iio *const priv = counter->priv;
> const int id = count->id;
> - const unsigned int quadrature_mode = priv->quadrature_mode[id];
> - const unsigned int scale = priv->quadrature_scale[id];
>
> - if (quadrature_mode)
> - switch (scale) {
> + spin_lock(&((struct quad8_iio *)priv)->lock);
> +
> + if (priv->quadrature_mode[id])
> + switch (priv->quadrature_scale[id]) {
> case 0:
> *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1;
> break;
> @@ -687,6 +742,8 @@ static int quad8_function_get(struct counter_device *counter,
> else
> *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION;
>
> + spin_unlock(&((struct quad8_iio *)priv)->lock);
> +
> return 0;
> }
>
> @@ -697,10 +754,15 @@ static int quad8_function_set(struct counter_device *counter,
> const int id = count->id;
> unsigned int *const quadrature_mode = priv->quadrature_mode + id;
> unsigned int *const scale = priv->quadrature_scale + id;
> - unsigned int mode_cfg = priv->count_mode[id] << 1;
> unsigned int *const synchronous_mode = priv->synchronous_mode + id;
> - const unsigned int idr_cfg = priv->index_polarity[id] << 1;
> const int base_offset = priv->base + 2 * id + 1;
> + unsigned int mode_cfg;
> + unsigned int idr_cfg;
> +
> + spin_lock(&priv->lock);
> +
> + mode_cfg = priv->count_mode[id] << 1;
> + idr_cfg = priv->index_polarity[id] << 1;
>
> if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) {
> *quadrature_mode = 0;
> @@ -736,6 +798,8 @@ static int quad8_function_set(struct counter_device *counter,
> /* Load mode configuration to Counter Mode Register */
> outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -852,15 +916,21 @@ static int quad8_index_polarity_set(struct counter_device *counter,
> {
> struct quad8_iio *const priv = counter->priv;
> const size_t channel_id = signal->id - 16;
> - const unsigned int idr_cfg = priv->synchronous_mode[channel_id] |
> - index_polarity << 1;
> const int base_offset = priv->base + 2 * channel_id + 1;
> + unsigned int idr_cfg;
The index_polarity parameter does not need to be protected so you can
initalized idr_cfg with it immediatedly:
unsigned int idr_cfg = index_polarity << 1;
> +
> + spin_lock(&priv->lock);
> +
> + idr_cfg = priv->synchronous_mode[channel_id] |
> + index_polarity << 1;
Since idr_cfg was already initialized with index_polarity, this line can
become:
idr_cfg |= priv->synchronous_mode[channel_id];
>
> priv->index_polarity[channel_id] = index_polarity;
>
> /* Load Index Control configuration to Index Control Register */
> outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -887,9 +957,13 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
> {
> struct quad8_iio *const priv = counter->priv;
> const size_t channel_id = signal->id - 16;
> - const unsigned int idr_cfg = synchronous_mode |
> - priv->index_polarity[channel_id] << 1;
> const int base_offset = priv->base + 2 * channel_id + 1;
> + unsigned int idr_cfg;
The synchronous_mode parameter does not need to be protected so you can
initalized idr_cfg with it immediatedly:
unsigned int idr_cfg = synchronous_mode;
> +
> + spin_lock(&priv->lock);
> +
> + idr_cfg = synchronous_mode |
> + priv->index_polarity[channel_id] << 1;
Since idr_cfg was already initialized with synchronous_mode, this line
can become:
idr_cfg |= priv->index_polarity[channel_id] << 1;
>
> /* Index function must be non-synchronous in non-quadrature mode */
> if (synchronous_mode && !priv->quadrature_mode[channel_id])
There's a return statement here that can cause a deadlock. You should
call spin_unlock before the return statement.
> @@ -900,6 +974,8 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
> /* Load Index Control configuration to Index Control Register */
> outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -964,6 +1040,8 @@ static int quad8_count_mode_set(struct counter_device *counter,
> break;
> }
>
> + spin_lock(&priv->lock);
> +
> priv->count_mode[count->id] = cnt_mode;
>
> /* Set count mode configuration value */
> @@ -976,6 +1054,8 @@ static int quad8_count_mode_set(struct counter_device *counter,
> /* Load mode configuration to Counter Mode Register */
> outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return 0;
> }
>
> @@ -1017,6 +1097,8 @@ static ssize_t quad8_count_enable_write(struct counter_device *counter,
> if (err)
> return err;
>
> + spin_lock(&priv->lock);
> +
> priv->ab_enable[count->id] = ab_enable;
>
> ior_cfg = ab_enable | priv->preset_enable[count->id] << 1;
> @@ -1024,6 +1106,8 @@ static ssize_t quad8_count_enable_write(struct counter_device *counter,
> /* Load I/O control configuration */
> outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
>
> + spin_unlock(&priv->lock);
> +
> return len;
> }
>
> @@ -1052,6 +1136,22 @@ static ssize_t quad8_count_preset_read(struct counter_device *counter,
> return sprintf(buf, "%u\n", priv->preset[count->id]);
> }
>
> +void quad8_preset_register_set(struct counter_device *counter,
> + const int base_offset, int id, unsigned int preset)
We can simplify this parameter list some more because base_offset can be
determined by the id. I think something like the following would work:
void quad8_preset_register_set(struct quad8_iio *quad8iio,
unsigned int id, unsigned int preset)
{
const unsigned int base_offset = quad8iio->base + 2 * id;
...
> +{
> + struct quad8_iio *const priv = counter->priv;
> + int i;
> +
> + priv->preset[id] = preset;
> +
> + /* Reset Byte Pointer */
> + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
> +
> + /* Set Preset Register */
> + for (i = 0; i < 3; i++)
> + outb(preset >> (8 * i), base_offset);
> +}
> +
> static ssize_t quad8_count_preset_write(struct counter_device *counter,
> struct counter_count *count, void *private, const char *buf, size_t len)
> {
> @@ -1059,7 +1159,6 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
> const int base_offset = priv->base + 2 * count->id;
Defining base_offset here will no longer be necessary because the new
quad8_preset_register_set will define it, so you can delete this line.
> unsigned int preset;
> int ret;
> - int i;
>
> ret = kstrtouint(buf, 0, &preset);
> if (ret)
> @@ -1069,14 +1168,11 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
> if (preset > 0xFFFFFF)
> return -EINVAL;
>
> - priv->preset[count->id] = preset;
> + spin_lock(&priv->lock);
>
> - /* Reset Byte Pointer */
> - outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
> + quad8_preset_register_set(counter, base_offset, count->id, preset);
This then becomes:
quad8_preset_register_set(priv, count->id, preset);
>
> - /* Set Preset Register */
> - for (i = 0; i < 3; i++)
> - outb(preset >> (8 * i), base_offset);
> + spin_unlock(&priv->lock);
>
> return len;
> }
> @@ -1086,13 +1182,17 @@ static ssize_t quad8_count_ceiling_read(struct counter_device *counter,
> {
> const struct quad8_iio *const priv = counter->priv;
>
> + spin_lock(&((struct quad8_iio *)priv)->lock);
> +
> /* Range Limit and Modulo-N count modes use preset value as ceiling */
> switch (priv->count_mode[count->id]) {
> case 1:
> case 3:
> - return quad8_count_preset_read(counter, count, private, buf);
> + return sprintf(buf, "%u\n", priv->preset[count->id]);
> }
>
> + spin_unlock(&((struct quad8_iio *)priv)->lock);
> +
> /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
> return sprintf(buf, "33554431\n");
> }
> @@ -1101,15 +1201,32 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
> struct counter_count *count, void *private, const char *buf, size_t len)
> {
> struct quad8_iio *const priv = counter->priv;
> + const int base_offset = priv->base + 2 * count->id;
This base_offset can go away since it will be defined anyway in the
quad8_preset_register_set function.
> + unsigned int preset;
Rename this variable to "ceiling". Although ceiling and preset share the
same register, they are functionally different so it's best for us to
differentiate between the two.
> + int ret;
> +
> + spin_lock(&priv->lock);
>
> /* Range Limit and Modulo-N count modes use preset value as ceiling */
> switch (priv->count_mode[count->id]) {
> case 1:
> case 3:
> - return quad8_count_preset_write(counter, count, private, buf,
> - len);
> + ret = kstrtouint(buf, 0, &preset);
> + if (ret)
> + return ret;
> +
> + /* Only 24-bit values are supported */
> + if (preset > 0xFFFFFF)
> + return -EINVAL;
The kstrtouint call and 24-bit value check should occur outside of this
switch statement since this check is needed regardless of the count
mode. So something like this:
ret = kstrtouint(buf, 0, &ceiling);
if (ret)
return ret;
if (ceiling > 0xFFFFFF)
return -EINVAL;
spin_lock(&priv->lock);
switch (priv->count_mode[count->id]) {
...
> +
> + quad8_preset_register_set(counter, base_offset,
> + count->id, preset);
This becomes:
quad8_preset_register_set(priv, count->id, ceiling);
> +
> + return len;
This return is not needed. You can break here instead.
Sincerely,
William Breathitt Gray
> }
>
> + spin_unlock(&priv->lock);
> +
> return len;
> }
>
> @@ -1137,6 +1254,8 @@ static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
> /* Preset enable is active low in Input/Output Control register */
> preset_enable = !preset_enable;
>
> + spin_lock(&priv->lock);
> +
> priv->preset_enable[count->id] = preset_enable;
>
> ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1;
> @@ -1144,6 +1263,8 @@ static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
> /* Load I/O control configuration to Input / Output Control Register */
> outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
>
> + spin_unlock(&priv->lock);
> +
> return len;
> }
>
> @@ -1429,6 +1550,9 @@ static int quad8_probe(struct device *dev, unsigned int id)
> quad8iio->counter.priv = quad8iio;
> quad8iio->base = base[id];
>
> + /* Initialize spin lock */
> + spin_lock_init(&quad8iio->lock);
> +
> /* Reset all counters and disable interrupt function */
> outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
> /* Set initial configuration for all counters */
> --
> 2.7.4
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
prev parent reply other threads:[~2020-03-12 15:29 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-12 11:24 [PATCH v3 1/3] counter: 104-quad-8: Add lock guards - generic interface Syed Nayyar Waris
2020-03-12 15:29 ` William Breathitt Gray [this message]
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=20200312152901.GA3250@icarus \
--to=vilhelm.gray@gmail.com \
--cc=jic23@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=syednwaris@gmail.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 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.