Merge tag 'iio-fixes-for-3.12a' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Sep 2013 23:45:36 +0000 (16:45 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 21 Sep 2013 23:45:36 +0000 (16:45 -0700)
Jonathan writes:

First round of IIO fixes for 3.12

A series of wrong 'struct dev' assumptions in suspend/resume callbacks
following on from this issue being identified in a new driver review.
One to watch out for in future.

A number of driver specific fixes
1) at91 - fix a overflow in clock rate computation
2) dummy - Kconfig dependency issue
3) isl29018 - uninitialized value
4) hmc5843 - measurement conversion bug introduced by recent cleanup.
5) ade7854-spi - wrong return value.

Some IIO core fixes
1) Wrong value picked up for event code creation for a modified channel
2) A null dereference on failure to initialize a buffer after no buffer has
   been in use, when using the available_scan_masks approach.
3) Sampling not stopped when a device is removed. Effects forced removal
   such as hot unplugging.
4) Prevent device going away if a chrdev is still open in userspace.
5) Prevent race on chardev opening and device being freed.
6) Add a missing iio_buffer_init in the call back buffer.

These last few are the first part of a set from Lars-Peter Clausen who
has been taking a closer look at our removal paths and buffer handling
than anyone has for quite some time.

13 files changed:
drivers/iio/accel/bma180.c
drivers/iio/adc/at91_adc.c
drivers/iio/buffer_cb.c
drivers/iio/dac/mcp4725.c
drivers/iio/iio_core.h
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-event.c
drivers/iio/temperature/tmp006.c
drivers/staging/iio/Kconfig
drivers/staging/iio/light/isl29018.c
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/iio/meter/ade7854-spi.c

index 12e32e6..81e3dc2 100644 (file)
@@ -620,7 +620,7 @@ static int bma180_remove(struct i2c_client *client)
 #ifdef CONFIG_PM_SLEEP
 static int bma180_suspend(struct device *dev)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
        struct bma180_data *data = iio_priv(indio_dev);
        int ret;
 
@@ -633,7 +633,7 @@ static int bma180_suspend(struct device *dev)
 
 static int bma180_resume(struct device *dev)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
        struct bma180_data *data = iio_priv(indio_dev);
        int ret;
 
index 84be63b..0f16b55 100644 (file)
@@ -556,7 +556,7 @@ static const struct iio_info at91_adc_info = {
 
 static int at91_adc_probe(struct platform_device *pdev)
 {
-       unsigned int prsc, mstrclk, ticks, adc_clk, shtim;
+       unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim;
        int ret;
        struct iio_dev *idev;
        struct at91_adc_state *st;
@@ -649,6 +649,7 @@ static int at91_adc_probe(struct platform_device *pdev)
         */
        mstrclk = clk_get_rate(st->clk);
        adc_clk = clk_get_rate(st->adc_clk);
+       adc_clk_khz = adc_clk / 1000;
        prsc = (mstrclk / (2 * adc_clk)) - 1;
 
        if (!st->startup_time) {
@@ -662,15 +663,15 @@ static int at91_adc_probe(struct platform_device *pdev)
         * defined in the electrical characteristics of the board, divided by 8.
         * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock
         */
-       ticks = round_up((st->startup_time * adc_clk /
-                         1000000) - 1, 8) / 8;
+       ticks = round_up((st->startup_time * adc_clk_khz /
+                         1000) - 1, 8) / 8;
        /*
         * a minimal Sample and Hold Time is necessary for the ADC to guarantee
         * the best converted final value between two channels selection
         * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock
         */
-       shtim = round_up((st->sample_hold_time * adc_clk /
-                         1000000) - 1, 1);
+       shtim = round_up((st->sample_hold_time * adc_clk_khz /
+                         1000) - 1, 1);
 
        reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask;
        reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask;
index 9d19ba7..415f3c6 100644 (file)
@@ -41,6 +41,8 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
                goto error_ret;
        }
 
+       iio_buffer_init(&cb_buff->buffer);
+
        cb_buff->private = private;
        cb_buff->cb = cb;
        cb_buff->buffer.access = &iio_cb_access;
index 1f4a48e..1397b6e 100644 (file)
@@ -37,21 +37,21 @@ struct mcp4725_data {
 
 static int mcp4725_suspend(struct device *dev)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct mcp4725_data *data = iio_priv(indio_dev);
+       struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
        u8 outbuf[2];
 
        outbuf[0] = (data->powerdown_mode + 1) << 4;
        outbuf[1] = 0;
        data->powerdown = true;
 
-       return i2c_master_send(to_i2c_client(dev), outbuf, 2);
+       return i2c_master_send(data->client, outbuf, 2);
 }
 
 static int mcp4725_resume(struct device *dev)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct mcp4725_data *data = iio_priv(indio_dev);
+       struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
        u8 outbuf[2];
 
        /* restore previous DAC value */
@@ -59,7 +59,7 @@ static int mcp4725_resume(struct device *dev)
        outbuf[1] = data->dac_value & 0xff;
        data->powerdown = false;
 
-       return i2c_master_send(to_i2c_client(dev), outbuf, 2);
+       return i2c_master_send(data->client, outbuf, 2);
 }
 
 #ifdef CONFIG_PM_SLEEP
index 05c1b74..9b32253 100644 (file)
@@ -49,11 +49,15 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 #define iio_buffer_poll_addr (&iio_buffer_poll)
 #define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
 
+void iio_disable_all_buffers(struct iio_dev *indio_dev);
+
 #else
 
 #define iio_buffer_poll_addr NULL
 #define iio_buffer_read_first_n_outer_addr NULL
 
+static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
+
 #endif
 
 int iio_device_register_eventset(struct iio_dev *indio_dev);
index e73033f..2710f72 100644 (file)
@@ -460,6 +460,25 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
        return bytes;
 }
 
