All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gwendal Grignou <gwendal@chromium.org>
To: Jonathan Cameron <jic23@kernel.org>
Cc: Brian Norris <briannorris@chromium.org>,
	Hartmut Knaack <knaack.h@gmx.de>,
	Lars-Peter Clausen <lars@metafoo.de>,
	Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
	Lee Jones <lee.jones@linaro.org>,
	Benson Leung <bleung@chromium.org>,
	Enric Balletbo i Serra <enric.balletbo@collabora.com>,
	Doug Anderson <dianders@chromium.org>,
	Guenter Roeck <groeck@chromium.org>,
	Fabien Lahoudere <fabien.lahoudere@collabora.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	linux-iio <linux-iio@vger.kernel.org>
Subject: Re: [PATCH v4 13/17] iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO
Date: Thu, 14 Nov 2019 10:17:52 -0800	[thread overview]
Message-ID: <CAPUE2uv_9YPsX_evtb4HSWHFuvWbLVGZjreWyJyeKVwTSh24Jw@mail.gmail.com> (raw)
In-Reply-To: <20191110131714.098ee2ea@archlinux>

The problem are:- in case of a kernel crash while collecting sensor
data: when the kernel restart, the sensors are still sending events. -
we can also enable a sensor behind the iiio driver back through debug
tools: we don

On Sun, Nov 10, 2019 at 5:17 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Tue,  5 Nov 2019 14:26:48 -0800
> Gwendal Grignou <gwendal@chromium.org> wrote:
>
> > When EC supports FIFO, each IIO device registers a callback, to put
> > samples in the buffer when they arrives from the FIFO.
> > We can still use a trigger to collect samples, but there may be some
> > duplications in the buffer: EC has a single FIFO, so once one sensor is
> > using it, all sensors event will be in the FIFO.
> > To be sure events generated by cros_ec_sensorhub or the trigger uses the
> > same time domain, current_timestamp_clock must be set to "boottime".
>
> How is that enforced?
I should have removed this comment: cros_ec_sensors_push_data() now
checks for the iio dev clock_id and add an offset if necessary.
I add a patch for IIO to allow changing timestamp_clock from the
driver itself: I set to default for cros ec sensor to boottime, since
it is the default timestamp source coming from the FIFO.

