iio:core: introduce timestamping clock selection
Subsystems (10)
v3 cover iio:core: introduce timestamping clock selection
IIO timestamping clock selection support based on the following principles :
* selected timestamping clock is a per-device attribute which the userspace may access through a sysfs file ;
* a single reference clock is used for both buffered samples and events of a given device at the same time ;
* userspace may choose amongst the following subset of available POSIX clocks:
CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME and CLOCK_TAI ;
* sample and event timestamps consistency with respect to clock changes is ensured by rejecting the ability to select a new clock as long as an events chrdev is opened or a buffered samples channel is enabled for a given device.
* no in-kernel API support since :
* consumers work synchronously in direct mode, i.e. timestamping may be
peformed using traditional kernel time keeping ;
* any given device can only feed a single timestamping channel to all consumers.
Changes since v1:
* isolate clock setup from sysfs
* rename timestamping clock sysfs entry to "timestamp_clock"
* make the "timestamp_clock" file content a self-describing string
* merge all 3 patches into a single one
* cosmetics
* rebase onto IIO testing branch
Changes since v2:
* rename timestamping clock sysfs entry to "current_timestamp_clock" to allow a futur refinement exposing available clocks through a "timestamp_clock_available" sysfs entry
* rename clock ids (remove "CLOCK_" prefix + lower case)
* checkpatch'ed
* rebase onto IIO testing branch
Regards.
Gregor Boirie (1):
iio:core: timestamping clock selection support
Documentation/ABI/testing/sysfs-bus-iio | 7 + Documentation/DocBook/iio.tmpl | 2 +- drivers/iio/accel/bma180.c | 2 +- drivers/iio/accel/bmc150-accel-core.c | 4 +- drivers/iio/accel/kxcjk-1013.c | 2 +- drivers/iio/accel/mma7455_core.c | 3 +- drivers/iio/accel/mma8452.c | 4 +- drivers/iio/accel/mma9551.c | 2 +- drivers/iio/accel/mma9553.c | 2 +- drivers/iio/adc/ad7291.c | 2 +- drivers/iio/adc/ad7298.c | 2 +- drivers/iio/adc/ad7476.c | 2 +- drivers/iio/adc/ad7887.c | 2 +- drivers/iio/adc/ad7923.c | 2 +- drivers/iio/adc/ad799x.c | 4 +- drivers/iio/adc/cc10001_adc.c | 2 +- drivers/iio/adc/hi8435.c | 2 +- drivers/iio/adc/ina2xx-adc.c | 6 +- drivers/iio/adc/max1363.c | 5 +- drivers/iio/adc/ti-ads1015.c | 3 +- drivers/iio/adc/vf610_adc.c | 3 +- drivers/iio/adc/xilinx-xadc-events.c | 4 +- drivers/iio/chemical/atlas-ph-sensor.c | 2 +- drivers/iio/dac/ad5421.c | 6 +- drivers/iio/dac/ad5504.c | 2 +- drivers/iio/dummy/iio_simple_dummy_buffer.c | 3 +- drivers/iio/dummy/iio_simple_dummy_events.c | 2 +- drivers/iio/gyro/bmg160_core.c | 30 ++-- drivers/iio/humidity/dht11.c | 16 +- drivers/iio/iio_core.h | 3 + drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 +- drivers/iio/industrialio-core.c | 179 +++++++++++++++++++++- drivers/iio/industrialio-event.c | 19 ++- drivers/iio/industrialio-trigger.c | 2 +- drivers/iio/light/acpi-als.c | 2 +- drivers/iio/light/adjd_s311.c | 2 +- drivers/iio/light/apds9300.c | 2 +- drivers/iio/light/apds9960.c | 4 +- drivers/iio/light/cm36651.c | 2 +- drivers/iio/light/gp2ap020a00f.c | 8 +- drivers/iio/light/isl29125.c | 2 +- drivers/iio/light/lm3533-als.c | 2 +- drivers/iio/light/ltr501.c | 7 +- drivers/iio/light/opt3001.c | 4 +- drivers/iio/light/stk3310.c | 2 +- drivers/iio/light/tcs3414.c | 2 +- drivers/iio/light/tcs3472.c | 2 +- drivers/iio/light/tsl2563.c | 2 +- drivers/iio/light/us5182d.c | 2 +- drivers/iio/magnetometer/hmc5843_core.c | 2 +- drivers/iio/magnetometer/mag3110.c | 2 +- drivers/iio/pressure/mpl3115.c | 2 +- drivers/iio/pressure/ms5611_core.c | 3 +- drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 2 +- drivers/iio/proximity/sx9500.c | 4 +- drivers/staging/iio/accel/lis3l02dq_core.c | 2 +- drivers/staging/iio/accel/sca3000_core.c | 2 +- drivers/staging/iio/adc/ad7280a.c | 8 +- drivers/staging/iio/adc/ad7606_ring.c | 3 +- drivers/staging/iio/adc/ad7816.c | 3 +- drivers/staging/iio/addac/adt7316.c | 4 +- drivers/staging/iio/cdc/ad7150.c | 2 +- drivers/staging/iio/light/tsl2x7x_core.c | 2 +- include/linux/iio/iio.h | 22 ++- 64 files changed, 326 insertions(+), 115 deletions(-)
Signature · 1 line
2.1.4
PATCH v3 1/1 iio:core: timestamping clock selection support
Adds a new per-device sysfs attribute "current_timestamp_clock" to allow userspace to select a particular POSIX clock for buffered samples and events timestamping.
Following clocks, as listed in clock_gettime(2), are supported:CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME and CLOCK_TAI.
--- Documentation/ABI/testing/sysfs-bus-iio | 7 + Documentation/DocBook/iio.tmpl | 2 +- drivers/iio/accel/bma180.c | 2 +- drivers/iio/accel/bmc150-accel-core.c | 4 +- drivers/iio/accel/kxcjk-1013.c | 2 +- drivers/iio/accel/mma7455_core.c | 3 +- drivers/iio/accel/mma8452.c | 4 +- drivers/iio/accel/mma9551.c | 2 +- drivers/iio/accel/mma9553.c | 2 +- drivers/iio/adc/ad7291.c | 2 +- drivers/iio/adc/ad7298.c | 2 +- drivers/iio/adc/ad7476.c | 2 +- drivers/iio/adc/ad7887.c | 2 +- drivers/iio/adc/ad7923.c | 2 +- drivers/iio/adc/ad799x.c | 4 +- drivers/iio/adc/cc10001_adc.c | 2 +- drivers/iio/adc/hi8435.c | 2 +- drivers/iio/adc/ina2xx-adc.c | 6 +- drivers/iio/adc/max1363.c | 5 +- drivers/iio/adc/ti-ads1015.c | 3 +- drivers/iio/adc/vf610_adc.c | 3 +- drivers/iio/adc/xilinx-xadc-events.c | 4 +- drivers/iio/chemical/atlas-ph-sensor.c | 2 +- drivers/iio/dac/ad5421.c | 6 +- drivers/iio/dac/ad5504.c | 2 +- drivers/iio/dummy/iio_simple_dummy_buffer.c | 3 +- drivers/iio/dummy/iio_simple_dummy_events.c | 2 +- drivers/iio/gyro/bmg160_core.c | 30 ++-- drivers/iio/humidity/dht11.c | 16 +- drivers/iio/iio_core.h | 3 + drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 +- drivers/iio/industrialio-core.c | 179 +++++++++++++++++++++- drivers/iio/industrialio-event.c | 19 ++- drivers/iio/industrialio-trigger.c | 2 +- drivers/iio/light/acpi-als.c | 2 +- drivers/iio/light/adjd_s311.c | 2 +- drivers/iio/light/apds9300.c | 2 +- drivers/iio/light/apds9960.c | 4 +- drivers/iio/light/cm36651.c | 2 +- drivers/iio/light/gp2ap020a00f.c | 8 +- drivers/iio/light/isl29125.c | 2 +- drivers/iio/light/lm3533-als.c | 2 +- drivers/iio/light/ltr501.c | 7 +- drivers/iio/light/opt3001.c | 4 +- drivers/iio/light/stk3310.c | 2 +- drivers/iio/light/tcs3414.c | 2 +- drivers/iio/light/tcs3472.c | 2 +- drivers/iio/light/tsl2563.c | 2 +- drivers/iio/light/us5182d.c | 2 +- drivers/iio/magnetometer/hmc5843_core.c | 2 +- drivers/iio/magnetometer/mag3110.c | 2 +- drivers/iio/pressure/mpl3115.c | 2 +- drivers/iio/pressure/ms5611_core.c | 3 +- drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 2 +- drivers/iio/proximity/sx9500.c | 4 +- drivers/staging/iio/accel/lis3l02dq_core.c | 2 +- drivers/staging/iio/accel/sca3000_core.c | 2 +- drivers/staging/iio/adc/ad7280a.c | 8 +- drivers/staging/iio/adc/ad7606_ring.c | 3 +- drivers/staging/iio/adc/ad7816.c | 3 +- drivers/staging/iio/addac/adt7316.c | 4 +- drivers/staging/iio/cdc/ad7150.c | 2 +- drivers/staging/iio/light/tsl2x7x_core.c | 2 +- include/linux/iio/iio.h | 22 ++- 64 files changed, 326 insertions(+), 115 deletions(-)
Documentation/ABI/testing/sysfs-bus-iio +7 -0
@@ -32,6 +32,13 @@ Description: Description of the physical chip / device for device X. Typically a part number. +What: /sys/bus/iio/devices/iio:deviceX/timestamp_clock +KernelVersion: 4.5 +Contact: [email protected] +Description: + String identifying current posix clock used to timestamp + buffered samples and events for device X. + What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency What: /sys/bus/iio/devices/triggerX/sampling_frequency
Documentation/DocBook/iio.tmpl +1 -1
@@ -594,7 +594,7 @@ irqreturn_t sensor_iio_pollfunc(int irq, void *p) { - pf->timestamp = iio_get_time_ns(); + pf->timestamp = iio_get_time_ns((struct indio_dev *)p); return IRQ_WAKE_THREAD; }
drivers/iio/accel/bma180.c +1 -1
@@ -654,7 +654,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)struct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct bma180_data *data =iio_priv (indio_dev); -int64_t time_ns =iio_get_time_ns (); +s64 time_ns =iio_get_time_ns (indio_dev);int bit, ret, i =0 ;mutex_lock (&data->mutex);
drivers/iio/accel/bmc150-accel-core.c +2 -2
@@ -892,7 +892,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,*/ if (!irq) { data->old_timestamp = data->timestamp; - data->timestamp =iio_get_time_ns (); + data->timestamp =iio_get_time_ns (indio_dev); }/*
@@ -1295,7 +1295,7 @@ static irqreturn_t bmc150_accel_irq_handler(int irq, void *private)int i; data->old_timestamp = data->timestamp; - data->timestamp =iio_get_time_ns (); + data->timestamp =iio_get_time_ns (indio_dev);for (i =0 ; i <BMC150_ACCEL_TRIGGERS ; i++) {if (data->triggers[i].enabled) {
drivers/iio/accel/kxcjk-1013.c +1 -1
@@ -1131,7 +1131,7 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)struct iio_dev *indio_dev = private;struct kxcjk1013_data *data =iio_priv (indio_dev); - data->timestamp =iio_get_time_ns (); + data->timestamp =iio_get_time_ns (indio_dev);if (data->dready_trigger_on)iio_trigger_poll (data->dready_trig);
drivers/iio/accel/mma7455_core.c +2 -1
@@ -97,7 +97,8 @@ static irqreturn_t mma7455_trigger_handler(int irq, void *p)if (ret) goto done; -iio_push_to_buffers_with_timestamp (indio_dev, buf,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, buf, +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/accel/mma8452.c +2 -2
@@ -718,7 +718,7 @@ static int mma8452_write_event_config(struct iio_dev *indio_dev,static void mma8452_transient_interrupt (struct iio_dev *indio_dev) {struct mma8452_data *data =iio_priv (indio_dev); -s64 ts =iio_get_time_ns (); +s64 ts =iio_get_time_ns (indio_dev);int src; src =i2c_smbus_read_byte_data (data->client, data->chip_info->ev_src);
@@ -798,7 +798,7 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p) goto done;iio_push_to_buffers_with_timestamp (indio_dev, buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/accel/mma9551.c +1 -1
@@ -391,7 +391,7 @@ static irqreturn_t mma9551_event_handler(int irq, void *private)iio_push_event (indio_dev,IIO_MOD_EVENT_CODE (IIO_INCLI ,0 , (mma_axis +1 ),IIO_EV_TYPE_ROC ,IIO_EV_DIR_RISING ), -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); out:mutex_unlock (&data->mutex);
drivers/iio/accel/mma9553.c +1 -1
@@ -1002,7 +1002,7 @@ static irqreturn_t mma9553_irq_handler(int irq, void *private)struct iio_dev *indio_dev = private;struct mma9553_data *data =iio_priv (indio_dev); - data->timestamp =iio_get_time_ns (); + data->timestamp =iio_get_time_ns (indio_dev);/* * Since we only configure the interrupt pin when an * event is enabled, we are sure we have at least
drivers/iio/adc/ad7291.c +1 -1
@@ -115,7 +115,7 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)u16 t_status, v_status;u16 command;int i; -s64 timestamp =iio_get_time_ns (); +s64 timestamp =iio_get_time_ns (indio_dev);if (ad7291_i2c_read (chip,AD7291_T_ALERT_STATUS , &t_status))return IRQ_HANDLED ;
drivers/iio/adc/ad7298.c +1 -1
@@ -163,7 +163,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) goto done;iio_push_to_buffers_with_timestamp (indio_dev, st->rx_buf, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/adc/ad7476.c +1 -1
@@ -70,7 +70,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) goto done;iio_push_to_buffers_with_timestamp (indio_dev, st->data, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/adc/ad7887.c +1 -1
@@ -122,7 +122,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) goto done;iio_push_to_buffers_with_timestamp (indio_dev, st->data, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/adc/ad7923.c +1 -1
@@ -181,7 +181,7 @@ static irqreturn_t ad7923_trigger_handler(int irq, void *p) goto done;iio_push_to_buffers_with_timestamp (indio_dev, st->rx_buf, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/adc/ad799x.c +2 -2
@@ -212,7 +212,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) goto out;iio_push_to_buffers_with_timestamp (indio_dev, st->rx_buf, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); out:iio_trigger_notify_done (indio_dev->trig);
@@ -508,7 +508,7 @@ static irqreturn_t ad799x_event_handler(int irq, void *private) (i >> 1), IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } done:
drivers/iio/adc/cc10001_adc.c +1 -1
@@ -186,7 +186,7 @@ done:if (!sample_invalid)iio_push_to_buffers_with_timestamp (indio_dev, data, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev));iio_trigger_notify_done (indio_dev->trig);return IRQ_HANDLED ;
drivers/iio/adc/hi8435.c +1 -1
@@ -400,7 +400,7 @@ static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val)iio_push_event (idev,IIO_UNMOD_EVENT_CODE (IIO_VOLTAGE , i,IIO_EV_TYPE_THRESH , dir), -iio_get_time_ns ()); +iio_get_time_ns (idev)); } }
drivers/iio/adc/ina2xx-adc.c +3 -3
@@ -442,7 +442,7 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)s64 time_a, time_b;unsigned int alert; - time_a =iio_get_time_ns (); + time_a =iio_get_time_ns (indio_dev);/* * Because the timer thread and the chip conversion clock
@@ -483,7 +483,7 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) data[i++] = val; } - time_b =iio_get_time_ns (); + time_b =iio_get_time_ns (indio_dev);iio_push_to_buffers_with_timestamp (indio_dev, (unsigned int *)data, time_a);
@@ -537,7 +537,7 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev)trace_printk ("Expected work period: %u us\n" , sampling_us);trace_printk ("Async readout mode: %d\n" , chip->allow_async_readout); - chip->prev_ns =iio_get_time_ns (); + chip->prev_ns =iio_get_time_ns (indio_dev); chip->task = kthread_run(ina2xx_capture_thread, (void *)indio_dev, "%s:%d-%uus", indio_dev->name, indio_dev->id,
drivers/iio/adc/max1363.c +3 -2
@@ -788,7 +788,7 @@ static irqreturn_t max1363_event_handler(int irq, void *private) {struct iio_dev *indio_dev = private;struct max1363_state *st =iio_priv (indio_dev); -s64 timestamp =iio_get_time_ns (); +s64 timestamp =iio_get_time_ns (indio_dev);unsigned long mask, loc;u8 rx;u8 tx[2 ] = { st->setupbyte,
@@ -1506,7 +1506,8 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)if (b_sent <0 ) goto done_free; -iio_push_to_buffers_with_timestamp (indio_dev, rxbuf,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, rxbuf, +iio_get_time_ns (indio_dev)); done_free:kfree (rxbuf);
drivers/iio/adc/ti-ads1015.c +2 -1
@@ -225,7 +225,8 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) buf[0 ] = res;mutex_unlock (&data->lock); -iio_push_to_buffers_with_timestamp (indio_dev, buf,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, buf, +iio_get_time_ns (indio_dev)); err:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/adc/vf610_adc.c +2 -1
@@ -594,7 +594,8 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id)if (iio_buffer_enabled (indio_dev)) { info->buffer[0 ] = info->value;iio_push_to_buffers_with_timestamp (indio_dev, - info->buffer,iio_get_time_ns ()); + info->buffer, +iio_get_time_ns (indio_dev));iio_trigger_notify_done (indio_dev->trig); }else complete (&info->completion);
drivers/iio/adc/xilinx-xadc-events.c +2 -2
@@ -46,7 +46,7 @@ static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event)iio_push_event (indio_dev,IIO_UNMOD_EVENT_CODE (chan->type, chan->channel,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_RISING ), -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); }else {/* * For other channels we don't know whether it is a upper or
@@ -56,7 +56,7 @@ static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event)iio_push_event (indio_dev,IIO_UNMOD_EVENT_CODE (chan->type, chan->channel,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_EITHER ), -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); } }
drivers/iio/chemical/atlas-ph-sensor.c +1 -1
@@ -183,7 +183,7 @@ static irqreturn_t atlas_trigger_handler(int irq, void *private)if (!ret)iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev));iio_trigger_notify_done (indio_dev->trig);
drivers/iio/dac/ad5421.c +3 -3
@@ -242,7 +242,7 @@ static irqreturn_t ad5421_fault_handler(int irq, void *data) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); }if (events &AD5421_FAULT_UNDER_CURRENT ) {
@@ -251,7 +251,7 @@ static irqreturn_t ad5421_fault_handler(int irq, void *data) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); }if (events &AD5421_FAULT_TEMP_OVER_140 ) {
@@ -260,7 +260,7 @@ static irqreturn_t ad5421_fault_handler(int irq, void *data) 0, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } old_fault = fault;
drivers/iio/dac/ad5504.c +1 -1
@@ -223,7 +223,7 @@ static irqreturn_t ad5504_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns((struct iio_dev *)private));return IRQ_HANDLED ; }
drivers/iio/dummy/iio_simple_dummy_buffer.c +2 -1
@@ -85,7 +85,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) } } -iio_push_to_buffers_with_timestamp (indio_dev, data,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, data, +iio_get_time_ns (indio_dev));kfree (data);
drivers/iio/dummy/iio_simple_dummy_events.c +1 -1
@@ -158,7 +158,7 @@ static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)struct iio_dev *indio_dev = private;struct iio_dummy_state *st =iio_priv (indio_dev); - st->event_timestamp =iio_get_time_ns (); + st->event_timestamp =iio_get_time_ns (indio_dev);return IRQ_WAKE_THREAD ; }
drivers/iio/gyro/bmg160_core.c +15 -15
@@ -884,25 +884,25 @@ static irqreturn_t bmg160_event_handler(int irq, void *private)if (val &BMG160_ANY_MOTION_BIT_X )iio_push_event (indio_dev,IIO_MOD_EVENT_CODE (IIO_ANGL_VEL , -0 , -IIO_MOD_X , -IIO_EV_TYPE_ROC , - dir), -iio_get_time_ns ()); +0 , +IIO_MOD_X , +IIO_EV_TYPE_ROC , + dir), +iio_get_time_ns (indio_dev));if (val &BMG160_ANY_MOTION_BIT_Y )iio_push_event (indio_dev,IIO_MOD_EVENT_CODE (IIO_ANGL_VEL , -0 , -IIO_MOD_Y , -IIO_EV_TYPE_ROC , - dir), -iio_get_time_ns ()); +0 , +IIO_MOD_Y , +IIO_EV_TYPE_ROC , + dir), +iio_get_time_ns (indio_dev));if (val &BMG160_ANY_MOTION_BIT_Z )iio_push_event (indio_dev,IIO_MOD_EVENT_CODE (IIO_ANGL_VEL , -0 , -IIO_MOD_Z , -IIO_EV_TYPE_ROC , - dir), -iio_get_time_ns ()); +0 , +IIO_MOD_Z , +IIO_EV_TYPE_ROC , + dir), +iio_get_time_ns (indio_dev)); ack_intr_status:if (!data->dready_trigger_on) {
drivers/iio/humidity/dht11.c +9 -7
@@ -110,7 +110,8 @@ static unsigned char dht11_decode_byte(char *bits)return ret; } -static int dht11_decode (struct dht11 *dht11,int offset) +static int dht11_decode (const struct iio_dev *iio_dev,struct dht11 *dht11, +int offset) {int i, t;char bits[DHT11_BITS_PER_READ ];
@@ -133,7 +134,7 @@ static int dht11_decode(struct dht11 *dht11, int offset)if (((hum_int + hum_dec + temp_int + temp_dec) &0xff ) != checksum)return -EIO ; - dht11->timestamp =ktime_get_boot_ns (); + dht11->timestamp =iio_get_time_ns (iio_dev);if (hum_int <20 ) {/* DHT22 */ dht11->temperature = (((temp_int &0x7f ) <<8 ) + temp_dec) * ((temp_int &0x80 ) ?-100 :100 );
@@ -161,7 +162,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)/* TODO: Consider making the handler safe for IRQ sharing */ if (dht11->num_edges <DHT11_EDGES_PER_READ && dht11->num_edges >=0 ) { - dht11->edges[dht11->num_edges].ts =ktime_get_boot_ns (); + dht11->edges[dht11->num_edges].ts =iio_get_time_ns (iio); dht11->edges[dht11->num_edges++].value =gpio_get_value (dht11->gpio);
@@ -180,8 +181,9 @@ static int dht11_read_raw(struct iio_dev *iio_dev,int ret, timeres, offset;mutex_lock (&dht11->lock); -if (dht11->timestamp +DHT11_DATA_VALID_TIME <ktime_get_boot_ns ()) { - timeres =ktime_get_resolution_ns (); +if (dht11->timestamp +DHT11_DATA_VALID_TIME < +iio_get_time_ns (iio_dev)) { + timeres =iio_get_time_res (iio_dev);if (timeres >DHT11_MIN_TIMERES ) {dev_err (dht11->dev,"timeresolution %dns too low\n" , timeres);
@@ -231,7 +233,7 @@ static int dht11_read_raw(struct iio_dev *iio_dev, offset =DHT11_EDGES_PREAMBLE + dht11->num_edges -DHT11_EDGES_PER_READ ;for (; offset >=0 ; --offset) { - ret =dht11_decode (dht11, offset); + ret =dht11_decode (iio_dev, dht11, offset);if (!ret)break ; }
@@ -302,7 +304,7 @@ static int dht11_probe(struct platform_device *pdev)return -EINVAL ; } - dht11->timestamp =ktime_get_boot_ns () -DHT11_DATA_VALID_TIME -1 ; + dht11->timestamp =iio_get_time_ns (iio) -DHT11_DATA_VALID_TIME -1 ; dht11->num_edges =-1 ;platform_set_drvdata (pdev, iio);
drivers/iio/iio_core.h +3 -0
@@ -79,4 +79,7 @@ void iio_device_unregister_eventset(struct iio_dev *indio_dev);void iio_device_wakeup_eventset (struct iio_dev *indio_dev);int iio_event_getfd (struct iio_dev *indio_dev); +struct iio_event_interface ; +bool iio_event_enabled (const struct iio_event_interface *ev_int); +#endif
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +1 -1
@@ -107,7 +107,7 @@ irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)struct inv_mpu6050_state *st =iio_priv (indio_dev);s64 timestamp; - timestamp =iio_get_time_ns (); + timestamp =iio_get_time_ns (indio_dev);kfifo_in_spinlocked (&st->timestamps, ×tamp,1 , &st->time_stamp_lock);
drivers/iio/industrialio-core.c +175 -4
214 lines not on this page · raw message
drivers/iio/industrialio-event.c +16 -3
@@ -44,6 +44,11 @@ struct iio_event_interface {struct mutex read_lock; }; +bool iio_event_enabled (const struct iio_event_interface *ev_int) +{ +return !!test_bit (IIO_BUSY_BIT_POS , &ev_int->flags); +} +/** * iio_push_event() - try to add event to the list for userspace reading * @indio_dev: IIO device structure
@@ -60,7 +65,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)int copied;/* Does anyone care? */ -if (test_bit (IIO_BUSY_BIT_POS , &ev_int->flags)) { +if (iio_event_enabled (ev_int)) { ev.id = ev_code; ev.timestamp = timestamp;
@@ -180,8 +185,14 @@ int iio_event_getfd(struct iio_dev *indio_dev)if (ev_int ==NULL )return -ENODEV ; -if (test_and_set_bit (IIO_BUSY_BIT_POS , &ev_int->flags)) -return -EBUSY ; + fd =mutex_lock_interruptible (&indio_dev->mlock); +if (fd) +return fd; + +if (test_and_set_bit (IIO_BUSY_BIT_POS , &ev_int->flags)) { + fd = -EBUSY ; + goto unlock; + }iio_device_get (indio_dev);
@@ -194,6 +205,8 @@ int iio_event_getfd(struct iio_dev *indio_dev)kfifo_reset_out (&ev_int->det_events); } +unlock: +mutex_unlock (&indio_dev->mlock);return fd; }
drivers/iio/industrialio-trigger.c +1 -1
@@ -251,7 +251,7 @@ static int iio_trigger_detach_poll_func(struct iio_trigger *trig,irqreturn_t iio_pollfunc_store_time (int irq,void *p) {struct iio_poll_func *pf = p; - pf->timestamp =iio_get_time_ns (); + pf->timestamp =iio_get_time_ns (pf->indio_dev);return IRQ_WAKE_THREAD ; }EXPORT_SYMBOL (iio_pollfunc_store_time);
drivers/iio/light/acpi-als.c +1 -1
@@ -118,7 +118,7 @@ static void acpi_als_notify(struct acpi_device *device, u32 event)struct iio_dev *indio_dev =acpi_driver_data (device);struct acpi_als *als =iio_priv (indio_dev);s32 *buffer = als->evt_buffer; -s64 time_ns =iio_get_time_ns (); +s64 time_ns =iio_get_time_ns (indio_dev);s32 val;int ret;
drivers/iio/light/adjd_s311.c +1 -1
@@ -118,7 +118,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)struct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct adjd_s311_data *data =iio_priv (indio_dev); -s64 time_ns =iio_get_time_ns (); +s64 time_ns =iio_get_time_ns (indio_dev);int i, j =0 ;int ret =adjd_s311_req_data (indio_dev);
drivers/iio/light/apds9300.c +1 -1
@@ -396,7 +396,7 @@ static irqreturn_t apds9300_interrupt_handler(int irq, void *private)IIO_UNMOD_EVENT_CODE (IIO_INTENSITY ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_EITHER ), - iio_get_time_ns()); + iio_get_time_ns(dev_info));apds9300_clear_intr (data);
drivers/iio/light/apds9960.c +2 -2
@@ -801,7 +801,7 @@ static irqreturn_t apds9960_interrupt_handler(int irq, void *private)IIO_UNMOD_EVENT_CODE (IIO_INTENSITY ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_EITHER ), - iio_get_time_ns()); + iio_get_time_ns(indio_dev));regmap_write (data->regmap,APDS9960_REG_CICLEAR ,1 ); }
@@ -810,7 +810,7 @@ static irqreturn_t apds9960_interrupt_handler(int irq, void *private)IIO_UNMOD_EVENT_CODE (IIO_PROXIMITY ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_EITHER ), - iio_get_time_ns()); + iio_get_time_ns(indio_dev));regmap_write (data->regmap,APDS9960_REG_PICLEAR ,1 ); }
drivers/iio/light/cm36651.c +1 -1
@@ -268,7 +268,7 @@ static irqreturn_t cm36651_irq_handler(int irq, void *data)CM36651_CMD_READ_RAW_PROXIMITY , IIO_EV_TYPE_THRESH, ev_dir); -iio_push_event (indio_dev, ev_code,iio_get_time_ns ()); +iio_push_event (indio_dev, ev_code,iio_get_time_ns (indio_dev));return IRQ_HANDLED ; }
drivers/iio/light/gp2ap020a00f.c +4 -4
@@ -851,7 +851,7 @@ static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data) GP2AP020A00F_SCAN_MODE_PROXIMITY, IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); }else { iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(
@@ -859,7 +859,7 @@ static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data) GP2AP020A00F_SCAN_MODE_PROXIMITY, IIO_EV_TYPE_ROC, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } }
@@ -925,7 +925,7 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data) IIO_MOD_LIGHT_CLEAR, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); }if (test_bit (GP2AP020A00F_FLAG_ALS_FALLING_EV , &priv->flags)) {
@@ -939,7 +939,7 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data) IIO_MOD_LIGHT_CLEAR, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } }
drivers/iio/light/isl29125.c +1 -1
@@ -189,7 +189,7 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p) }iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/light/lm3533-als.c +1 -1
@@ -267,7 +267,7 @@ static irqreturn_t lm3533_als_isr(int irq, void *dev_id) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); out:return IRQ_HANDLED ; }
drivers/iio/light/ltr501.c +4 -3
@@ -1256,7 +1256,8 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p) buf[j++] = psdata <R501_PS_DATA_MASK ; } -iio_push_to_buffers_with_timestamp (indio_dev, buf,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, buf, +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
@@ -1282,14 +1283,14 @@ static irqreturn_t ltr501_interrupt_handler(int irq, void *private)IIO_UNMOD_EVENT_CODE (IIO_INTENSITY ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_EITHER ), - iio_get_time_ns()); + iio_get_time_ns(indio_dev));if (status <R501_STATUS_PS_INTR )iio_push_event (indio_dev,IIO_UNMOD_EVENT_CODE (IIO_PROXIMITY ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_EITHER ), -iio_get_time_ns ()); +iio_get_time_ns (indio_dev));return IRQ_HANDLED ; }
drivers/iio/light/opt3001.c +2 -2
@@ -713,13 +713,13 @@ static irqreturn_t opt3001_irq(int irq, void *_iio)IIO_UNMOD_EVENT_CODE (IIO_LIGHT ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_RISING ), - iio_get_time_ns()); + iio_get_time_ns(iio));if (ret &OPT3001_CONFIGURATION_FL )iio_push_event (iio,IIO_UNMOD_EVENT_CODE (IIO_LIGHT ,0 ,IIO_EV_TYPE_THRESH ,IIO_EV_DIR_FALLING ), -iio_get_time_ns ()); +iio_get_time_ns (iio)); }else if (ret &OPT3001_CONFIGURATION_CRF ) { ret =i2c_smbus_read_word_swapped (opt->client,OPT3001_RESULT );if (ret <0 ) {
drivers/iio/light/stk3310.c +1 -1
@@ -529,7 +529,7 @@ static irqreturn_t stk3310_irq_handler(int irq, void *private)struct iio_dev *indio_dev = private;struct stk3310_data *data =iio_priv (indio_dev); - data->timestamp =iio_get_time_ns (); + data->timestamp =iio_get_time_ns (indio_dev);return IRQ_WAKE_THREAD ; }
drivers/iio/light/tcs3414.c +1 -1
@@ -217,7 +217,7 @@ static irqreturn_t tcs3414_trigger_handler(int irq, void *p) }iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/light/tcs3472.c +1 -1
@@ -204,7 +204,7 @@ static irqreturn_t tcs3472_trigger_handler(int irq, void *p) }iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/light/tsl2563.c +1 -1
@@ -630,7 +630,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(dev_info));/* clear the interrupt and push the event */ i2c_smbus_write_byte (chip->client,TSL2563_CMD |TSL2563_CLEARINT );
drivers/iio/light/us5182d.c +1 -1
@@ -833,7 +833,7 @@ static irqreturn_t us5182d_irq_thread_handler(int irq, void *private) dir = ret &US5182D_CFG0_PROX ?IIO_EV_DIR_RISING :IIO_EV_DIR_FALLING ; ev =IIO_UNMOD_EVENT_CODE (IIO_PROXIMITY ,1 ,IIO_EV_TYPE_THRESH , dir); -iio_push_event (indio_dev, ev,iio_get_time_ns ()); +iio_push_event (indio_dev, ev,iio_get_time_ns (indio_dev)); ret =i2c_smbus_write_byte_data (data->client,US5182D_REG_CFG0 , ret & ~US5182D_CFG0_PX_IRQ );
drivers/iio/magnetometer/hmc5843_core.c +1 -1
@@ -451,7 +451,7 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p) goto done;iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/magnetometer/mag3110.c +1 -1
@@ -261,7 +261,7 @@ static irqreturn_t mag3110_trigger_handler(int irq, void *p) }iio_push_to_buffers_with_timestamp (indio_dev, buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/pressure/mpl3115.c +1 -1
@@ -171,7 +171,7 @@ static irqreturn_t mpl3115_trigger_handler(int irq, void *p)mutex_unlock (&data->lock);iio_push_to_buffers_with_timestamp (indio_dev, buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); done:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/pressure/ms5611_core.c +2 -1
@@ -191,7 +191,8 @@ static irqreturn_t ms5611_trigger_handler(int irq, void *p)if (ret <0 ) goto err; -iio_push_to_buffers_with_timestamp (indio_dev, buf,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, buf, +iio_get_time_ns (indio_dev)); err:iio_trigger_notify_done (indio_dev->trig);
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +1 -1
@@ -244,7 +244,7 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private) ret =lidar_get_measurement (data, data->buffer);if (!ret) {iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); }else if (ret != -EINVAL ) {dev_err (&data->client->dev,"cannot read LIDAR measurement" ); }
drivers/iio/proximity/sx9500.c +2 -2
@@ -492,7 +492,7 @@ static void sx9500_push_events(struct iio_dev *indio_dev) dir = new_prox ?IIO_EV_DIR_FALLING :IIO_EV_DIR_RISING ; ev =IIO_UNMOD_EVENT_CODE (IIO_PROXIMITY , chan,IIO_EV_TYPE_THRESH , dir); -iio_push_event (indio_dev, ev,iio_get_time_ns ()); +iio_push_event (indio_dev, ev,iio_get_time_ns (indio_dev)); data->prox_stat[chan] = new_prox; } }
@@ -669,7 +669,7 @@ static irqreturn_t sx9500_trigger_handler(int irq, void *private) }iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, -iio_get_time_ns ()); +iio_get_time_ns (indio_dev)); out:mutex_unlock (&data->mutex);
drivers/staging/iio/accel/lis3l02dq_core.c +1 -1
@@ -451,7 +451,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)struct iio_dev *indio_dev = private;u8 t; -s64 timestamp =iio_get_time_ns (); +s64 timestamp =iio_get_time_ns (indio_dev); lis3l02dq_spi_read_reg_8(indio_dev, LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
drivers/staging/iio/accel/sca3000_core.c +1 -1
@@ -775,7 +775,7 @@ static irqreturn_t sca3000_event_handler(int irq, void *private)struct iio_dev *indio_dev = private;struct sca3000_state *st =iio_priv (indio_dev);int ret, val; -s64 last_timestamp =iio_get_time_ns (); +s64 last_timestamp =iio_get_time_ns (indio_dev);/* * Could lead if badly timed to an extra read of status reg,
drivers/staging/iio/adc/ad7280a.c +4 -4
@@ -705,7 +705,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) IIO_EV_DIR_RISING,IIO_EV_TYPE_THRESH , 0, 0, 0), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); else if (((channels[i] >> 11) & 0xFFF) <= st->cell_threshlow) iio_push_event(indio_dev,
@@ -715,7 +715,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) IIO_EV_DIR_FALLING, IIO_EV_TYPE_THRESH, 0, 0, 0), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); }else {if (((channels[i] >>11 ) &0xFFF ) >= st->aux_threshhigh) iio_push_event(indio_dev,
@@ -724,7 +724,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); else if (((channels[i] >> 11) & 0xFFF) <= st->aux_threshlow) iio_push_event(indio_dev,
@@ -733,7 +733,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } }
drivers/staging/iio/adc/ad7606_ring.c +2 -1
@@ -77,7 +77,8 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) goto done; } -iio_push_to_buffers_with_timestamp (indio_dev, buf,iio_get_time_ns ()); +iio_push_to_buffers_with_timestamp (indio_dev, buf, +iio_get_time_ns (indio_dev)); done:gpio_set_value (st->pdata->gpio_convst,0 );iio_trigger_notify_done (indio_dev->trig);
drivers/staging/iio/adc/ad7816.c +2 -1
@@ -253,7 +253,8 @@ static const struct attribute_group ad7816_attribute_group = {static irqreturn_t ad7816_event_handler (int irq,void *private) { -iio_push_event (private,IIO_EVENT_CODE_AD7816_OTI ,iio_get_time_ns ()); +iio_push_event (private,IIO_EVENT_CODE_AD7816_OTI , +iio_get_time_ns ((struct iio_dev *)private));return IRQ_HANDLED ; }
drivers/staging/iio/addac/adt7316.c +2 -2
@@ -1755,7 +1755,7 @@ static irqreturn_t adt7316_event_handler(int irq, void *private)if ((chip->id &ID_FAMILY_MASK ) !=ID_ADT75XX ) stat1 &=0x1F ; - time =iio_get_time_ns (); + time =iio_get_time_ns (indio_dev);if (stat1 &BIT (0 )) iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
@@ -1807,7 +1807,7 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); }return IRQ_HANDLED ;
drivers/staging/iio/cdc/ad7150.c +1 -1
@@ -493,7 +493,7 @@ static irqreturn_t ad7150_event_handler(int irq, void *private)struct iio_dev *indio_dev = private;struct ad7150_chip_info *chip =iio_priv (indio_dev);u8 int_status; -s64 timestamp =iio_get_time_ns (); +s64 timestamp =iio_get_time_ns (indio_dev);int ret; ret =i2c_smbus_read_byte_data (chip->client,AD7150_STATUS );
drivers/staging/iio/light/tsl2x7x_core.c +1 -1
@@ -1524,7 +1524,7 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) {struct iio_dev *indio_dev = private;struct tsl2X7X_chip *chip =iio_priv (indio_dev); -s64 timestamp =iio_get_time_ns (); +s64 timestamp =iio_get_time_ns (indio_dev);int ret;u8 value;
include/linux/iio/iio.h +14 -8
@@ -281,13 +281,8 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, }, \ } -/** -* iio_get_time_ns() - utility function to get a time stamp for events etc -**/ -static inline s64 iio_get_time_ns (void ) -{ -return ktime_get_real_ns (); -} +s64 iio_get_time_ns (const struct iio_dev *indio_dev); +unsigned int iio_get_time_res (const struct iio_dev *indio_dev);/* Device operating modes */ #define INDIO_DIRECT_MODE 0x01
@@ -466,6 +461,7 @@ struct iio_buffer_setup_ops {* @chan_attr_group: [INTERN] group for all attrs in base directory * @name: [DRIVER] name of the device. * @info: [DRIVER] callbacks and constant info from driver +* @clock_id: [INTERN] timestamping clock posix identifier * @info_exist_lock: [INTERN] lock to prevent use during removal * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable
@@ -506,6 +502,7 @@ struct iio_dev {struct attribute_group chan_attr_group;const char *name;const struct iio_info *info; +clockid_t clock_id;struct mutex info_exist_lock;const struct iio_buffer_setup_ops *setup_ops;struct cdev chrdev;
@@ -532,7 +529,7 @@ extern struct bus_type iio_bus_type;/** * iio_device_put() - reference counted deallocation of struct device -* @indio_dev: IIO device structure containing the device +* @indio_dev: IIO device structure containing the device **/ static inline void iio_device_put (struct iio_dev *indio_dev) {
@@ -541,6 +538,15 @@ static inline void iio_device_put(struct iio_dev *indio_dev) }/** +* iio_device_get_clock() - Retrieve current timestamping clock for the device +* @indio_dev: IIO device structure containing the device +*/ +static inline clockid_t iio_device_get_clock (const struct iio_dev *indio_dev) +{ +return indio_dev->clock_id; +} + +/** * dev_to_iio_dev() - Get IIO device struct from a device struct * @dev: The device embedded in the IIO device *
Signature · 1 line
2.1.4
Re: [PATCH v3 1/1] iio:core: timestamping clock selection support
Hi Gregor!
Quoted 5 lines · Gregor Boirie
Adds a new per-device sysfs attribute "
current_timestamp_clock" to allow userspace to select a particular POSIX clock for buffered samples and events timestamping.drivers/iio/humidity/dht11.c | 16 +-
The dht11 driver only uses timestamps internally. AFAICT they are not exported to user space, so there is little point in making the clock selectable.
What's more important: The timestamps are used to decide the validity of cached values. I think your change introduces a bug where the driver could report outdated (or even uninitialized) values to user space.
(Actually we switched the driver to monotonic time just recently to fix this.)
HTH,
Harald
Quoted 60 lines
drivers/iio/humidity/dht11.c +9
-7@@ -110,7 +110,8 @@ static unsigned char dht11_decode_byte(char *bits)return ret; } -static int dht11_decode (struct dht11 *dht11,int offset) +static int dht11_decode (const struct iio_dev *iio_dev,struct dht11 *dht11, +int offset) {int i, t;char bits[DHT11_BITS_PER_READ ];@@ -133,7 +134,7 @@ static int dht11_decode(struct dht11 *dht11, int offset)if (((hum_int + hum_dec + temp_int + temp_dec) &0xff ) != checksum)return -EIO ; - dht11->timestamp =ktime_get_boot_ns (); + dht11->timestamp =iio_get_time_ns (iio_dev);if (hum_int <20 ) {/* DHT22 */ dht11->temperature = (((temp_int &0x7f ) <<8 ) + temp_dec) * ((temp_int &0x80 ) ?-100 :100 );@@ -161,7 +162,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)/* TODO: Consider making the handler safe for IRQ sharing */ if (dht11->num_edges <DHT11_EDGES_PER_READ && dht11->num_edges >=0 ) { - dht11->edges[dht11->num_edges].ts =ktime_get_boot_ns (); + dht11->edges[dht11->num_edges].ts =iio_get_time_ns (iio); dht11->edges[dht11->num_edges++].value =gpio_get_value (dht11->gpio);@@ -180,8 +181,9 @@ static int dht11_read_raw(struct iio_dev *iio_dev,int ret, timeres, offset;mutex_lock (&dht11->lock); -if (dht11->timestamp +DHT11_DATA_VALID_TIME <ktime_get_boot_ns ()) { - timeres =ktime_get_resolution_ns (); +if (dht11->timestamp +DHT11_DATA_VALID_TIME < +iio_get_time_ns (iio_dev)) { + timeres =iio_get_time_res (iio_dev);if (timeres >DHT11_MIN_TIMERES ) {dev_err (dht11->dev,"timeresolution %dns too low\n" , timeres);@@ -231,7 +233,7 @@ static int dht11_read_raw(struct iio_dev *iio_dev, offset =DHT11_EDGES_PREAMBLE + dht11->num_edges -DHT11_EDGES_PER_READ ;for (; offset >=0 ; --offset) { - ret =dht11_decode (dht11, offset); + ret =dht11_decode (iio_dev, dht11, offset);if (!ret)break ; }@@ -302,7 +304,7 @@ static int dht11_probe(struct platform_device *pdev)return -EINVAL ; } - dht11->timestamp =ktime_get_boot_ns () -DHT11_DATA_VALID_TIME -1 ; + dht11->timestamp =iio_get_time_ns (iio) -DHT11_DATA_VALID_TIME -1 ; dht11->num_edges =-1 ;
Re: [PATCH v3 1/1] iio:core: timestamping clock selection support
Quoted 1 line · Harald Geyer
Hi Gregor!
Hi Harald,
[snip]
Quoted 4 lines
drivers/iio/humidity/dht11.c | 16 +-The dht11 driver only uses timestamps internally. AFAICT they are not exported to user space, so there is little point in making the clock selectable.
Ok. It seems no timestamping channel / events is exposed anyway: I suppose it makes no sense to use the timestamping clock API in this case.
Quoted 7 lines
What's more important: The timestamps are used to decide the validity of cached values. I think your change introduces a bug where the driver could report outdated (or even uninitialized) values to user space.
(Actually we switched the driver to monotonic time just recently to fix this.)
I guess I should leave the dht11 driver completly untouched in my patch then. Thanks for the quick feedback :)
[snip]
Regards,
Grégor.