Merge tag 'iio-fixes-for-4.2a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jul 2015 21:18:07 +0000 (14:18 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jul 2015 21:18:07 +0000 (14:18 -0700)
Jonathan writes:

First set of IIO fixes for the 4.2 cycle.

* Fix a regression in hid sensors suspend time as a result of adding runtime
  pm.  The normal flow of waking up devices in order to go into suspend
  (given the devices are normally suspended when not reading) to a regression
  in suspend time on some laptops (reports of an additional 8 seconds).
  Fix this by checking to see if a user action resulting in the wake up, and
  make it a null operation if it didn't.  Note that for hid sensors, there is
  nothing useful to be done when moving into a full suspend from a runtime
  suspend so they might as well be left alone.
* rochip_saradc: fix some missing MODULE_* data including the licence so that
  the driver does not taint the kernel incorrectly and can build as a module.
* twl4030 - mark irq as oneshot as it always should have been.
* inv-mpu - write formats for attributes not specified, leading to miss
  interpretation of the gyro scale channel when written.
* Proximity ABI clarification.  This had snuck through as a mess.  Some
  drivers thought proximity went in one direction, some the other.  We went
  with the most common option, documented it and fixed up the drivers going
  the other way.  Fix for sx9500 included in this set.
* ad624r - fix a wrong shift in the output data.
* at91_adc - remove a false limit on the value of the STARTUP register
  applied by too small a type for the device tree parameter.
* cm3323 - clear the bits when setting the integration time (otherwise
  we can only ever set more bits in the relevant field).
* bmc150-accel - multiple triggers are registered, but on error were not being
  unwound in the opposite order leading to removal of triggers that had not
  yet successfully been registered (count down instead of up when unwinding).
* tcs3414 - ensure right part of val / val2 pair read so that the integration
  time is not always 0.
* cc10001_adc - bug in kconfig dependency. Use of OR when AND was intended.

1  2 
Documentation/ABI/testing/sysfs-bus-iio
drivers/iio/accel/bmc150-accel.c
drivers/iio/adc/Kconfig
drivers/iio/adc/twl4030-madc.c
drivers/iio/proximity/sx9500.c
include/linux/hid-sensor-hub.h

index bbed111c31b4ed7658e61ac6b7140284c3035dc6,1fbdd79d16240ae4496cbc5cc82fce0d9d845dc2..70c9b1ac66dbc5880c90312b47ba0b28669a77a6
@@@ -71,8 -71,6 +71,8 @@@ Description
  
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_raw
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_raw
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_raw
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_raw
  KernelVersion:        2.6.35
  Contact:      linux-iio@vger.kernel.org
  Description:
                unique to allow association with event codes. Units after
                application of scale and offset are millivolts.
  
 +              Channels with 'i' and 'q' modifiers always exist in pairs and both
 +              channels refer to the same signal. The 'i' channel contains the in-phase
 +              component of the signal while the 'q' channel contains the quadrature
 +              component.
 +
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw
  KernelVersion:        2.6.35
  Contact:      linux-iio@vger.kernel.org
@@@ -253,16 -246,8 +253,16 @@@ What:            /sys/bus/iio/devices/iio:deviceX
  What:         /sys/bus/iio/devices/iio:deviceX/in_accel_z_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltage_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltage_q_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltage_i_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_current_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_i_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_q_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_current_q_offset
 +What:         /sys/bus/iio/devices/iio:deviceX/in_current_i_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_temp_offset
  What:         /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
@@@ -288,22 -273,14 +288,22 @@@ Description
                to the _raw output.
  
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltage_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltage_i_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_voltage_q_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_scale
  What:         /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale
  What:         /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_current_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_i_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_currentY_q_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_current_i_scale
 +What:         /sys/bus/iio/devices/iio:deviceX/in_current_q_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_accel_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale
  What:         /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale
@@@ -351,10 -328,6 +351,10 @@@ Description
  
  What          /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale
  What          /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale
 +What          /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_calibscale
 +What          /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_calibscale
 +What          /sys/bus/iio/devices/iio:deviceX/in_voltage_i_calibscale
 +What          /sys/bus/iio/devices/iio:deviceX/in_voltage_q_calibscale
  What          /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale
  What          /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale
  What          /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale
@@@ -447,16 -420,6 +447,16 @@@ Description
                to the underlying data channel, then this parameter
                gives the 3dB frequency of the filter in Hz.
  
 +What:         /sys/.../in_accel_filter_high_pass_3db_frequency
 +What:         /sys/.../in_anglvel_filter_high_pass_3db_frequency
 +What:         /sys/.../in_magn_filter_high_pass_3db_frequency
 +KernelVersion:        4.2
 +Contact:      linux-iio@vger.kernel.org
 +Description:
 +              If a known or controllable high pass filter is applied
 +              to the underlying data channel, then this parameter
 +              gives the 3dB frequency of the filter in Hz.
 +
  What:         /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw
  What:         /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_raw
  KernelVersion:        2.6.37