>  I'd have no problem with core support for IIO
> to allow a driver that has requirements like this to override
> the normal flexibility.
>
> >
> > When no FIFO, the user space app needs to call trigger_new, or better
> > register a high precision timer.
> >
> > Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
> A question + a comment that I'm still not happy with the fact we have
> to protect against a race on startup.  However, we can perhaps make that
> a problem for another day.
>
> Assuming the question on the mode mask change is resolved.
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
> > ---
> > Changes in v4:
> > - Fix a logic error when the sensor is not "physical", for instance lig
> >   angle: core_init() would return !0 even if there was no error.
> > - Check patch with --strict option
> >     Use sizeof(*obj) instead of sizeof(struct ...obj)
> >     Alignement
> > Change in v3:
> > - Remove double line
> > - Fix indentation
> > - Add code to support iio clock_id setting. Optimized for
> >   CLOCK_BOOTTIME.
> > Change in v2 from "Use triggered buffer only when EC does not support
> > FIFO":
> > - Keep trigger all the time.
> > - Add  devm_add_action to cleanup callback registration.
> > - EC that "reports" legacy sensors do not have FIFO.
> > - Use iiio_is_buffer_enabled instead of checking the scan_mask
> >   before sending samples to buffer.
> > - Add empty lines for visibility.
> >
> >  drivers/iio/accel/cros_ec_accel_legacy.c      |  8 +-
> >  .../cros_ec_sensors/cros_ec_lid_angle.c       |  2 +-
> >  .../common/cros_ec_sensors/cros_ec_sensors.c  |  9 +-
> >  .../cros_ec_sensors/cros_ec_sensors_core.c    | 85 ++++++++++++++++++-
> >  drivers/iio/light/cros_ec_light_prox.c        |  9 +-
> >  drivers/iio/pressure/cros_ec_baro.c           |  9 +-
> >  .../linux/iio/common/cros_ec_sensors_core.h   | 10 ++-
> >  7 files changed, 103 insertions(+), 29 deletions(-)
> >
> > diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c
> > index 65f85faf6f31..b9f651e4ce99 100644
> > --- a/drivers/iio/accel/cros_ec_accel_legacy.c
> > +++ b/drivers/iio/accel/cros_ec_accel_legacy.c
> > @@ -171,7 +171,8 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
> >       if (!indio_dev)
> >               return -ENOMEM;
> >
> > -     ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
> > +     ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
> > +                                     cros_ec_sensors_capture, NULL);
> >       if (ret)
> >               return ret;
> >
> > @@ -191,11 +192,6 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
> >               state->sign[CROS_EC_SENSOR_Z] = -1;
> >       }
> >
> > -     ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
> > -                     cros_ec_sensors_capture, NULL);
> > -     if (ret)
> > -             return ret;
> > -
> >       return devm_iio_device_register(dev, indio_dev);
> >  }
> >
> > diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
> > index 1dcc2a16ab2d..e30a59fcf0f9 100644
> > --- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
> > +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
> > @@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
> >       if (!indio_dev)
> >               return -ENOMEM;
> >
> > -     ret = cros_ec_sensors_core_init(pdev, indio_dev, false);
> > +     ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL);
> >       if (ret)
> >               return ret;
> >
> > diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
> > index 7dce04473467..62a0dd970988 100644
> > --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
> > +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
> > @@ -231,7 +231,9 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
> >       if (!indio_dev)
> >               return -ENOMEM;
> >
> > -     ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
> > +     ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
> > +                                     cros_ec_sensors_capture,
> > +                                     cros_ec_sensors_push_data);
> >       if (ret)
> >               return ret;
> >
> > @@ -293,11 +295,6 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
> >       else
> >               state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
> >
> > -     ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
> > -                     cros_ec_sensors_capture, NULL);
> > -     if (ret)
> > -             return ret;
> > -
> >       return devm_iio_device_register(dev, indio_dev);
> >  }
> >
> > diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
> > index b47da497a3c3..904cd26dd31f 100644
> > --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
> > +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
> > @@ -12,6 +12,7 @@
> >  #include <linux/iio/iio.h>
> >  #include <linux/iio/kfifo_buf.h>
> >  #include <linux/iio/trigger_consumer.h>
> > +#include <linux/iio/triggered_buffer.h>
> >  #include <linux/kernel.h>
> >  #include <linux/mfd/cros_ec.h>
> >  #include <linux/module.h>
> > @@ -83,17 +84,78 @@ static void get_default_min_max_freq(enum motionsensor_type type,
> >       }
> >  }
> >
> > +int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
> > +                           s16 *data,
> > +                           s64 timestamp)
> > +{
> > +     struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
> > +     s16 *out;
> > +     s64 delta;
> > +     unsigned int i;
> > +
> > +     /*
> > +      * It can happen if we get a samples before the iio device is fully
> > +      * registered.
>
> I'd really like to stop that happening as it seems like a nasty racey corner case.
> I'm not convinced there aren't 'half registered' cases we can still hit even
> with this protection.  Hardware should be in a clean state before any
> interrupts etc are registered.
You're right, st can not be null, since devm_iio_device_alloc is
called before cros_ec_sensors_core_init that register the callback.
>
> However if you are sure this protection is enough that can be a job for another day.
>
> I suspect you get away with it because of the next check always failing in
> those racey conditions as can't enable the buffer until we have a fully
> set up device.
>
> > +      */
> > +     if (!st)
> > +             return 0;
> > +
> > +     /*
> > +      * Ignore samples if the buffer is not set: it is needed if the ODR is
> > +      * set but the buffer is not enabled yet.
> > +      */
> > +     if (!iio_buffer_enabled(indio_dev))
> > +             return 0;
This check is necessary:
- in case of a kernel crash while collecting sensor data: when the
kernel restart, the sensors are still sending events.
- we can also enable a sensor behind the iiio driver back through
debug tools: the sensor will send sample, but the iio driver is not
ready for them.
> > +
> > +     out = (s16 *)st->samples;
> > +     for_each_set_bit(i,
> > +                      indio_dev->active_scan_mask,
> > +                      indio_dev->masklength) {
> > +             *out = data[i];
> > +             out++;
> > +     }
> > +
> > +     if (iio_device_get_clock(indio_dev) != CLOCK_BOOTTIME)
> > +             delta = iio_get_time_ns(indio_dev) - cros_ec_get_time_ns();
> > +     else
> > +             delta = 0;
> > +
> > +     iio_push_to_buffers_with_timestamp(indio_dev, st->samples,
> > +                                        timestamp + delta);
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data);
> > +
> > +static void cros_ec_sensors_core_clean(void *arg)
> > +{
> > +     struct platform_device *pdev = (struct platform_device *)arg;
> > +     struct cros_ec_sensorhub *sensor_hub =
> > +             dev_get_drvdata(pdev->dev.parent);
> > +     struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> > +     struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
> > +     u8 sensor_num = st->param.info.sensor_num;
> > +
> > +     cros_ec_sensorhub_unregister_push_data(sensor_hub, sensor_num);
> > +}
> > +
> >  /**
> >   * cros_ec_sensors_core_init() - basic initialization of the core structure
> >   * @pdev:            platform device created for the sensors
> >   * @indio_dev:               iio device structure of the device
> >   * @physical_device: true if the device refers to a physical device
> > + * @trigger_capture:    function pointer to call buffer is triggered,
> > + *    for backward compatibility.
> > + * @push_data:          function to call when cros_ec_sensorhub receives
> > + *    a sample for that sensor.
> >   *
> >   * Return: 0 on success, -errno on failure.
> >   */
> >  int cros_ec_sensors_core_init(struct platform_device *pdev,
> >                             struct iio_dev *indio_dev,
> > -                           bool physical_device)
> > +                           bool physical_device,
> > +                           cros_ec_sensors_capture_t trigger_capture,
> > +                           cros_ec_sensorhub_push_data_cb_t push_data)
> >  {
> >       struct device *dev = &pdev->dev;
> >       struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
> > @@ -132,8 +194,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
> >       indio_dev->name = pdev->name;
> >
> >       if (physical_device) {
> > -             indio_dev->modes = INDIO_DIRECT_MODE;
> > -
>
> This particular changes seems odd. Are we dropping access via sysfs?
> From what I recall we don't actually do much with this currently in the
> IIO core, but we 'might' in future ;)
Should not have been removed.

>
> >               state->param.cmd = MOTIONSENSE_CMD_INFO;
> >               state->param.info.sensor_num = sensor_platform->sensor_num;
> >               ret = cros_ec_motion_send_host_cmd(state, 0);
> > @@ -162,6 +222,25 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
> >                       state->frequencies[2] =
> >                           state->resp->info_3.max_frequency;
> >               }
> > +
> > +             ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
> > +                                                   trigger_capture, NULL);
> > +             if (ret)
> > +                     return ret;
> > +
> > +             if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
> > +                     ret = cros_ec_sensorhub_register_push_data(sensor_hub,
> > +                                             sensor_platform->sensor_num,
> > +                                             indio_dev, push_data);
> > +                     if (ret)
> > +                             return ret;
> > +
> > +                     ret = devm_add_action_or_reset(dev,
> > +                                             cros_ec_sensors_core_clean,
> > +                                             pdev);
> > +                     if (ret)
> > +                             return ret;
> > +             }
> >       }
> >
> >       return 0;
> > diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c
> > index d85a391e50c5..698b2ee81ebf 100644
> > --- a/drivers/iio/light/cros_ec_light_prox.c
> > +++ b/drivers/iio/light/cros_ec_light_prox.c
> > @@ -178,7 +178,9 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
> >       if (!indio_dev)
> >               return -ENOMEM;
> >
> > -     ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
> > +     ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
> > +                                     cros_ec_sensors_capture,
> > +                                     cros_ec_sensors_push_data);
> >       if (ret)
> >               return ret;
> >
> > @@ -237,11 +239,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
> >
> >       state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
> >
> > -     ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
> > -                                           cros_ec_sensors_capture, NULL);
> > -     if (ret)
> > -             return ret;
> > -
> >       return devm_iio_device_register(dev, indio_dev);
> >  }
> >
> > diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c
> > index 2354302375de..e1c86b22676c 100644
> > --- a/drivers/iio/pressure/cros_ec_baro.c
> > +++ b/drivers/iio/pressure/cros_ec_baro.c
> > @@ -134,7 +134,9 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
> >       if (!indio_dev)
> >               return -ENOMEM;
> >
> > -     ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
> > +     ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
> > +                                     cros_ec_sensors_capture,
> > +                                     cros_ec_sensors_push_data);
> >       if (ret)
> >               return ret;
> >
> > @@ -180,11 +182,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
> >
> >       state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
> >
> > -     ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
> > -                                           cros_ec_sensors_capture, NULL);
> > -     if (ret)
> > -             return ret;
> > -
> >       return devm_iio_device_register(dev, indio_dev);
> >  }
> >
> > diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h
> > index 0af918978f97..b8f573ca9dcc 100644
> > --- a/include/linux/iio/common/cros_ec_sensors_core.h
> > +++ b/include/linux/iio/common/cros_ec_sensors_core.h
> > @@ -12,6 +12,7 @@
> >  #include <linux/irqreturn.h>
> >  #include <linux/platform_data/cros_ec_commands.h>
> >  #include <linux/platform_data/cros_ec_proto.h>
> > +#include <linux/platform_data/cros_ec_sensorhub.h>
> >
> >  enum {
> >       CROS_EC_SENSOR_X,
> > @@ -32,6 +33,8 @@ enum {
> >  /* Minimum sampling period to use when device is suspending */
> >  #define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000  /* 1 second */
> >
> > +typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p);
> > +
> >  /**
> >   * struct cros_ec_sensors_core_state - state data for EC sensors IIO driver
> >   * @ec:                              cros EC device structure
> > @@ -87,9 +90,14 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
> >
> >  struct platform_device;
> >  int cros_ec_sensors_core_init(struct platform_device *pdev,
> > -                           struct iio_dev *indio_dev, bool physical_device);
> > +                           struct iio_dev *indio_dev, bool physical_device,
> > +                           cros_ec_sensors_capture_t trigger_capture,
> > +                           cros_ec_sensorhub_push_data_cb_t push_data);
> >
> >  irqreturn_t cros_ec_sensors_capture(int irq, void *p);
> > +int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
> > +                           s16 *data,
> > +                           s64 timestamp);
> >
> >  int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st,
> >                                u16 opt_length);
>

  reply	other threads:[~2019-11-14 18:18 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-05 22:26 [PATCH v4 00/17] cros_ec: Add sensorhub driver and FIFO processing Gwendal Grignou
2019-11-05 22:26 ` [PATCH v4 01/17] mfd: cros_ec: Add sensor_count and make check_features public Gwendal Grignou
2019-11-08 22:03   ` Enric Balletbo Serra
2019-11-11 11:44     ` Lee Jones
2019-11-16 11:49       ` Jonathan Cameron
2019-11-05 22:26 ` [PATCH v4 02/17] platform: cros_ec: Add cros_ec_sensor_hub driver Gwendal Grignou
2019-11-10 12:10   ` Jonathan Cameron
2019-11-11  9:24     ` Enric Balletbo i Serra
2019-11-11 11:55       ` Jonathan Cameron
2019-11-05 22:26 ` [PATCH v4 03/17] platform/mfd:iio: cros_ec: Register sensor through sensorhub Gwendal Grignou
2019-11-10 12:13   ` Jonathan Cameron
2019-11-11  9:25     ` Enric Balletbo i Serra
2019-11-11 11:43   ` Lee Jones
2019-11-05 22:26 ` [PATCH v4 04/17] platform: chrome: cros-ec: record event timestamp in the hard irq Gwendal Grignou
2019-11-10 12:16   ` Jonathan Cameron
2019-11-11  9:27     ` Enric Balletbo i Serra
2019-11-05 22:26 ` [PATCH v4 05/17] platform: chrome: cros_ec: Do not attempt to register a non-positive IRQ number Gwendal Grignou
2019-11-10 12:17   ` Jonathan Cameron
2019-11-11  9:29     ` Enric Balletbo i Serra
2019-11-14  0:58       ` Gwendal Grignou
2019-11-05 22:26 ` [PATCH v4 06/17] platform: chrome: cros_ec: handle MKBP more events flag Gwendal Grignou
2019-11-10 12:28   ` Jonathan Cameron
2019-11-11  9:30     ` Enric Balletbo i Serra
2019-11-05 22:26 ` [PATCH v4 07/17] Revert "Input: cros_ec_keyb - add back missing mask for event_type" Gwendal Grignou
2019-11-11  9:20   ` Enric Balletbo i Serra
2019-11-11 19:23     ` Dmitry Torokhov
2019-11-05 22:26 ` [PATCH v4 08/17] Revert "Input: cros_ec_keyb: mask out extra flags in event_type" Gwendal Grignou
2019-11-11  9:20   ` Enric Balletbo i Serra
2019-11-11 19:23     ` Dmitry Torokhov
2019-11-05 22:26 ` [PATCH v4 09/17] platform: chrome: sensorhub: Add FIFO support Gwendal Grignou
2019-11-06 21:13   ` Gwendal Grignou
2019-11-10 12:54     ` Jonathan Cameron
2019-11-14  1:01       ` Gwendal Grignou
2019-11-05 22:26 ` [PATCH v4 10/17] platform: chrome: sensorhub: Add code to spread timestmap Gwendal Grignou
2019-11-10 12:57   ` Jonathan Cameron
2019-11-05 22:26 ` [PATCH v4 11/17] platform: chrome: sensorhub: Add median filter Gwendal Grignou
2019-11-10 13:07   ` Jonathan Cameron
2019-11-05 22:26 ` [PATCH v4 12/17] iio: cros_ec: Move function description to .c file Gwendal Grignou
2019-11-10 13:08   ` Jonathan Cameron
2019-11-11  9:35     ` Enric Balletbo i Serra
2019-11-05 22:26 ` [PATCH v4 13/17] iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO Gwendal Grignou
2019-11-10 13:17   ` Jonathan Cameron
2019-11-14 18:17     ` Gwendal Grignou [this message]
2019-11-05 22:26 ` [PATCH v4 14/17] iio: cros_ec: Remove pm function Gwendal Grignou
2019-11-10 13:18   ` Jonathan Cameron
2019-11-11  9:37     ` Enric Balletbo i Serra
2019-11-05 22:26 ` [PATCH v4 15/17] iio: cros_ec: Expose hwfifo_timeout Gwendal Grignou
2019-11-10 13:21   ` Jonathan Cameron
2019-11-05 22:26 ` [PATCH v4 16/17] iio: cros_ec: Report hwfifo_watermark_max Gwendal Grignou
2019-11-10 13:22   ` Jonathan Cameron
2019-11-05 22:26 ` [PATCH v4 17/17] iio: cros_ec: Use Hertz as unit for sampling frequency Gwendal Grignou
2019-11-10 13:24   ` Jonathan Cameron

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=CAPUE2uv_9YPsX_evtb4HSWHFuvWbLVGZjreWyJyeKVwTSh24Jw@mail.gmail.com \
    --to=gwendal@chromium.org \
    --cc=bleung@chromium.org \
    --cc=briannorris@chromium.org \
    --cc=dianders@chromium.org \
    --cc=enric.balletbo@collabora.com \
    --cc=fabien.lahoudere@collabora.com \
    --cc=groeck@chromium.org \
    --cc=jic23@kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=lee.jones@linaro.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmeerw@pmeerw.net \
    /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.