Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / drivers / iio / industrialio-core.c
index e145931ef1b82906478c5a32505cada2d8eb1547..97f0297b120f41e7f73d9b5a5cf27887da146a92 100644 (file)
@@ -383,14 +383,14 @@ static ssize_t iio_read_channel_info(struct device *dev,
                scale_db = true;
        case IIO_VAL_INT_PLUS_MICRO:
                if (val2 < 0)
-                       return sprintf(buf, "-%d.%06u%s\n", val, -val2,
+                       return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2,
                                scale_db ? " dB" : "");
                else
                        return sprintf(buf, "%d.%06u%s\n", val, val2,
                                scale_db ? " dB" : "");
        case IIO_VAL_INT_PLUS_NANO:
                if (val2 < 0)
-                       return sprintf(buf, "-%d.%09u\n", val, -val2);
+                       return sprintf(buf, "-%ld.%09u\n", abs(val), -val2);
                else
                        return sprintf(buf, "%d.%09u\n", val, val2);
        case IIO_VAL_FRACTIONAL:
@@ -912,6 +912,53 @@ void iio_device_free(struct iio_dev *dev)
 }
 EXPORT_SYMBOL(iio_device_free);
 
+static void devm_iio_device_release(struct device *dev, void *res)
+{
+       iio_device_free(*(struct iio_dev **)res);
+}
+
+static int devm_iio_device_match(struct device *dev, void *res, void *data)
+{
+       struct iio_dev **r = res;
+       if (!r || !*r) {
+               WARN_ON(!r || !*r);
+               return 0;
+       }
+       return *r == data;
+}
+
+struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
+{
+       struct iio_dev **ptr, *iio_dev;
+
+       ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr),
+                          GFP_KERNEL);
+       if (!ptr)
+               return NULL;
+
+       /* use raw alloc_dr for kmalloc caller tracing */
+       iio_dev = iio_device_alloc(sizeof_priv);
+       if (iio_dev) {
+               *ptr = iio_dev;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return iio_dev;
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
+
+void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
+{
+       int rc;
+
+       rc = devres_release(dev, devm_iio_device_release,
+                           devm_iio_device_match, iio_dev);
+       WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_free);
+
 /**
  * iio_chrdev_open() - chrdev file open for buffer access and ioctls
  **/