+void iio_disable_all_buffers(struct iio_dev *indio_dev)
+{
+       struct iio_buffer *buffer, *_buffer;
+
+       if (list_empty(&indio_dev->buffer_list))
+               return;
+
+       if (indio_dev->setup_ops->predisable)
+               indio_dev->setup_ops->predisable(indio_dev);
+
+       list_for_each_entry_safe(buffer, _buffer,
+                       &indio_dev->buffer_list, buffer_list)
+               list_del_init(&buffer->buffer_list);
+
+       indio_dev->currentmode = INDIO_DIRECT_MODE;
+       if (indio_dev->setup_ops->postdisable)
+               indio_dev->setup_ops->postdisable(indio_dev);
+}
+
 int iio_update_buffers(struct iio_dev *indio_dev,
                       struct iio_buffer *insert_buffer,
                       struct iio_buffer *remove_buffer)
@@ -528,8 +547,15 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                         * Note can only occur when adding a buffer.
                         */
                        list_del(&insert_buffer->buffer_list);
-                       indio_dev->active_scan_mask = old_mask;
-                       success = -EINVAL;
+                       if (old_mask) {
+                               indio_dev->active_scan_mask = old_mask;
+                               success = -EINVAL;
+                       }
+                       else {
+                               kfree(compound_mask);
+                               ret = -EINVAL;
+                               goto error_ret;
+                       }
                }
        } else {
                indio_dev->active_scan_mask = compound_mask;
index 97f0297..8e84cd5 100644 (file)
@@ -848,8 +848,6 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
 static void iio_dev_release(struct device *device)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(device);
-       if (indio_dev->chrdev.dev)
-               cdev_del(&indio_dev->chrdev);
        if (indio_dev->modes & INDIO_BUFFER_TRIGGERED)
                iio_device_unregister_trigger_consumer(indio_dev);
        iio_device_unregister_eventset(indio_dev);
@@ -970,6 +968,8 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
        if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags))
                return -EBUSY;
 
+       iio_device_get(indio_dev);
+
        filp->private_data = indio_dev;
 
        return 0;
@@ -983,6 +983,8 @@ static int iio_chrdev_release(struct inode *inode, struct file *filp)
        struct iio_dev *indio_dev = container_of(inode->i_cdev,
                                                struct iio_dev, chrdev);
        clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
+       iio_device_put(indio_dev);
+
        return 0;
 }
 
@@ -1052,18 +1054,20 @@ int iio_device_register(struct iio_dev *indio_dev)
                indio_dev->setup_ops == NULL)
                indio_dev->setup_ops = &noop_ring_setup_ops;
 
-       ret = device_add(&indio_dev->dev);
-       if (ret < 0)
-               goto error_unreg_eventset;
        cdev_init(&indio_dev->chrdev, &iio_buffer_fileops);
        indio_dev->chrdev.owner = indio_dev->info->driver_module;
+       indio_dev->chrdev.kobj.parent = &indio_dev->dev.kobj;
        ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1);
        if (ret < 0)
-               goto error_del_device;
-       return 0;
+               goto error_unreg_eventset;
 
-error_del_device:
-       device_del(&indio_dev->dev);
+       ret = device_add(&indio_dev->dev);
+       if (ret < 0)
+               goto error_cdev_del;
+
+       return 0;
+error_cdev_del:
+       cdev_del(&indio_dev->chrdev);
 error_unreg_eventset:
        iio_device_unregister_eventset(indio_dev);
 error_free_sysfs:
