diff options
| author | mattis fjallstrom <mattis@acm.org> | 2015-10-02 17:59:11 -0700 |
|---|---|---|
| committer | mattis fjallstrom <mattis@acm.org> | 2015-10-02 17:59:11 -0700 |
| commit | b291034eef47ffdd9a486dd6b41c0c76c4d33353 (patch) | |
| tree | 1d8585e20cd2683893bee839bedcfbced2637a9c | |
| parent | cf37981b4c9c4bfceab735aa210e2a8531c86954 (diff) | |
| download | olio-linux-3.10-b291034eef47ffdd9a486dd6b41c0c76c4d33353.tar.xz olio-linux-3.10-b291034eef47ffdd9a486dd6b41c0c76c4d33353.zip | |
Improved wakeup performance.
Change-Id: Idd79c715744046d50736e08b07e0c937d4ff7318
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c | 1 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c | 35 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c | 110 |
3 files changed, 132 insertions, 14 deletions
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c index f28fa07270f..75d3e3aaca2 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c @@ -8,7 +8,6 @@ * Licensed under the GPL-2. */ -/* #define DEBUG */ #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c index b0df8009aa8..aca1924a38b 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c @@ -7,7 +7,7 @@ * * Licensed under the GPL-2. */ - +//#define DEBUG #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> @@ -1841,6 +1841,34 @@ ssize_t st_lsm6ds3_sysfs_get_irq_src(struct device *dev, } +static ssize_t st_lsm6ds3_sysfs_ack_wakeup_irq(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret; + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + uint32_t i; + struct timespec ts; + s64 ack_time; + + ret = sscanf(buf, "%i", &i); + if(ret != 1 || i != 1){ + dev_err(sdata->cdata->dev,"error, write 1 to ack"); + return -EINVAL; + } + + mutex_lock(&sdata->cdata->fifo_lock); +#define ACK_TIME_DEBUG 1 +#if ACK_TIME_DEBUG + get_monotonic_boottime(&ts); + ack_time = timespec_to_ns(&ts); + dev_info(sdata->cdata->dev, "IRQ acked from android@%lld", ack_time); +#endif + wake_unlock(&sdata->cdata->tap_wlock); + + mutex_unlock(&sdata->cdata->fifo_lock); + return size; +} + static ssize_t st_lsm6ds3_sysfs_write_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { @@ -1971,6 +1999,8 @@ static IIO_DEVICE_ATTR(irq_source, S_IRUGO, static IIO_DEVICE_ATTR(write_reg, S_IWUSR, NULL, st_lsm6ds3_sysfs_write_reg, 0); +static IIO_DEVICE_ATTR(ack_wakeup_irq, S_IWUSR, + NULL, st_lsm6ds3_sysfs_ack_wakeup_irq, 0); static IIO_DEVICE_ATTR(read_reg, S_IRUGO | S_IWUSR, st_lsm6ds3_sysfs_read_reg_get, @@ -1997,6 +2027,7 @@ static struct attribute *st_lsm6ds3_accel_attributes[] = { &iio_dev_attr_read_reg.dev_attr.attr, &iio_dev_attr_sixd_wake_mask.dev_attr.attr, &iio_dev_attr_suspend_samples.dev_attr.attr, + &iio_dev_attr_ack_wakeup_irq.dev_attr.attr, NULL, }; @@ -2149,7 +2180,7 @@ int st_lsm6ds3_common_probe(struct lsm6ds3_data *cdata, int irq) dev_info(cdata->dev, "driver use DRDY int pin 1\n"); } - cdata->sixd_mask = SIXD_MASK_VALID_BITS; + cdata->sixd_mask = 0x21; cdata->indio_dev[ST_INDIO_DEV_ACCEL]->name = kasprintf(GFP_KERNEL, "%s_%s", cdata->name, diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c index d4106ad5071..d5f6ed5fcf4 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c @@ -7,9 +7,8 @@ * * Licensed under the GPL-2. */ - -/* #define DEBUG */ - +//#define WAKE_STATS_DEBUG_INFO +//#define DEBUG #include <linux/kernel.h> #include <linux/device.h> #include <linux/module.h> @@ -38,7 +37,7 @@ #define ST_LSM6DS3_TAP_SRC_Z_AXIS_MASK (1<<0) #define ST_LSM6DS3_6D_SRC_ADDR 0x1d - +#define ST_LSM6DS3_6D_SRC_DETECTED_MASK (1<<6) static struct workqueue_struct *st_lsm6ds3_wq; @@ -63,6 +62,82 @@ irqreturn_t st_lsm6ds3_save_timestamp(int irq, void *private) return IRQ_HANDLED; } +#ifdef WAKE_STATS_DEBUG_INFO +static int wakeup_irq_count = 0; +static int wakeup_irq_stayawake_count = 0; +static int wakeup_irq_keepawake_count = 0; +#define MAX_ORIENTATIONS 6 +static int wake_up_orient_count[MAX_ORIENTATIONS] = {0}; +static long wake_up_orient_times[MAX_ORIENTATIONS] = {0}; +s64 last_orient_change_time_ns = 0; +int last_orient; + + +static void update_orient_stats(u8 d6d_src_reg, s64 ctime_ns) +{ + return; + s64 delta = 0; + int orient_val; + d6d_src_reg &= SIXD_MASK_VALID_BITS; + orient_val = __ffs(d6d_src_reg); + if( orient_val >= MAX_ORIENTATIONS){ + return; + } + + wake_up_orient_count[orient_val]++; + if(last_orient_change_time_ns != 0){ + delta = ctime_ns - last_orient_change_time_ns; + do_div(delta, 1E6); //down to milliseconds + wake_up_orient_times[last_orient] += delta; + } + last_orient_change_time_ns = ctime_ns; + last_orient = orient_val; +} + +static void print_wake_stats(struct lsm6ds3_data *cdata) +{ + struct timespec monotonic, boot, misc; + s64 mon_ns, boot_ns, misc_ns, tot_ms=0; + int i; + + get_monotonic_boottime(&monotonic); + ktime_get_ts(&boot); + getnstimeofday(&misc); + mon_ns = timespec_to_ns(&monotonic); + boot_ns = timespec_to_ns(&boot); + misc_ns = timespec_to_ns(&misc); + do_div(mon_ns,1E9); + do_div(boot_ns,1E9); + do_div(misc_ns,1E9); + + dev_info(cdata->dev, "wkstat: unignored/total/keepawake: \t%i\t%i\t%i", wakeup_irq_stayawake_count, wakeup_irq_count, + wakeup_irq_keepawake_count); + dev_info(cdata->dev, "wkstat times: tot:\t%lld\tawake:\t%lld", mon_ns, boot_ns); + dev_info(cdata->dev, "wkstat all orient count: 5-0 %i\t%i\t%i\t%i\t%i\t%i", + wake_up_orient_count[5], + wake_up_orient_count[4], + wake_up_orient_count[3], + wake_up_orient_count[2], + wake_up_orient_count[1], + wake_up_orient_count[0]); + + for(i=0; i<MAX_ORIENTATIONS; i++) + tot_ms += wake_up_orient_times[i]; + + dev_info(cdata->dev, "wkstat orient times(uS): 5-0 %ld\t%ld\t%ld\t%ld\t%ld\t%ld\ttot:%lld", + wake_up_orient_times[5], + wake_up_orient_times[4], + wake_up_orient_times[3], + wake_up_orient_times[2], + wake_up_orient_times[1], + wake_up_orient_times[0], tot_ms); + +} +#endif /* WAKE_STATS_DEBUG_INFO */ + + + + static void st_lsm6ds3_irq_management(struct work_struct *data_work) { struct lsm6ds3_data *cdata; @@ -73,13 +148,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) int wake_irq; int ignore_event = 0; - - cdata = container_of((struct work_struct *)data_work, struct lsm6ds3_data, data_work); wake_irq = last_wakeup_reason_test(cdata->irq); - mutex_lock(&cdata->fifo_lock); cdata->tf->read(cdata, ST_LSM6DS3_6D_SRC_ADDR, 1, &d6d_src_reg, true); cdata->tf->read(cdata, ST_LSM6DS3_TAP_SRC_ADDR, 1, &tap_src_reg, true); @@ -89,7 +161,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) dev_dbg(cdata->dev, "ST irq start :src_value, 6d, tap:%x %x %x",src_value, d6d_src_reg, tap_src_reg); - if(d6d_src_reg & (1<<6)){ + if(d6d_src_reg & ST_LSM6DS3_6D_SRC_DETECTED_MASK){ +#ifdef WAKE_STATS_DEBUG_INFO + update_orient_stats(d6d_src_reg, cdata->timestamp); +#endif dev_info(cdata->dev, "D6D IRQ val:0x%x mask:0x%x", SIXD_MASK_VALID_BITS & d6d_src_reg, cdata->sixd_mask); if(cdata->sixd_mask & d6d_src_reg){ d6d_event = 1; @@ -113,7 +188,9 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) } } if(cdata->first_irq_from_resume && wake_irq){ - dev_info(cdata->dev, "First IRQ from a RESUME"); +#ifdef WAKE_STATS_DEBUG_INFO + wakeup_irq_count++; +#endif if(!d6d_event && !tap_event && !ignore_event){ dev_info(cdata->dev, "No event from first resume, assuming lost TAP"); tap_event = 1; @@ -124,8 +201,16 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) } if(!ignore_event && (tap_event || d6d_event) && cdata->first_irq_from_resume){ - dev_info(cdata->dev, "Setting wake lock"); - wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1500)); + wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(500)); +#ifdef WAKE_STATS_DEBUG_INFO + wakeup_irq_stayawake_count++; +#endif + } + else if(d6d_event && !ignore_event){//negative roll + wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(200)); +#ifdef WAKE_STATS_DEBUG_INFO + wakeup_irq_keepawake_count++; +#endif } //significant motion event processing if(tap_event){ @@ -179,6 +264,9 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) if(cdata->first_irq_from_resume){ cdata->first_irq_from_resume = 0; st_lsm6ds3_reconfigure_fifo(cdata, false); +#ifdef WAKE_STATS_DEBUG_INFO + print_wake_stats(cdata); +#endif } enable_irq(cdata->irq); return; |