@@@ -917,26 -880,6 +917,26 @@@ Description
                met before an event is generated. If direction is not
                specified then this period applies to both directions.
  
 +What:         /sys/.../events/in_accel_thresh_rising_low_pass_filter_3db
 +What:         /sys/.../events/in_anglvel_thresh_rising_low_pass_filter_3db
 +What:         /sys/.../events/in_magn_thresh_rising_low_pass_filter_3db
 +KernelVersion:        4.2
 +Contact:      linux-iio@vger.kernel.org
 +Description:
 +              If a low pass filter can be applied to the event generation
 +              this property gives its 3db frequency in Hz.
 +              A value of zero disables the filter.
 +
 +What:         /sys/.../events/in_accel_thresh_rising_high_pass_filter_3db
 +What:         /sys/.../events/in_anglvel_thresh_rising_high_pass_filter_3db
 +What:         /sys/.../events/in_magn_thresh_rising_high_pass_filter_3db
 +KernelVersion:        4.2
 +Contact:      linux-iio@vger.kernel.org
 +Description:
 +              If a high pass filter can be applied to the event generation
 +              this property gives its 3db frequency in Hz.
 +              A value of zero disables the filter.
 +
  What:         /sys/.../events/in_activity_still_thresh_rising_en
  What:         /sys/.../events/in_activity_still_thresh_falling_en
  What:         /sys/.../events/in_activity_walking_thresh_rising_en
@@@ -1073,10 -1016,6 +1073,10 @@@ What:         /sys/.../iio:deviceX/scan_elemen
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_supply_en
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_en
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY-voltageZ_en
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_i_en
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_q_en
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltage_i_en
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltage_q_en
  What:         /sys/.../iio:deviceX/scan_elements/in_incli_x_en
  What:         /sys/.../iio:deviceX/scan_elements/in_incli_y_en
  What:         /sys/.../iio:deviceX/scan_elements/in_pressureY_en
@@@ -1095,10 -1034,6 +1095,10 @@@ What:         /sys/.../iio:deviceX/scan_elemen
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_type
  What:         /sys/.../iio:deviceX/scan_elements/in_voltage_type
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_supply_type
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_i_type
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_q_type
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltage_i_type
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltage_q_type
  What:         /sys/.../iio:deviceX/scan_elements/in_timestamp_type
  What:         /sys/.../iio:deviceX/scan_elements/in_pressureY_type
  What:         /sys/.../iio:deviceX/scan_elements/in_pressure_type
@@@ -1136,10 -1071,6 +1136,10 @@@ Description
  
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_index
  What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_supply_index
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_i_index
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltageY_q_index
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltage_i_index
 +What:         /sys/.../iio:deviceX/scan_elements/in_voltage_q_index
  What:         /sys/.../iio:deviceX/scan_elements/in_accel_x_index
  What:         /sys/.../iio:deviceX/scan_elements/in_accel_y_index
  What:         /sys/.../iio:deviceX/scan_elements/in_accel_z_index
@@@ -1234,10 -1165,8 +1234,8 @@@ Description
                object is near the sensor, usually be observing
                reflectivity of infrared or ultrasound emitted.
                Often these sensors are unit less and as such conversion
-               to SI units is not possible.  Where it is, the units should
-               be meters.  If such a conversion is not possible, the reported
-               values should behave in the same way as a distance, i.e. lower
-               values indicate something is closer to the sensor.
+               to SI units is not possible. Higher proximity measurements
+               indicate closer objects, and vice versa.
  
  What:         /sys/.../iio:deviceX/in_illuminance_input
  What:         /sys/.../iio:deviceX/in_illuminance_raw
@@@ -1299,8 -1228,6 +1297,8 @@@ Description
                or without compensation from tilt sensors.
  
  What:         /sys/bus/iio/devices/iio:deviceX/in_currentX_raw
 +What:         /sys/bus/iio/devices/iio:deviceX/in_currentX_i_raw
 +What:         /sys/bus/iio/devices/iio:deviceX/in_currentX_q_raw
  KernelVersion:        3.18
  Contact:      linux-iio@vger.kernel.org
  Description:
                present, output should be considered as processed with the
                unit in milliamps.
  
 +              Channels with 'i' and 'q' modifiers always exist in pairs and both
 +              channels refer to the same signal. The 'i' channel contains the in-phase
 +              component of the signal while the 'q' channel contains the quadrature
 +              component.
 +
  What:         /sys/.../iio:deviceX/in_energy_en
  What:         /sys/.../iio:deviceX/in_distance_en
  What:         /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_en
@@@ -1440,26 -1362,3 +1438,26 @@@ Description
                hwfifo_watermak_min but not equal to any of the values in this
                list, the driver will chose an appropriate value for the
                hardware fifo watermark level.
 +
 +What:         /sys/bus/iio/devices/iio:deviceX/in_temp_calibemissivity
 +What:         /sys/bus/iio/devices/iio:deviceX/in_tempX_calibemissivity
 +What:         /sys/bus/iio/devices/iio:deviceX/in_temp_object_calibemissivity
 +What:         /sys/bus/iio/devices/iio:deviceX/in_tempX_object_calibemissivity
 +KernelVersion:        4.1
 +Contact:      linux-iio@vger.kernel.org
 +Description:
 +              The emissivity ratio of the surface in the field of view of the
 +              contactless temperature sensor.  Emissivity varies from 0 to 1,
 +              with 1 being the emissivity of a black body.
 +
 +What:         /sys/bus/iio/devices/iio:deviceX/in_magn_x_oversampling_ratio
 +What:         /sys/bus/iio/devices/iio:deviceX/in_magn_y_oversampling_ratio
 +What:         /sys/bus/iio/devices/iio:deviceX/in_magn_z_oversampling_ratio
 +KernelVersion:        4.2
 +Contact:      linux-iio@vger.kernel.org
 +Description:
 +              Hardware applied number of measurements for acquiring one
 +              data point. The HW will do <type>[_name]_oversampling_ratio
 +              measurements and return the average value as output data. Each
 +              value resulted from <type>[_name]_oversampling_ratio measurements
 +              is considered as one sample for <type>[_name]_sampling_frequency.