@@ -1078,9 +1082,16 @@ EXPORT_SYMBOL(iio_device_register);
 void iio_device_unregister(struct iio_dev *indio_dev)
 {
        mutex_lock(&indio_dev->info_exist_lock);
+
+       device_del(&indio_dev->dev);
+
+       if (indio_dev->chrdev.dev)
+               cdev_del(&indio_dev->chrdev);
+
+       iio_disable_all_buffers(indio_dev);
+
        indio_dev->info = NULL;
        mutex_unlock(&indio_dev->info_exist_lock);
-       device_del(&indio_dev->dev);
 }
 EXPORT_SYMBOL(iio_device_unregister);
 subsys_initcall(iio_init);
index 10aa9ef..6be65ef 100644 (file)
@@ -72,7 +72,8 @@ EXPORT_SYMBOL(iio_push_event);
 static unsigned int iio_event_poll(struct file *filep,
                             struct poll_table_struct *wait)
 {
-       struct iio_event_interface *ev_int = filep->private_data;
+       struct iio_dev *indio_dev = filep->private_data;
+       struct iio_event_interface *ev_int = indio_dev->event_interface;
        unsigned int events = 0;
 
        poll_wait(filep, &ev_int->wait, wait);
@@ -90,7 +91,8 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
                                     size_t count,
                                     loff_t *f_ps)
 {
-       struct iio_event_interface *ev_int = filep->private_data;
+       struct iio_dev *indio_dev = filep->private_data;
+       struct iio_event_interface *ev_int = indio_dev->event_interface;
        unsigned int copied;
        int ret;
 
@@ -121,7 +123,8 @@ error_unlock:
 
 static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
 {
-       struct iio_event_interface *ev_int = filep->private_data;
+       struct iio_dev *indio_dev = filep->private_data;
+       struct iio_event_interface *ev_int = indio_dev->event_interface;
 
        spin_lock_irq(&ev_int->wait.lock);
        __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
@@ -133,6 +136,8 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
        kfifo_reset_out(&ev_int->det_events);
        spin_unlock_irq(&ev_int->wait.lock);
 
+       iio_device_put(indio_dev);
+
        return 0;
 }
 
@@ -158,12 +163,15 @@ int iio_event_getfd(struct iio_dev *indio_dev)
                return -EBUSY;
        }
        spin_unlock_irq(&ev_int->wait.lock);
-       fd = anon_inode_getfd("iio:event",
-                               &iio_event_chrdev_fileops, ev_int, O_RDONLY);
+       iio_device_get(indio_dev);
+
+       fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
+                               indio_dev, O_RDONLY);
        if (fd < 0) {
                spin_lock_irq(&ev_int->wait.lock);
                __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
                spin_unlock_irq(&ev_int->wait.lock);
+               iio_device_put(indio_dev);
        }
        return fd;
 }
@@ -276,7 +284,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
                        goto error_ret;
                }
                if (chan->modified)
-                       mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
+                       mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel2,
                                                  i/IIO_EV_DIR_MAX,
                                                  i%IIO_EV_DIR_MAX);
                else if (chan->differential)
index 64ccde3..6d63883 100644 (file)
@@ -255,12 +255,14 @@ static int tmp006_remove(struct i2c_client *client)
 #ifdef CONFIG_PM_SLEEP
 static int tmp006_suspend(struct device *dev)
 {
-       return tmp006_powerdown(iio_priv(dev_to_iio_dev(dev)));
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       return tmp006_powerdown(iio_priv(indio_dev));
 }
 
 static int tmp006_resume(struct device *dev)
 {
-       struct tmp006_data *data = iio_priv(dev_to_iio_dev(dev));
+       struct tmp006_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
        return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
                data->config | TMP006_CONFIG_MOD_MASK);
 }
index db4d6dc..b36feb0 100644 (file)
@@ -37,7 +37,7 @@ config IIO_SIMPLE_DUMMY_EVENTS
 
 config IIO_SIMPLE_DUMMY_BUFFER
        boolean "Buffered capture support"
-       depends on IIO_KFIFO_BUF
+       select IIO_KFIFO_BUF
        help
          Add buffered data capture to the simple dummy driver.
 
index 351936c..e4998e4 100644 (file)
@@ -563,6 +563,7 @@ static int isl29018_probe(struct i2c_client *client,
        mutex_init(&chip->lock);
 
        chip->lux_scale = 1;
+       chip->lux_uscale = 0;
        chip->range = 1000;
        chip->adc_bit = 16;
        chip->suspended = false;
index d2748c3..c3f3f53 100644 (file)
@@ -229,7 +229,7 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev,
        if (result < 0)
                return -EINVAL;
 
-       *val = result;
+       *val = sign_extend32(result, 15);
        return IIO_VAL_INT;
 }
 
index a802cf2..4c6d204 100644 (file)
@@ -299,7 +299,7 @@ static int ade7854_spi_probe(struct spi_device *spi)
        if (ret)
                iio_device_free(indio_dev);
 
-       return 0;
+       return ret;
 }
 
 static int ade7854_spi_remove(struct spi_device *spi)