Commit 3ca4fb43 authored by Jean-Baptiste Maneyrol's avatar Jean-Baptiste Maneyrol Committed by Jonathan Cameron
Browse files

iio: imu: inv_mpu6050: replace timestamp fifo by generic timestamp



Using a fifo for storing timestamps is useless since the interrupt
is in one-shot mode, preventing the hard irq handler to be called
when the irq thread is running. Instead use the generic timestamp
function iio_pollfunc_store_time.

Signed-off-by: default avatarJean-Baptiste Maneyrol <jmaneyrol@invensense.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent c2c8406b
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@
#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/spinlock.h>
#include <linux/iio/iio.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
@@ -1003,7 +1001,7 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
	indio_dev->modes = INDIO_BUFFER_TRIGGERED;

	result = devm_iio_triggered_buffer_setup(dev, indio_dev,
						 inv_mpu6050_irq_handler,
						 iio_pollfunc_store_time,
						 inv_mpu6050_read_fifo,
						 NULL);
	if (result) {
@@ -1016,8 +1014,6 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
		return result;
	}

	INIT_KFIFO(st->timestamps);
	spin_lock_init(&st->time_stamp_lock);
	result = devm_iio_device_register(dev, indio_dev);
	if (result) {
		dev_err(dev, "IIO register fail %d\n", result);
+0 −10
Original line number Diff line number Diff line
@@ -12,8 +12,6 @@
*/
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/kfifo.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@@ -116,36 +114,30 @@ struct inv_mpu6050_hw {

/*
 *  struct inv_mpu6050_state - Driver state variables.
 *  @TIMESTAMP_FIFO_SIZE: fifo size for timestamp.
 *  @lock:              Chip access lock.
 *  @trig:              IIO trigger.
 *  @chip_config:	Cached attribute information.
 *  @reg:		Map of important registers.
 *  @hw:		Other hardware-specific information.
 *  @chip_type:		chip type.
 *  @time_stamp_lock:	spin lock to time stamp.
 *  @plat_data:		platform data (deprecated in favor of @orientation).
 *  @orientation:	sensor chip orientation relative to main hardware.
 *  @timestamps:        kfifo queue to store time stamp.
 *  @map		regmap pointer.
 *  @irq		interrupt number.
 *  @irq_mask		the int_pin_cfg mask to configure interrupt type.
 */
struct inv_mpu6050_state {
#define TIMESTAMP_FIFO_SIZE 16
	struct mutex lock;
	struct iio_trigger  *trig;
	struct inv_mpu6050_chip_config chip_config;
	const struct inv_mpu6050_reg_map *reg;
	const struct inv_mpu6050_hw *hw;
	enum   inv_devices chip_type;
	spinlock_t time_stamp_lock;
	struct i2c_mux_core *muxc;
	struct i2c_client *mux_client;
	unsigned int powerup_count;
	struct inv_mpu6050_platform_data plat_data;
	struct iio_mount_matrix orientation;
	DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
	struct regmap *map;
	int irq;
	u8 irq_mask;
@@ -234,7 +226,6 @@ struct inv_mpu6050_state {

/* init parameters */
#define INV_MPU6050_INIT_FIFO_RATE           50
#define INV_MPU6050_TIME_STAMP_TOR           5
#define INV_MPU6050_MAX_FIFO_RATE            1000
#define INV_MPU6050_MIN_FIFO_RATE            4
#define INV_MPU6050_ONE_K_HZ                 1000
@@ -300,7 +291,6 @@ enum inv_mpu6050_clock_sel_e {
	NUM_CLK
};

irqreturn_t inv_mpu6050_irq_handler(int irq, void *p);
irqreturn_t inv_mpu6050_read_fifo(int irq, void *p);
int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev, int irq_type);
int inv_reset_fifo(struct iio_dev *indio_dev);
+1 −43
Original line number Diff line number Diff line
@@ -19,20 +19,9 @@
#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/poll.h>
#include "inv_mpu_iio.h"

static void inv_clear_kfifo(struct inv_mpu6050_state *st)
{
	unsigned long flags;

	/* take the spin lock sem to avoid interrupt kick in */
	spin_lock_irqsave(&st->time_stamp_lock, flags);
	kfifo_reset(&st->timestamps);
	spin_unlock_irqrestore(&st->time_stamp_lock, flags);
}

int inv_reset_fifo(struct iio_dev *indio_dev)
{
	int result;
@@ -62,9 +51,6 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
	if (result)
		goto reset_fifo_fail;

	/* clear timestamps fifo */
	inv_clear_kfifo(st);

	/* enable interrupt */
	if (st->chip_config.accl_fifo_enable ||
	    st->chip_config.gyro_fifo_enable) {
@@ -98,23 +84,6 @@ reset_fifo_fail:
	return result;
}

/**
 * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
 */
irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct inv_mpu6050_state *st = iio_priv(indio_dev);
	s64 timestamp;

	timestamp = iio_get_time_ns(indio_dev);
	kfifo_in_spinlocked(&st->timestamps, &timestamp, 1,
			    &st->time_stamp_lock);

	return IRQ_WAKE_THREAD;
}

/**
 * inv_mpu6050_read_fifo() - Transfer data from hardware FIFO to KFIFO.
 */
@@ -127,7 +96,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
	int result;
	u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
	u16 fifo_count;
	s64 timestamp;
	s64 timestamp = pf->timestamp;
	int int_status;

	mutex_lock(&st->lock);
@@ -171,28 +140,17 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
		goto flush_fifo;
	if (fifo_count >  INV_MPU6050_FIFO_THRESHOLD)
		goto flush_fifo;
	/* Timestamp mismatch. */
	if (kfifo_len(&st->timestamps) >
	    fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
		goto flush_fifo;
	do {
		result = regmap_bulk_read(st->map, st->reg->fifo_r_w,
					  data, bytes_per_datum);
		if (result)
			goto flush_fifo;

		result = kfifo_out(&st->timestamps, &timestamp, 1);
		/* when there is no timestamp, put timestamp as 0 */
		if (result == 0)
			timestamp = 0;

		/* skip first samples if needed */
		if (st->skip_samples)
			st->skip_samples--;
		else
			iio_push_to_buffers_with_timestamp(indio_dev, data,
							   timestamp);

		fifo_count -= bytes_per_datum;
	} while (fifo_count >= bytes_per_datum);