index 4e70f51c237089f54ebee9882df499551d56b1e3,bf827d012a71492a2088e91dd364cfacc245febd..cc5a35750b507359f6496c980d30bdb7027ded76
@@@ -196,7 -196,7 +196,7 @@@ struct bmc150_accel_data 
        u32 slope_thres;
        u32 range;
        int ev_enable_state;
 -      int64_t timestamp, old_timestamp;
 +      int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
        const struct bmc150_accel_chip_info *chip_info;
  };
  
@@@ -1183,6 -1183,7 +1183,6 @@@ static const struct iio_info bmc150_acc
        .write_event_value      = bmc150_accel_write_event,
        .write_event_config     = bmc150_accel_write_event_config,
        .read_event_config      = bmc150_accel_read_event_config,
 -      .validate_trigger       = bmc150_accel_validate_trigger,
        .driver_module          = THIS_MODULE,
  };
  
@@@ -1221,7 -1222,7 +1221,7 @@@ static irqreturn_t bmc150_accel_trigger
        mutex_unlock(&data->mutex);
  
        iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
 -                                         data->timestamp);
 +                                         pf->timestamp);
  err_read:
        iio_trigger_notify_done(indio_dev->trig);
  
@@@ -1464,7 -1465,7 +1464,7 @@@ static void bmc150_accel_unregister_tri
  {
        int i;
  
-       for (i = from; i >= 0; i++) {
+       for (i = from; i >= 0; i--) {
                if (data->triggers[i].indio_trig) {
                        iio_trigger_unregister(data->triggers[i].indio_trig);
                        data->triggers[i].indio_trig = NULL;
@@@ -1534,13 -1535,6 +1534,13 @@@ static int bmc150_accel_fifo_set_mode(s
        return ret;
  }
  
 +static int bmc150_accel_buffer_preenable(struct iio_dev *indio_dev)
 +{
 +      struct bmc150_accel_data *data = iio_priv(indio_dev);
 +
 +      return bmc150_accel_set_power_state(data, true);
 +}
 +
  static int bmc150_accel_buffer_postenable(struct iio_dev *indio_dev)
  {
        struct bmc150_accel_data *data = iio_priv(indio_dev);
        return 0;
  }
  
 +static int bmc150_accel_buffer_postdisable(struct iio_dev *indio_dev)
 +{
 +      struct bmc150_accel_data *data = iio_priv(indio_dev);
 +
 +      return bmc150_accel_set_power_state(data, false);
 +}
 +
  static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
 +      .preenable = bmc150_accel_buffer_preenable,
        .postenable = bmc150_accel_buffer_postenable,
        .predisable = bmc150_accel_buffer_predisable,
 +      .postdisable = bmc150_accel_buffer_postdisable,
  };
  
  static int bmc150_accel_probe(struct i2c_client *client,
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &bmc150_accel_info;
  
 +      ret = iio_triggered_buffer_setup(indio_dev,
 +                                       &iio_pollfunc_store_time,
 +                                       bmc150_accel_trigger_handler,
 +                                       &bmc150_accel_buffer_ops);
 +      if (ret < 0) {
 +              dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
 +              return ret;
 +      }
 +
        if (client->irq < 0)
                client->irq = bmc150_accel_gpio_probe(client, data);
  
                                                BMC150_ACCEL_IRQ_NAME,
                                                indio_dev);
                if (ret)
 -                      return ret;
 +                      goto err_buffer_cleanup;
  
                /*
                 * Set latched mode interrupt. While certain interrupts are
                                             BMC150_ACCEL_INT_MODE_LATCH_RESET);
                if (ret < 0) {
                        dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
 -                      return ret;
 +                      goto err_buffer_cleanup;
                }
  
                bmc150_accel_interrupts_setup(indio_dev, data);
  
                ret = bmc150_accel_triggers_setup(indio_dev, data);
                if (ret)
 -                      return ret;
 -
 -              ret = iio_triggered_buffer_setup(indio_dev,
 -                                               &iio_pollfunc_store_time,
 -                                               bmc150_accel_trigger_handler,
 -                                               &bmc150_accel_buffer_ops);
 -              if (ret < 0) {
 -                      dev_err(&client->dev,
 -                              "Failed: iio triggered buffer setup\n");
 -                      goto err_trigger_unregister;
 -              }
 +                      goto err_buffer_cleanup;
  
                if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
                    i2c_check_functionality(client->adapter,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "Unable to register iio device\n");
 -              goto err_buffer_cleanup;
 +              goto err_trigger_unregister;
        }
  
        ret = pm_runtime_set_active(&client->dev);
  
  err_iio_unregister:
        iio_device_unregister(indio_dev);
 -err_buffer_cleanup:
 -      if (indio_dev->pollfunc)
 -              iio_triggered_buffer_cleanup(indio_dev);
  err_trigger_unregister:
        bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1);
 +err_buffer_cleanup:
 +      iio_triggered_buffer_cleanup(indio_dev);
  
        return ret;
  }
@@@ -1743,8 -1730,6 +1743,8 @@@ static int bmc150_accel_remove(struct i
  
        bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1);
  
 +      iio_triggered_buffer_cleanup(indio_dev);
 +
        mutex_lock(&data->mutex);
        bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0);
        mutex_unlock(&data->mutex);
diff --combined drivers/iio/adc/Kconfig
index 7c5565891cb83012f9034b3e9224629c08a00ced,1bcb65b8d4a1a482b7754b99e39b0f5517435eb6..eb0cd897714a26b619b9e6c924ce4c3a65a5806b
@@@ -135,13 -135,6 +135,13 @@@ config AXP288_AD
          device. Depending on platform configuration, this general purpose ADC can
          be used for sampling sensors such as thermal resistors.
  
 +config BERLIN2_ADC
 +      tristate "Marvell Berlin2 ADC driver"
 +      depends on ARCH_BERLIN
 +      help
 +        Marvell Berlin2 ADC driver. This ADC has 8 channels, with one used for
 +        temperature measurement.
 +
  config DA9150_GPADC
        tristate "Dialog DA9150 GPADC driver support"
        depends on MFD_DA9150
  
  config CC10001_ADC
        tristate "Cosmic Circuits 10001 ADC driver"
-       depends on HAVE_CLK || REGULATOR
-       depends on HAS_IOMEM
+       depends on HAS_IOMEM && HAVE_CLK && REGULATOR
        select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
@@@ -292,11 -284,11 +291,11 @@@ config TI_ADC081
          called ti-adc081c.
  
  config TI_ADC128S052
 -      tristate "Texas Instruments ADC128S052"
 +      tristate "Texas Instruments ADC128S052/ADC122S021"
        depends on SPI
        help
          If you say yes here you get support for Texas Instruments ADC128S052
 -        chip.
 +        and ADC122S021 chips.
  
          This driver can also be built as a module. If so, the module will be
          called ti-adc128s052.
index 06f4792240f025ac56b9cc42946cc4834f0ad480,4caecbea4c97da41ca942872c463eb86e9b47b55..ebe415f1064000c95c88f5d20da48a7f52f71d84
@@@ -235,7 -235,7 +235,7 @@@ static int twl4030battery_temperature(i
        if (ret < 0)
                return ret;
  
 -      curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
 +      curr = ((val & TWL4030_BCI_ITHSENS) + 1) * 10;
        /* Getting and calculating the thermistor resistance in ohms */
        res = volt * 1000 / curr;
        /* calculating temperature */
@@@ -662,8 -662,10 +662,8 @@@ EXPORT_SYMBOL_GPL(twl4030_get_madc_conv
   *
   * @madc:     pointer to twl4030_madc_data struct
   * @chan:     can be one of the two values:
 - *            TWL4030_BCI_ITHEN
 - *            Enables bias current for main battery type reading
 - *            TWL4030_BCI_TYPEN
 - *            Enables bias current for main battery temperature sensing
 + *            0 - Enables bias current for main battery type reading
 + *            1 - Enables bias current for main battery temperature sensing
   * @on:               enable or disable chan.
   *
   * Function to enable or disable bias current for
@@@ -833,7 -835,8 +833,8 @@@ static int twl4030_madc_probe(struct pl
        irq = platform_get_irq(pdev, 0);
        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
                                   twl4030_madc_threaded_irq_handler,
-                                  IRQF_TRIGGER_RISING, "twl4030_madc", madc);
+                                  IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                                  "twl4030_madc", madc);
        if (ret) {
                dev_err(&pdev->dev, "could not request irq\n");
                goto err_i2c;
index 2042e375f8351de6dc04b0b6ae7861702d17c6cf,bd26a484abcc3ce265400821b28b12564975a76c..01494cd6fa32fe791082699eef66a773ded1cc28
@@@ -18,8 -18,6 +18,8 @@@
  #include <linux/acpi.h>
  #include <linux/gpio/consumer.h>
  #include <linux/regmap.h>
 +#include <linux/pm.h>
 +#include <linux/delay.h>
  
  #include <linux/iio/iio.h>
  #include <linux/iio/buffer.h>
@@@ -31,9 -29,7 +31,9 @@@
  
  #define SX9500_DRIVER_NAME            "sx9500"
  #define SX9500_IRQ_NAME                       "sx9500_event"
 -#define SX9500_GPIO_NAME              "sx9500_gpio"
 +
 +#define SX9500_GPIO_INT                       "interrupt"
 +#define SX9500_GPIO_RESET             "reset"
  
  /* Register definitions. */
  #define SX9500_REG_IRQ_SRC            0x00
@@@ -77,7 -73,6 +77,7 @@@
  #define SX9500_CONVDONE_IRQ           BIT(3)
  
  #define SX9500_PROXSTAT_SHIFT         4
 +#define SX9500_COMPSTAT_MASK          GENMASK(3, 0)
  
  #define SX9500_NUM_CHANNELS           4
  
@@@ -86,7 -81,6 +86,7 @@@ struct sx9500_data 
        struct i2c_client *client;
        struct iio_trigger *trig;
        struct regmap *regmap;
 +      struct gpio_desc *gpiod_rst;
        /*
         * Last reading of the proximity status for each channel.  We
         * only send an event to user space when this changes.
        bool event_enabled[SX9500_NUM_CHANNELS];
        bool trigger_enabled;
        u16 *buffer;
 +      /* Remember enabled channels and sample rate during suspend. */
 +      unsigned int suspend_ctrl0;
 +      struct completion completion;
 +      int data_rdy_users, close_far_users;
 +      int channel_users[SX9500_NUM_CHANNELS];
  };
  
  static const struct iio_event_spec sx9500_events[] = {
@@@ -150,10 -139,6 +150,10 @@@ static const struct 
        {2, 500000},
  };
  
 +static const unsigned int sx9500_scan_period_table[] = {
 +      30, 60, 90, 120, 150, 200, 300, 400,
 +};
 +
  static const struct regmap_range sx9500_writable_reg_ranges[] = {
        regmap_reg_range(SX9500_REG_IRQ_MSK, SX9500_REG_IRQ_MSK),
        regmap_reg_range(SX9500_REG_PROX_CTRL0, SX9500_REG_PROX_CTRL8),
@@@ -206,67 -191,7 +206,67 @@@ static const struct regmap_config sx950
        .volatile_table = &sx9500_volatile_regs,
  };
  
 -static int sx9500_read_proximity(struct sx9500_data *data,
 +static int sx9500_inc_users(struct sx9500_data *data, int *counter,
 +                          unsigned int reg, unsigned int bitmask)
 +{
 +      (*counter)++;
 +      if (*counter != 1)
 +              /* Bit is already active, nothing to do. */
 +              return 0;
 +
 +      return regmap_update_bits(data->regmap, reg, bitmask, bitmask);
 +}
 +
 +static int sx9500_dec_users(struct sx9500_data *data, int *counter,
 +                          unsigned int reg, unsigned int bitmask)
 +{
 +      (*counter)--;
 +      if (*counter != 0)
 +              /* There are more users, do not deactivate. */
 +              return 0;
 +
 +      return regmap_update_bits(data->regmap, reg, bitmask, 0);
 +}
 +
 +static int sx9500_inc_chan_users(struct sx9500_data *data, int chan)
 +{
 +      return sx9500_inc_users(data, &data->channel_users[chan],
 +                              SX9500_REG_PROX_CTRL0, BIT(chan));
 +}
 +
 +static int sx9500_dec_chan_users(struct sx9500_data *data, int chan)
 +{
 +      return sx9500_dec_users(data, &data->channel_users[chan],
 +                              SX9500_REG_PROX_CTRL0, BIT(chan));
 +}
 +
 +static int sx9500_inc_data_rdy_users(struct sx9500_data *data)
 +{
 +      return sx9500_inc_users(data, &data->data_rdy_users,
 +                              SX9500_REG_IRQ_MSK, SX9500_CONVDONE_IRQ);
 +}
 +
 +static int sx9500_dec_data_rdy_users(struct sx9500_data *data)
 +{
 +      return sx9500_dec_users(data, &data->data_rdy_users,
 +                              SX9500_REG_IRQ_MSK, SX9500_CONVDONE_IRQ);
 +}
 +
 +static int sx9500_inc_close_far_users(struct sx9500_data *data)
 +{
 +      return sx9500_inc_users(data, &data->close_far_users,
 +                              SX9500_REG_IRQ_MSK,
 +                              SX9500_CLOSE_IRQ | SX9500_FAR_IRQ);
 +}
 +
 +static int sx9500_dec_close_far_users(struct sx9500_data *data)
 +{
 +      return sx9500_dec_users(data, &data->close_far_users,
 +                              SX9500_REG_IRQ_MSK,
 +                              SX9500_CLOSE_IRQ | SX9500_FAR_IRQ);
 +}
 +
 +static int sx9500_read_prox_data(struct sx9500_data *data,
                                 const struct iio_chan_spec *chan,
                                 int *val)
  {
        if (ret < 0)
                return ret;
  
-       *val = 32767 - (s16)be16_to_cpu(regval);
+       *val = be16_to_cpu(regval);
  
        return IIO_VAL_INT;
  }
  
 +/*
 + * If we have no interrupt support, we have to wait for a scan period
 + * after enabling a channel to get a result.
 + */
 +static int sx9500_wait_for_sample(struct sx9500_data *data)
 +{
 +      int ret;
 +      unsigned int val;
 +
 +      ret = regmap_read(data->regmap, SX9500_REG_PROX_CTRL0, &val);
 +      if (ret < 0)
 +              return ret;
 +
 +      val = (val & SX9500_SCAN_PERIOD_MASK) >> SX9500_SCAN_PERIOD_SHIFT;
 +
 +      msleep(sx9500_scan_period_table[val]);
 +
 +      return 0;
 +}
 +
 +static int sx9500_read_proximity(struct sx9500_data *data,
 +                               const struct iio_chan_spec *chan,
 +                               int *val)
 +{
 +      int ret;
 +
 +      mutex_lock(&data->mutex);
 +
 +      ret = sx9500_inc_chan_users(data, chan->channel);
 +      if (ret < 0)
 +              goto out;
 +
 +      ret = sx9500_inc_data_rdy_users(data);
 +      if (ret < 0)
 +              goto out_dec_chan;
 +
 +      mutex_unlock(&data->mutex);
 +
 +      if (data->client->irq > 0)
 +              ret = wait_for_completion_interruptible(&data->completion);
 +      else
 +              ret = sx9500_wait_for_sample(data);
 +
 +      if (ret < 0)
 +              return ret;
 +
 +      mutex_lock(&data->mutex);
 +
 +      ret = sx9500_read_prox_data(data, chan, val);
 +      if (ret < 0)
 +              goto out;
 +
 +      ret = sx9500_dec_chan_users(data, chan->channel);
 +      if (ret < 0)
 +              goto out;
 +
 +      ret = sx9500_dec_data_rdy_users(data);
 +      if (ret < 0)
 +              goto out;
 +
 +      ret = IIO_VAL_INT;
 +
 +      goto out;
 +
 +out_dec_chan:
 +      sx9500_dec_chan_users(data, chan->channel);
 +out:
 +      mutex_unlock(&data->mutex);
 +      reinit_completion(&data->completion);
 +
 +      return ret;
 +}
 +
  static int sx9500_read_samp_freq(struct sx9500_data *data,
                                 int *val, int *val2)
  {
@@@ -384,6 -236,7 +384,6 @@@ static int sx9500_read_raw(struct iio_d
                           int *val, int *val2, long mask)
  {
        struct sx9500_data *data = iio_priv(indio_dev);
 -      int ret;
  
        switch (chan->type) {
        case IIO_PROXIMITY:
                case IIO_CHAN_INFO_RAW:
                        if (iio_buffer_enabled(indio_dev))
                                return -EBUSY;
 -                      mutex_lock(&data->mutex);
 -                      ret = sx9500_read_proximity(data, chan, val);
 -                      mutex_unlock(&data->mutex);
 -                      return ret;
 +                      return sx9500_read_proximity(data, chan, val);
                case IIO_CHAN_INFO_SAMP_FREQ:
                        return sx9500_read_samp_freq(data, val, val2);
                default:
@@@ -462,16 -318,28 +462,16 @@@ static irqreturn_t sx9500_irq_handler(i
        return IRQ_WAKE_THREAD;
  }
  
 -static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
 +static void sx9500_push_events(struct iio_dev *indio_dev)
  {
 -      struct iio_dev *indio_dev = private;
 -      struct sx9500_data *data = iio_priv(indio_dev);
        int ret;
        unsigned int val, chan;
 -
 -      mutex_lock(&data->mutex);
 -
 -      ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
 -      if (ret < 0) {
 -              dev_err(&data->client->dev, "i2c transfer error in irq\n");
 -              goto out;
 -      }
 -
 -      if (!(val & (SX9500_CLOSE_IRQ | SX9500_FAR_IRQ)))
 -              goto out;
 +      struct sx9500_data *data = iio_priv(indio_dev);
  
        ret = regmap_read(data->regmap, SX9500_REG_STAT, &val);
        if (ret < 0) {
                dev_err(&data->client->dev, "i2c transfer error in irq\n");
 -              goto out;
 +              return;
        }
  
        val >>= SX9500_PROXSTAT_SHIFT;
                        /* No change on this channel. */
                        continue;
  
 -              dir = new_prox ? IIO_EV_DIR_FALLING :
 -                      IIO_EV_DIR_RISING;
 -              ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
 -                                        chan,
 -                                        IIO_EV_TYPE_THRESH,
 -                                        dir);
 +              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());
                data->prox_stat[chan] = new_prox;
        }
 +}
 +
 +static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
 +{
 +      struct iio_dev *indio_dev = private;
 +      struct sx9500_data *data = iio_priv(indio_dev);
 +      int ret;
 +      unsigned int val;
 +
 +      mutex_lock(&data->mutex);
 +
 +      ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
 +      if (ret < 0) {
 +              dev_err(&data->client->dev, "i2c transfer error in irq\n");
 +              goto out;
 +      }
 +
 +      if (val & (SX9500_CLOSE_IRQ | SX9500_FAR_IRQ))
 +              sx9500_push_events(indio_dev);
 +
 +      if (val & SX9500_CONVDONE_IRQ)
 +              complete_all(&data->completion);
  
  out:
        mutex_unlock(&data->mutex);
@@@ -542,7 -391,9 +542,7 @@@ static int sx9500_write_event_config(st
                                     int state)
  {
        struct sx9500_data *data = iio_priv(indio_dev);
 -      int ret, i;
 -      bool any_active = false;
 -      unsigned int irqmask;
 +      int ret;
  
        if (chan->type != IIO_PROXIMITY || type != IIO_EV_TYPE_THRESH ||
            dir != IIO_EV_DIR_EITHER)
  
        mutex_lock(&data->mutex);
  
 -      data->event_enabled[chan->channel] = state;
 +      if (state == 1) {
 +              ret = sx9500_inc_chan_users(data, chan->channel);
 +              if (ret < 0)
 +                      goto out_unlock;
 +              ret = sx9500_inc_close_far_users(data);
 +              if (ret < 0)
 +                      goto out_undo_chan;
 +      } else {
 +              ret = sx9500_dec_chan_users(data, chan->channel);
 +              if (ret < 0)
 +                      goto out_unlock;
 +              ret = sx9500_dec_close_far_users(data);
 +              if (ret < 0)
 +                      goto out_undo_chan;
 +      }
  
 -      for (i = 0; i < SX9500_NUM_CHANNELS; i++)
 -              if (data->event_enabled[i]) {
 -                      any_active = true;
 -                      break;
 -              }
 +      data->event_enabled[chan->channel] = state;
 +      goto out_unlock;
  
 -      irqmask = SX9500_CLOSE_IRQ | SX9500_FAR_IRQ;
 -      if (any_active)
 -              ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
 -                                       irqmask, irqmask);
 +out_undo_chan:
 +      if (state == 1)
 +              sx9500_dec_chan_users(data, chan->channel);
        else
 -              ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
 -                                       irqmask, 0);
 -
 +              sx9500_inc_chan_users(data, chan->channel);
 +out_unlock:
        mutex_unlock(&data->mutex);
 -
        return ret;
  }
  
@@@ -626,16 -469,12 +626,16 @@@ static int sx9500_set_trigger_state(str
  
        mutex_lock(&data->mutex);
  
 -      ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
 -                               SX9500_CONVDONE_IRQ,
 -                               state ? SX9500_CONVDONE_IRQ : 0);
 -      if (ret == 0)
 -              data->trigger_enabled = state;
 +      if (state)
 +              ret = sx9500_inc_data_rdy_users(data);
 +      else
 +              ret = sx9500_dec_data_rdy_users(data);
 +      if (ret < 0)
 +              goto out;
 +
 +      data->trigger_enabled = state;
  
 +out:
        mutex_unlock(&data->mutex);
  
        return ret;
@@@ -657,7 -496,7 +657,7 @@@ static irqreturn_t sx9500_trigger_handl
  
        for_each_set_bit(bit, indio_dev->active_scan_mask,
                         indio_dev->masklength) {
 -              ret = sx9500_read_proximity(data, &indio_dev->channels[bit],
 +              ret = sx9500_read_prox_data(data, &indio_dev->channels[bit],
                                            &val);
                if (ret < 0)
                        goto out;
@@@ -676,62 -515,6 +676,62 @@@ out
        return IRQ_HANDLED;
  }
  
 +static int sx9500_buffer_preenable(struct iio_dev *indio_dev)
 +{
 +      struct sx9500_data *data = iio_priv(indio_dev);
 +      int ret, i;
 +
 +      mutex_lock(&data->mutex);
 +
 +      for (i = 0; i < SX9500_NUM_CHANNELS; i++)
 +              if (test_bit(i, indio_dev->active_scan_mask)) {
 +                      ret = sx9500_inc_chan_users(data, i);
 +                      if (ret)
 +                              break;
 +              }
 +
 +      if (ret)
 +              for (i = i - 1; i >= 0; i--)
 +                      if (test_bit(i, indio_dev->active_scan_mask))
 +                              sx9500_dec_chan_users(data, i);
 +
 +      mutex_unlock(&data->mutex);
 +
 +      return ret;
 +}
 +
 +static int sx9500_buffer_predisable(struct iio_dev *indio_dev)
 +{
 +      struct sx9500_data *data = iio_priv(indio_dev);
 +      int ret, i;
 +
 +      iio_triggered_buffer_predisable(indio_dev);
 +
 +      mutex_lock(&data->mutex);
 +
 +      for (i = 0; i < SX9500_NUM_CHANNELS; i++)
 +              if (test_bit(i, indio_dev->active_scan_mask)) {
 +                      ret = sx9500_dec_chan_users(data, i);
 +                      if (ret)
 +                              break;
 +              }
 +
 +      if (ret)
 +              for (i = i - 1; i >= 0; i--)
 +                      if (test_bit(i, indio_dev->active_scan_mask))
 +                              sx9500_inc_chan_users(data, i);
 +
 +      mutex_unlock(&data->mutex);
 +
 +      return ret;
 +}
 +
 +static const struct iio_buffer_setup_ops sx9500_buffer_setup_ops = {
 +      .preenable = sx9500_buffer_preenable,
 +      .postenable = iio_triggered_buffer_postenable,
 +      .predisable = sx9500_buffer_predisable,
 +};
 +
  struct sx9500_reg_default {
        u8 reg;
        u8 def;
@@@ -787,57 -570,17 +787,57 @@@ static const struct sx9500_reg_default 
        },
        {
                .reg = SX9500_REG_PROX_CTRL0,
 -              /* Scan period: 30ms, all sensors enabled. */
 -              .def = 0x0f,
 +              /* Scan period: 30ms, all sensors disabled. */
 +              .def = 0x00,
        },
  };
  
 +/* Activate all channels and perform an initial compensation. */
 +static int sx9500_init_compensation(struct iio_dev *indio_dev)
 +{
 +      struct sx9500_data *data = iio_priv(indio_dev);
 +      int i, ret;
 +      unsigned int val;
 +
 +      ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
 +                               GENMASK(SX9500_NUM_CHANNELS, 0),
 +                               GENMASK(SX9500_NUM_CHANNELS, 0));
 +      if (ret < 0)
 +              return ret;
 +
 +      for (i = 10; i >= 0; i--) {
 +              usleep_range(10000, 20000);
 +              ret = regmap_read(data->regmap, SX9500_REG_STAT, &val);
 +              if (ret < 0)
 +                      goto out;
 +              if (!(val & SX9500_COMPSTAT_MASK))
 +                      break;
 +      }
 +
 +      if (i < 0) {
 +              dev_err(&data->client->dev, "initial compensation timed out");
 +              ret = -ETIMEDOUT;
 +      }
 +
 +out:
 +      regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
 +                         GENMASK(SX9500_NUM_CHANNELS, 0), 0);
 +      return ret;
 +}
 +
  static int sx9500_init_device(struct iio_dev *indio_dev)
  {
        struct sx9500_data *data = iio_priv(indio_dev);
        int ret, i;
        unsigned int val;
  
 +      if (data->gpiod_rst) {
 +              gpiod_set_value_cansleep(data->gpiod_rst, 0);
 +              usleep_range(1000, 2000);
 +              gpiod_set_value_cansleep(data->gpiod_rst, 1);
 +              usleep_range(1000, 2000);
 +      }
 +
        ret = regmap_write(data->regmap, SX9500_REG_IRQ_MSK, 0);
        if (ret < 0)
                return ret;
                        return ret;
        }
  
 -      return 0;
 +      return sx9500_init_compensation(indio_dev);
  }
  
 -static int sx9500_gpio_probe(struct i2c_client *client,
 -                           struct sx9500_data *data)
 +static void sx9500_gpio_probe(struct i2c_client *client,
 +                            struct sx9500_data *data)
  {
        struct device *dev;
        struct gpio_desc *gpio;
 -      int ret;
  
        if (!client)
 -              return -EINVAL;
 +              return;
  
        dev = &client->dev;
  
 -      /* data ready gpio interrupt pin */
 -      gpio = devm_gpiod_get_index(dev, SX9500_GPIO_NAME, 0, GPIOD_IN);
 -      if (IS_ERR(gpio)) {
 -              dev_err(dev, "acpi gpio get index failed\n");
 -              return PTR_ERR(gpio);
 +      if (client->irq <= 0) {
 +              gpio = devm_gpiod_get_index(dev, SX9500_GPIO_INT, 0, GPIOD_IN);
 +              if (IS_ERR(gpio))
 +                      dev_err(dev, "gpio get irq failed\n");
 +              else
 +                      client->irq = gpiod_to_irq(gpio);
        }
  
 -      ret = gpiod_to_irq(gpio);
 -
 -      dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
 -
 -      return ret;
 +      data->gpiod_rst = devm_gpiod_get_index(dev, SX9500_GPIO_RESET,
 +                                             0, GPIOD_OUT_HIGH);
 +      if (IS_ERR(data->gpiod_rst)) {
 +              dev_warn(dev, "gpio get reset pin failed\n");
 +              data->gpiod_rst = NULL;
 +      }
  }
  
  static int sx9500_probe(struct i2c_client *client,
        data = iio_priv(indio_dev);
        data->client = client;
        mutex_init(&data->mutex);
 +      init_completion(&data->completion);
        data->trigger_enabled = false;
  
        data->regmap = devm_regmap_init_i2c(client, &sx9500_regmap_config);
        if (IS_ERR(data->regmap))
                return PTR_ERR(data->regmap);
  
 -      sx9500_init_device(indio_dev);
 -
        indio_dev->dev.parent = &client->dev;
        indio_dev->name = SX9500_DRIVER_NAME;
        indio_dev->channels = sx9500_channels;
        indio_dev->modes = INDIO_DIRECT_MODE;
        i2c_set_clientdata(client, indio_dev);
  
 -      if (client->irq <= 0)
 -              client->irq = sx9500_gpio_probe(client, data);
 +      sx9500_gpio_probe(client, data);
  
 -      if (client->irq > 0) {
 +      ret = sx9500_init_device(indio_dev);
 +      if (ret < 0)
 +              return ret;
 +
 +      if (client->irq <= 0)
 +              dev_warn(&client->dev, "no valid irq found\n");
 +      else {
                ret = devm_request_threaded_irq(&client->dev, client->irq,
                                sx9500_irq_handler, sx9500_irq_thread_handler,
                                IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
        }
  
        ret = iio_triggered_buffer_setup(indio_dev, NULL,
 -                                       sx9500_trigger_handler, NULL);
 +                                       sx9500_trigger_handler,
 +                                       &sx9500_buffer_setup_ops);
        if (ret < 0)
                goto out_trigger_unregister;
  
@@@ -983,49 -720,6 +983,49 @@@ static int sx9500_remove(struct i2c_cli
        return 0;
  }
  
 +#ifdef CONFIG_PM_SLEEP
 +static int sx9500_suspend(struct device *dev)
 +{
 +      struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 +      struct sx9500_data *data = iio_priv(indio_dev);
 +      int ret;
 +
 +      mutex_lock(&data->mutex);
 +      ret = regmap_read(data->regmap, SX9500_REG_PROX_CTRL0,
 +                        &data->suspend_ctrl0);
 +      if (ret < 0)
 +              goto out;
 +
 +      /*
 +       * Scan period doesn't matter because when all the sensors are
 +       * deactivated the device is in sleep mode.
 +       */
 +      ret = regmap_write(data->regmap, SX9500_REG_PROX_CTRL0, 0);
 +
 +out:
 +      mutex_unlock(&data->mutex);
 +      return ret;
 +}
 +
 +static int sx9500_resume(struct device *dev)
 +{
 +      struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 +      struct sx9500_data *data = iio_priv(indio_dev);
 +      int ret;
 +
 +      mutex_lock(&data->mutex);
 +      ret = regmap_write(data->regmap, SX9500_REG_PROX_CTRL0,
 +                         data->suspend_ctrl0);
 +      mutex_unlock(&data->mutex);
 +
 +      return ret;
 +}
 +#endif /* CONFIG_PM_SLEEP */
 +
 +static const struct dev_pm_ops sx9500_pm_ops = {
 +      SET_SYSTEM_SLEEP_PM_OPS(sx9500_suspend, sx9500_resume)
 +};
 +
  static const struct acpi_device_id sx9500_acpi_match[] = {
        {"SSX9500", 0},
        { },
@@@ -1034,7 -728,7 +1034,7 @@@ MODULE_DEVICE_TABLE(acpi, sx9500_acpi_m
  
  static const struct i2c_device_id sx9500_id[] = {
        {"sx9500", 0},
 -      {}
 +      { },
  };
  MODULE_DEVICE_TABLE(i2c, sx9500_id);
  
@@@ -1042,7 -736,6 +1042,7 @@@ static struct i2c_driver sx9500_driver 
        .driver = {
                .name   = SX9500_DRIVER_NAME,
                .acpi_match_table = ACPI_PTR(sx9500_acpi_match),
 +              .pm = &sx9500_pm_ops,
        },
        .probe          = sx9500_probe,
        .remove         = sx9500_remove,
index 0042bf330b99ffa6edd77677529753bdd00b79d4,cd224dfd94d8280261c1b1f15161fccae5e245af..c02b5ce6c5cdb787c3cb5ddb1ca7652dc5fe9d1e
@@@ -74,7 -74,7 +74,7 @@@ struct sensor_hub_pending 
   * @usage:            Usage id for this hub device instance.
   * @start_collection_index: Starting index for a phy type collection
   * @end_collection_index: Last index for a phy type collection
 - * @mutex:            synchronizing mutex.
 + * @mutex_ptr:                synchronizing mutex pointer.
   * @pending:          Holds information of pending sync read request.
   */
  struct hid_sensor_hub_device {
@@@ -84,7 -84,7 +84,7 @@@
        u32 usage;
        int start_collection_index;
        int end_collection_index;
 -      struct mutex mutex;
 +      struct mutex *mutex_ptr;
        struct sensor_hub_pending pending;
  };
  
@@@ -230,6 -230,7 +230,7 @@@ struct hid_sensor_common 
        struct platform_device *pdev;
        unsigned usage_id;
        atomic_t data_ready;
+       atomic_t user_requested_state;
        struct iio_trigger *trigger;
        struct hid_sensor_hub_attribute_info poll;
        struct hid_sensor_hub_attribute_info report_state;