staging:iio: rework of attribute registration.

This set also includes quite a number of bug fixes of particularly
remove functions.

Necessary due to issue pointed out in Bart Van Assche's patch:
docs/driver-model: Document device.groups

V2: Rebase due to patch reordering.
V3: Pull various error fixes and cleanups out into their own patches.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Acked-by: Michael Hennerich <Michael.Hennerich@analog.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 1e19aba..2785460 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -463,7 +463,7 @@
 
 static int __devinit adis16201_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16201_state *st;
 	struct iio_dev *indio_dev;
 
@@ -492,11 +492,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       adis16201_channels,
 				       ARRAY_SIZE(adis16201_channels));
@@ -515,6 +510,10 @@
 	ret = adis16201_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
@@ -524,10 +523,7 @@
 error_unreg_ring_funcs:
 	adis16201_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 2a658f0..27079a9 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -419,7 +419,7 @@
 
 static int __devinit adis16203_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct iio_dev *indio_dev;
 	struct adis16203_state *st;
 
@@ -446,11 +446,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       adis16203_channels,
 				       ARRAY_SIZE(adis16203_channels));
@@ -469,6 +464,11 @@
 	ret = adis16203_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -478,10 +478,7 @@
 error_unreg_ring_funcs:
 	adis16203_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index 42a37bb..e0b8784 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -494,7 +494,7 @@
 
 static int __devinit adis16204_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16204_state *st;
 	struct iio_dev *indio_dev;
 
@@ -521,11 +521,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       adis16204_channels,
 				       ARRAY_SIZE(adis16204_channels));
@@ -544,6 +539,10 @@
 	ret = adis16204_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -553,10 +552,7 @@
 error_unreg_ring_funcs:
 	adis16204_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index d59a9e4..377c6d7 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -467,7 +467,7 @@
 
 static int __devinit adis16209_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16209_state *st;
 	struct iio_dev *indio_dev;
 
@@ -494,11 +494,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       adis16209_channels,
 				       ARRAY_SIZE(adis16209_channels));
@@ -517,6 +512,10 @@
 	ret = adis16209_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -526,10 +525,7 @@
 error_unreg_ring_funcs:
 	adis16209_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index b6504f1..0dd02a3 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -519,7 +519,7 @@
 
 static int __devinit adis16240_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16240_state *st;
 	struct iio_dev *indio_dev;
 
@@ -547,11 +547,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       adis16240_channels,
 				       ARRAY_SIZE(adis16240_channels));
@@ -570,6 +565,9 @@
 	ret = adis16240_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
@@ -579,10 +577,7 @@
 error_unreg_ring_funcs:
 	adis16240_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 61d114a..ee91cc7 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -663,7 +663,7 @@
 
 static int __devinit lis3l02dq_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct lis3l02dq_state *st;
 	struct iio_dev *indio_dev;
 
@@ -690,11 +690,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       lis3l02dq_channels,
 				       ARRAY_SIZE(lis3l02dq_channels));
@@ -722,6 +717,11 @@
 	ret = lis3l02dq_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -735,9 +735,6 @@
 error_unreg_ring_funcs:
 	lis3l02dq_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
 		iio_free_device(indio_dev);
 error_ret:
 	return ret;
@@ -790,9 +787,8 @@
 	lis3l02dq_remove_trigger(indio_dev);
 	iio_ring_buffer_unregister(indio_dev);
 	lis3l02dq_unconfigure_ring(indio_dev);
-	iio_device_unregister(indio_dev);
 
-	return 0;
+	iio_device_unregister(indio_dev);
 
 err_ret:
 	return ret;
diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
index d70623c..3d154b8 100644
--- a/drivers/staging/iio/adc/ad7150.c
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -719,7 +719,7 @@
 static int __devinit ad7150_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
-	int ret = 0, regdone = 0;
+	int ret;
 	struct ad7150_chip_info *chip;
 	struct iio_dev *indio_dev;
 
@@ -742,11 +742,6 @@
 
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-	regdone = 1;
-
 	if (client->irq) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
@@ -759,15 +754,20 @@
 			goto error_free_dev;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_irq;
+
+
 	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
 
 	return 0;
+error_free_irq:
+	if (client->irq)
+		free_irq(client->irq, indio_dev);
 
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 16ddbde..46a891d 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -811,10 +811,6 @@
 	indio_dev->info = &ad7291_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
 	if (client->irq > 0) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
@@ -823,7 +819,7 @@
 					   id->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_dev;
+			goto error_free_dev;
 
 		/* set irq polarity low level */
 		chip->command |= AD7291_ALART_POLARITY;
@@ -835,6 +831,10 @@
 		goto error_unreg_irq;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unreg_irq;
+
 	dev_info(&client->dev, "%s temperature sensor registered.\n",
 			 id->name);
 
@@ -842,8 +842,6 @@
 
 error_unreg_irq:
 	free_irq(client->irq, indio_dev);
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 6487359..a627bfe 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -165,7 +165,7 @@
 {
 	struct ad7298_platform_data *pdata = spi->dev.platform_data;
 	struct ad7298_state *st;
-	int ret, regdone = 0;
+	int ret;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
 	if (indio_dev == NULL)
@@ -218,19 +218,19 @@
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_disable_reg;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       &ad7298_channels[1], /* skip temp0 */
 				       ARRAY_SIZE(ad7298_channels) - 1);
 	if (ret)
 		goto error_cleanup_ring;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unregister_ring;
 
 	return 0;
 
+error_unregister_ring:
+	iio_ring_buffer_unregister(indio_dev);
 error_cleanup_ring:
 	ad7298_ring_cleanup(indio_dev);
 error_disable_reg:
@@ -239,11 +239,7 @@
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index 7329b00..edf25ce 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -129,7 +129,6 @@
 	struct ad7476_state *st;
 	struct iio_dev *indio_dev;
 	int ret, voltage_uv = 0;
-	bool reg_done = false;
 
 	indio_dev = iio_allocate_device(sizeof(*st));
 	if (indio_dev == NULL) {
@@ -180,28 +179,29 @@
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_disable_reg;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       st->chip_info->channel,
 				       ARRAY_SIZE(st->chip_info->channel));
 	if (ret)
 		goto error_cleanup_ring;
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_ring_unregister;
 	return 0;
 
+error_ring_unregister:
+	iio_ring_buffer_unregister(indio_dev);
 error_cleanup_ring:
 	ad7476_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	if (!reg_done)
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
+
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 7b43da9..bea663d 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -439,7 +439,7 @@
 {
 	struct ad7606_platform_data *pdata = dev->platform_data;
 	struct ad7606_state *st;
-	int ret, regdone = 0;
+	int ret;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
 	if (indio_dev == NULL) {
@@ -501,18 +501,18 @@
 	if (ret)
 		goto error_free_irq;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_irq;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       indio_dev->channels,
 				       indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unregister_ring;
 
 	return indio_dev;
+error_unregister_ring:
+	iio_ring_buffer_unregister(indio_dev);
 
 error_cleanup_ring:
 	ad7606_ring_cleanup(indio_dev);
@@ -529,10 +529,7 @@
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ERR_PTR(ret);
 }
diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c
index 41150c6..eea77f1 100644
--- a/drivers/staging/iio/adc/ad7745.c
+++ b/drivers/staging/iio/adc/ad7745.c
@@ -578,7 +578,7 @@
 static int __devinit ad774x_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
-	int ret = 0, regdone = 0;
+	int ret;
 	struct ad774x_chip_info *chip;
 	struct iio_dev *indio_dev;
 
@@ -599,11 +599,6 @@
 	indio_dev->info = &ad774x_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-	regdone = 1;
-
 	if (client->irq) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
@@ -615,15 +610,18 @@
 			goto error_free_dev;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_irq;
+
 	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
 
 	return 0;
 
+error_free_irq:
+	free_irq(client->irq, indio_dev);
 error_free_dev:
-	if (regdone)
-		free_irq(client->irq, indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index b42a7ac..17d18fc 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -827,7 +827,7 @@
 	struct ad7793_platform_data *pdata = spi->dev.platform_data;
 	struct ad7793_state *st;
 	struct iio_dev *indio_dev;
-	int ret, i, voltage_uv = 0, regdone = 0;
+	int ret, i, voltage_uv = 0;
 
 	if (!pdata) {
 		dev_err(&spi->dev, "no platform data?\n");
@@ -890,11 +890,6 @@
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring;
-	regdone = 1;
-
 	ret = ad7793_probe_trigger(indio_dev);
 	if (ret)
 		goto error_unreg_ring;
@@ -909,6 +904,10 @@
 	if (ret)
 		goto error_uninitialize_ring;
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_uninitialize_ring;
+
 	return 0;
 
 error_uninitialize_ring:
@@ -924,10 +923,7 @@
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
 
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 5a4586f..deec8f2 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -396,10 +396,6 @@
 	indio_dev->info = &ad7816_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_gpio;
-
 	if (spi_dev->irq) {
 		/* Only low trigger is supported in ad7816/7/8 */
 		ret = request_threaded_irq(spi_dev->irq,
@@ -409,16 +405,19 @@
 					   indio_dev->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_dev;
+			goto error_free_gpio;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_irq;
+
 	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
 			 indio_dev->name);
 
 	return 0;
-
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
+error_free_irq:
+	free_irq(spi_dev->irq, indio_dev);
 error_free_gpio:
 	gpio_free(chip->busy_pin);
 error_free_gpio_convert:
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index e71d088..cdd7c13 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -93,7 +93,7 @@
 {
 	struct ad7887_platform_data *pdata = spi->dev.platform_data;
 	struct ad7887_state *st;
-	int ret, voltage_uv = 0, regdone = 0;
+	int ret, voltage_uv = 0;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
 	if (indio_dev == NULL)
@@ -189,18 +189,19 @@
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_disable_reg;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       indio_dev->channels,
 				       indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
-	return 0;
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unregister_ring;
+
+	return 0;
+error_unregister_ring:
+	iio_ring_buffer_unregister(indio_dev);
 error_cleanup_ring:
 	ad7887_ring_cleanup(indio_dev);
 error_disable_reg:
@@ -209,10 +210,7 @@
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index cfe4b2c..75b8c37 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -657,7 +657,7 @@
 static int __devinit ad799x_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct ad799x_platform_data *pdata = client->dev.platform_data;
 	struct ad799x_state *st;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
@@ -701,11 +701,6 @@
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_cleanup_ring;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       indio_dev->channels,
 				       indio_dev->num_channels);
@@ -723,9 +718,14 @@
 		if (ret)
 			goto error_cleanup_ring;
 	}
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_irq;
 
 	return 0;
 
+error_free_irq:
+	free_irq(client->irq, indio_dev);
 error_cleanup_ring:
 	ad799x_ring_cleanup(indio_dev);
 error_disable_reg:
@@ -734,10 +734,7 @@
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index edc65c5..cbbd349 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -782,10 +782,6 @@
 	indio_dev->info = &adt7310_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
 	/* CT critcal temperature event. line 0 */
 	if (spi_dev->irq) {
 		if (adt7310_platform_data[2])
@@ -799,7 +795,7 @@
 					   indio_dev->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_dev;
+			goto error_free_dev;
 	}
 
 	/* INT bound temperature alarm event. line 1 */
@@ -836,6 +832,10 @@
 		}
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unreg_int_irq;
+
 	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
 			indio_dev->name);
 
@@ -845,8 +845,6 @@
 	free_irq(adt7310_platform_data[0], indio_dev);
 error_unreg_ct_irq:
 	free_irq(spi_dev->irq, indio_dev);
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index e7e9e25..cc913bc 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -749,10 +749,6 @@
 	indio_dev->info = &adt7410_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
 	/* CT critcal temperature event. line 0 */
 	if (client->irq) {
 		ret = request_threaded_irq(client->irq,
@@ -762,7 +758,7 @@
 					   id->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_dev;
+			goto error_free_dev;
 	}
 
 	/* INT bound temperature alarm event. line 1 */
@@ -799,6 +795,9 @@
 			goto error_unreg_int_irq;
 		}
 	}
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unreg_int_irq;
 
 	dev_info(&client->dev, "%s temperature sensor registered.\n",
 			 id->name);
@@ -809,8 +808,6 @@
 	free_irq(adt7410_platform_data[0], indio_dev);
 error_unreg_ct_irq:
 	free_irq(client->irq, indio_dev);
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
index b56bfcd..08215e9 100644
--- a/drivers/staging/iio/adc/adt75.c
+++ b/drivers/staging/iio/adc/adt75.c
@@ -567,10 +567,6 @@
 	indio_dev->info = &adt75_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
 	if (client->irq > 0) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
@@ -579,7 +575,7 @@
 					   indio_dev->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_dev;
+			goto error_free_dev;
 
 		ret = adt75_i2c_read(indio_dev, ADT75_CONFIG, &chip->config);
 		if (ret) {
@@ -597,14 +593,16 @@
 		}
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unreg_irq;
+
 	dev_info(&client->dev, "%s temperature sensor registered.\n",
 			 indio_dev->name);
 
 	return 0;
 error_unreg_irq:
 	free_irq(client->irq, indio_dev);
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index adbd89b..9962f59 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -1254,7 +1254,7 @@
 static int __devinit max1363_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 {
-	int ret, i, regdone = 0;
+	int ret, i;
 	struct max1363_state *st;
 	struct iio_dev *indio_dev;
 	struct regulator *reg;
@@ -1312,10 +1312,6 @@
 	if (ret)
 		goto error_free_available_scan_masks;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_cleanup_ring;
-	regdone = 1;
 	ret = iio_ring_buffer_register(indio_dev,
 				       st->chip_info->channels,
 				       st->chip_info->num_channels);
@@ -1334,8 +1330,13 @@
 			goto error_uninit_ring;
 	}
 
-	return 0;
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto error_free_irq;
 
+	return 0;
+error_free_irq:
+	free_irq(st->client->irq, indio_dev);
 error_uninit_ring:
 	iio_ring_buffer_unregister(indio_dev);
 error_cleanup_ring:
@@ -1343,10 +1344,7 @@
 error_free_available_scan_masks:
 	kfree(indio_dev->available_scan_masks);
 error_free_device:
-	if (!regdone)
-		iio_free_device(indio_dev);
-	else
-		iio_device_unregister(indio_dev);
+	iio_free_device(indio_dev);
 error_disable_reg:
 	regulator_disable(reg);
 error_put_reg:
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index e60a9d6..17b6c13 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -2167,10 +2167,6 @@
 	indio_dev->name = name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
 	if (chip->bus.irq > 0) {
 		if (adt7316_platform_data[0])
 			chip->bus.irq_flags = adt7316_platform_data[0];
@@ -2182,7 +2178,7 @@
 					   indio_dev->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_dev;
+			goto error_free_dev;
 
 		if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
 			chip->config1 |= ADT7316_INT_POLARITY;
@@ -2200,6 +2196,10 @@
 		goto error_unreg_irq;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_unreg_irq;
+
 	dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
 			indio_dev->name);
 
@@ -2207,8 +2207,6 @@
 
 error_unreg_irq:
 	free_irq(chip->bus.irq, indio_dev);
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
@@ -2221,7 +2219,6 @@
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = iio_priv(indio_dev);
 
-	dev_set_drvdata(dev, NULL);
 	if (chip->bus.irq)
 		free_irq(chip->bus.irq, indio_dev);
 	iio_device_unregister(indio_dev);
diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
index 9a421f2..c528dff 100644
--- a/drivers/staging/iio/dac/ad5504.c
+++ b/drivers/staging/iio/dac/ad5504.c
@@ -282,6 +282,11 @@
 	struct regulator *reg;
 	int ret, voltage_uv = 0;
 
+	indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
 	reg = regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(reg)) {
 		ret = regulator_enable(reg);
@@ -291,11 +296,6 @@
 		voltage_uv = regulator_get_voltage(reg);
 	}
 
-	indio_dev = iio_allocate_device(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
 	spi_set_drvdata(spi, indio_dev);
 	st = iio_priv(indio_dev);
 	if (voltage_uv)
@@ -315,10 +315,6 @@
 		indio_dev->info = &ad5504_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
 	if (spi->irq) {
 		ret = request_threaded_irq(spi->irq,
 					   NULL,
@@ -327,15 +323,17 @@
 					   spi_get_device_id(st->spi)->name,
 					   indio_dev);
 		if (ret)
-			goto error_unreg_iio_device;
+			goto error_disable_reg;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_irq;
+
 	return 0;
 
-error_unreg_iio_device:
-	iio_device_unregister(indio_dev);
-error_free_dev:
-	iio_free_device(indio_dev);
+error_free_irq:
+	free_irq(spi->irq, indio_dev);
 error_disable_reg:
 	if (!IS_ERR(reg))
 		regulator_disable(reg);
@@ -343,6 +341,8 @@
 	if (!IS_ERR(reg))
 		regulator_put(reg);
 
+	iio_free_device(indio_dev);
+error_ret:
 	return ret;
 }
 
@@ -350,17 +350,17 @@
 {
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct ad5504_state *st = iio_priv(indio_dev);
-	struct regulator *reg = st->reg;
+
 	if (spi->irq)
 		free_irq(spi->irq, indio_dev);
 
-	iio_device_unregister(indio_dev);
-
-	if (!IS_ERR(reg)) {
-		regulator_disable(reg);
-		regulator_put(reg);
+	if (!IS_ERR(st->reg)) {
+		regulator_disable(st->reg);
+		regulator_put(st->reg);
 	}
 
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
index 0f1d431..e5edf59 100644
--- a/drivers/staging/iio/dac/ad5624r_spi.c
+++ b/drivers/staging/iio/dac/ad5624r_spi.c
@@ -272,7 +272,6 @@
 
 	return 0;
 
-
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c
index c32789f..6e76820 100644
--- a/drivers/staging/iio/dac/ad5686.c
+++ b/drivers/staging/iio/dac/ad5686.c
@@ -393,16 +393,16 @@
 	indio_dev->channels = st->chip_info->channel;
 	indio_dev->num_channels = AD5686_DAC_CHANNELS;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_disable_reg;
-
 	regdone = 1;
 	ret = ad5686_spi_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0,
 				!!voltage_uv, 0);
 	if (ret)
 		goto error_disable_reg;
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_disable_reg;
+
 	return 0;
 
 error_disable_reg:
@@ -412,10 +412,7 @@
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
 
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
index 5a5de97..74f5406 100644
--- a/drivers/staging/iio/dac/ad5791.c
+++ b/drivers/staging/iio/dac/ad5791.c
@@ -396,6 +396,8 @@
 	}
 	iio_device_unregister(indio_dev);
 
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
index 3f50873..4810805 100644
--- a/drivers/staging/iio/gyro/adis16060_core.c
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -143,7 +143,7 @@
 
 static int __devinit adis16060_r_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16060_state *st;
 	struct iio_dev *indio_dev;
 
@@ -169,16 +169,12 @@
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_free_dev;
-	regdone = 1;
 
 	adis16060_iio_dev = indio_dev;
 	return 0;
 
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index 16ba0e1..826f8f1 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -137,7 +137,7 @@
 
 static int __devinit adis16080_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16080_state *st;
 	struct iio_dev *indio_dev;
 
@@ -165,15 +165,10 @@
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_free_dev;
-	regdone = 1;
-
 	return 0;
 
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index acd17e5..73157b2 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -577,7 +577,7 @@
 
 static int __devinit adis16260_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16260_platform_data *pd = spi->dev.platform_data;
 	struct adis16260_state *st;
 	struct iio_dev *indio_dev;
@@ -625,10 +625,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
 	ret = iio_ring_buffer_register(indio_dev,
 				       indio_dev->channels,
 				       ARRAY_SIZE(adis16260_channels_x));
@@ -654,6 +650,10 @@
 	ret = adis16260_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -663,10 +663,7 @@
 error_unreg_ring_funcs:
 	adis16260_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index fad88fc..a59988f 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -283,9 +283,12 @@
  * @num_channels:	[DRIVER] number of chanels specified in @channels.
  * @channel_attr_list:	[INTERN] keep track of automatically created channel
  *			attributes
+ * @chan_attr_group:	[INTERN] group for all attrs in base directory
  * @name:		[DRIVER] name of the device.
  * @info:		[DRIVER] callbacks and constant info from driver
  * @chrdev:		[INTERN] associated character device
+ * @groups:		[INTERN] attribute groups
+ * @groupcounter:	[INTERN] index of next attribute group
  **/
 struct iio_dev {
 	int				id;
@@ -308,9 +311,13 @@
 	int				num_channels;
 
 	struct list_head		channel_attr_list;
+	struct attribute_group		chan_attr_group;
 	const char			*name;
 	const struct iio_info		*info;
 	struct cdev			chrdev;
+#define IIO_MAX_GROUPS 6
+	const struct attribute_group	*groups[IIO_MAX_GROUPS + 1];
+	int				groupcounter;
 };
 
 /**
diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h
index d7eb0d8..3a80dbf 100644
--- a/drivers/staging/iio/iio_core.h
+++ b/drivers/staging/iio/iio_core.h
@@ -14,7 +14,6 @@
 #define _IIO_CORE_H_
 
 int __iio_add_chan_devattr(const char *postfix,
-			   const char *group,
 			   struct iio_chan_spec const *chan,
 			   ssize_t (*func)(struct device *dev,
 					   struct device_attribute *attr,
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index e199bbe..65399d1 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -675,7 +675,7 @@
 static int __devinit ad5933_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 {
-	int ret, regdone = 0, voltage_uv = 0;
+	int ret, voltage_uv = 0;
 	struct ad5933_platform_data *pdata = client->dev.platform_data;
 	struct ad5933_state *st;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
@@ -727,11 +727,6 @@
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring;
-	regdone = 1;
-
 	/* skip temp0_input, register in0_(real|imag)_raw */
 	ret = iio_ring_buffer_register(indio_dev, &ad5933_channels[1], 2);
 	if (ret)
@@ -745,6 +740,10 @@
 	if (ret)
 		goto error_uninitialize_ring;
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_uninitialize_ring;
+
 	return 0;
 
 error_uninitialize_ring:
@@ -758,10 +757,7 @@
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
 
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 	return ret;
 }
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 3e8fcd3..0fca3bf 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -821,7 +821,7 @@
 
 static int __devinit adis16400_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct adis16400_state *st;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 	if (indio_dev == NULL) {
@@ -848,11 +848,6 @@
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       st->variant->channels,
 				       st->variant->num_channels);
@@ -871,6 +866,10 @@
 	ret = adis16400_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -881,10 +880,7 @@
 error_unreg_ring_funcs:
 	adis16400_unconfigure_ring(indio_dev);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 2af056c..49322bf 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -119,6 +119,7 @@
 	int					current_events;
 	struct list_head dev_attr_list;
 	unsigned long flags;
+	struct attribute_group			group;
 };
 
 int iio_push_event(struct iio_dev *dev_info, u64 ev_code, s64 timestamp)
@@ -506,7 +507,6 @@
 }
 
 int __iio_add_chan_devattr(const char *postfix,
-			   const char *group,
 			   struct iio_chan_spec const *chan,
 			   ssize_t (*readfunc)(struct device *dev,
 					       struct device_attribute *attr,
@@ -544,12 +544,6 @@
 			ret = -EBUSY;
 			goto error_device_attr_deinit;
 		}
-
-	ret = sysfs_add_file_to_group(&dev->kobj,
-				      &iio_attr->dev_attr.attr, group);
-	if (ret < 0)
-		goto error_device_attr_deinit;
-
 	list_add(&iio_attr->l, attr_list);
 
 	return 0;
@@ -565,13 +559,13 @@
 static int iio_device_add_channel_sysfs(struct iio_dev *dev_info,
 					struct iio_chan_spec const *chan)
 {
-	int ret, i;
+	int ret, i, attrcount = 0;
 
 	if (chan->channel < 0)
 		return 0;
 
 	ret = __iio_add_chan_devattr(iio_data_type_name[chan->processed_val],
-				     NULL, chan,
+				     chan,
 				     &iio_read_channel_info,
 				     (chan->output ?
 				      &iio_write_channel_info : NULL),
@@ -581,10 +575,11 @@
 				     &dev_info->channel_attr_list);
 	if (ret)
 		goto error_ret;
+	attrcount++;
 
 	for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) {
 		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2],
-					     NULL, chan,
+					     chan,
 					     &iio_read_channel_info,
 					     &iio_write_channel_info,
 					     (1 << i),
@@ -597,7 +592,9 @@
 		}
 		if (ret < 0)
 			goto error_ret;
+		attrcount++;
 	}
+	ret = attrcount;
 error_ret:
 	return ret;
 }
@@ -605,8 +602,6 @@
 static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
 						 struct iio_dev_attr *p)
 {
-	sysfs_remove_file_from_group(&dev_info->dev.kobj,
-				     &p->dev_attr.attr, NULL);
 	kfree(p->dev_attr.attr.name);
 	kfree(p);
 }
@@ -621,31 +616,19 @@
 
 static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
 
-static struct attribute *iio_base_dummy_attrs[] = {
-	NULL
-};
-static struct attribute_group iio_base_dummy_group = {
-	.attrs = iio_base_dummy_attrs,
-};
-
 static int iio_device_register_sysfs(struct iio_dev *dev_info)
 {
-	int i, ret = 0;
+	int i, ret = 0, attrcount, attrn, attrcount_orig = 0;
 	struct iio_dev_attr *p, *n;
+	struct attribute **attr;
 
-	if (dev_info->info->attrs)
-		ret = sysfs_create_group(&dev_info->dev.kobj,
-					 dev_info->info->attrs);
-	else
-		ret = sysfs_create_group(&dev_info->dev.kobj,
-					 &iio_base_dummy_group);
-	
-	if (ret) {
-		dev_err(dev_info->dev.parent,
-			"Failed to register sysfs hooks\n");
-		goto error_ret;
+	/* First count elements in any existing group */
+	if (dev_info->info->attrs) {
+		attr = dev_info->info->attrs->attrs;
+		while (*attr++ != NULL)
+			attrcount_orig++;
 	}
-
+	attrcount = attrcount_orig;
 	/*
 	 * New channel registration method - relies on the fact a group does
 	 *  not need to be initialized if it is name is NULL.
@@ -658,14 +641,36 @@
 							   ->channels[i]);
 			if (ret < 0)
 				goto error_clear_attrs;
+			attrcount += ret;
 		}
-	if (dev_info->name) { 
-		ret = sysfs_add_file_to_group(&dev_info->dev.kobj,
-					      &dev_attr_name.attr,
-					      NULL);
-		if (ret)
-			goto error_clear_attrs;
+
+	if (dev_info->name)
+		attrcount++;
+
+	dev_info->chan_attr_group.attrs
+		= kzalloc(sizeof(dev_info->chan_attr_group.attrs[0])*
+			  (attrcount + 1),
+			  GFP_KERNEL);
+	if (dev_info->chan_attr_group.attrs == NULL) {
+		ret = -ENOMEM;
+		goto error_clear_attrs;
 	}
+	/* Copy across original attributes */
+	if (dev_info->info->attrs)
+		memcpy(dev_info->chan_attr_group.attrs,
+		       dev_info->info->attrs->attrs,
+		       sizeof(dev_info->chan_attr_group.attrs[0])
+		       *attrcount_orig);
+	attrn = attrcount_orig;
+	/* Add all elements from the list. */
+	list_for_each_entry(p, &dev_info->channel_attr_list, l)
+		dev_info->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr;
+	if (dev_info->name)
+		dev_info->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr;
+
+	dev_info->groups[dev_info->groupcounter++] =
+		&dev_info->chan_attr_group;
+
 	return 0;
 
 error_clear_attrs:
@@ -674,32 +679,20 @@
 		list_del(&p->l);
 		iio_device_remove_and_free_read_attr(dev_info, p);
 	}
-	if (dev_info->info->attrs)
-		sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs);
-	else
-		sysfs_remove_group(&dev_info->dev.kobj, &iio_base_dummy_group);
-error_ret:
-	return ret;
 
+	return ret;
 }
 
 static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 {
 
 	struct iio_dev_attr *p, *n;
-	if (dev_info->name)
-		sysfs_remove_file_from_group(&dev_info->dev.kobj,
-					     &dev_attr_name.attr,
-					     NULL);
+
 	list_for_each_entry_safe(p, n, &dev_info->channel_attr_list, l) {
 		list_del(&p->l);
 		iio_device_remove_and_free_read_attr(dev_info, p);
 	}
-
-	if (dev_info->info->attrs)
-		sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs);
-	else
-		sysfs_remove_group(&dev_info->dev.kobj, &iio_base_dummy_group);
+	kfree(dev_info->chan_attr_group.attrs);
 }
 
 static const char * const iio_ev_type_text[] = {
@@ -790,7 +783,7 @@
 static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 				      struct iio_chan_spec const *chan)
 {
-	int ret = 0, i, mask = 0;
+	int ret = 0, i, mask = 0, attrcount = 0;
 	char *postfix;
 	if (!chan->event_mask)
 		return 0;
@@ -820,7 +813,6 @@
 						    i%IIO_EV_TYPE_MAX);
 
 		ret = __iio_add_chan_devattr(postfix,
-					     "events",
 					     chan,
 					     &iio_ev_state_show,
 					     iio_ev_state_store,
@@ -832,7 +824,7 @@
 		kfree(postfix);
 		if (ret)
 			goto error_ret;
-
+		attrcount++;
 		postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
 				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
 				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
@@ -840,7 +832,7 @@
 			ret = -ENOMEM;
 			goto error_ret;
 		}
-		ret = __iio_add_chan_devattr(postfix, "events", chan,
+		ret = __iio_add_chan_devattr(postfix, chan,
 					     iio_ev_value_show,
 					     iio_ev_value_store,
 					     mask,
@@ -851,9 +843,9 @@
 		kfree(postfix);
 		if (ret)
 			goto error_ret;
-
+		attrcount++;
 	}
-
+	ret = attrcount;
 error_ret:
 	return ret;
 }
@@ -864,9 +856,6 @@
 	list_for_each_entry_safe(p, n,
 				 &dev_info->event_interface->
 				 dev_attr_list, l) {
-		sysfs_remove_file_from_group(&dev_info->dev.kobj,
-					     &p->dev_attr.attr,
-					     NULL);
 		kfree(p->dev_attr.attr.name);
 		kfree(p);
 	}
@@ -874,18 +863,18 @@
 
 static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info)
 {
-	int j;
-	int ret;
+	int j, ret, attrcount = 0;
 
 	INIT_LIST_HEAD(&dev_info->event_interface->dev_attr_list);
 	/* Dynically created from the channels array */
 	for (j = 0; j < dev_info->num_channels; j++) {
 		ret = iio_device_add_event_sysfs(dev_info,
 						 &dev_info->channels[j]);
-		if (ret)
+		if (ret < 0)
 			goto error_clear_attrs;
+		attrcount += ret;
 	}
-	return 0;
+	return attrcount;
 
 error_clear_attrs:
 	__iio_remove_event_config_attrs(dev_info);
@@ -893,15 +882,6 @@
 	return ret;
 }
 
-static struct attribute *iio_events_dummy_attrs[] = {
-	NULL
-};
-
-static struct attribute_group iio_events_dummy_group = {
-	.name = "events",
-	.attrs = iio_events_dummy_attrs
-};
-
 static bool iio_check_for_dynamic_events(struct iio_dev *dev_info)
 {
 	int j;
@@ -922,9 +902,12 @@
 	init_waitqueue_head(&ev_int->wait);
 }
 
+static const char *iio_event_group_name = "events";
 static int iio_device_register_eventset(struct iio_dev *dev_info)
 {
-	int ret = 0;
+	struct iio_dev_attr *p;
+	int ret = 0, attrcount_orig = 0, attrcount, attrn;
+	struct attribute **attr;
 
 	if (!(dev_info->info->event_attrs ||
 	      iio_check_for_dynamic_events(dev_info)))
@@ -938,41 +921,48 @@
 	}
 
 	iio_setup_ev_int(dev_info->event_interface);
-	if (dev_info->info->event_attrs != NULL)
-		ret = sysfs_create_group(&dev_info->dev.kobj,
-					 dev_info->info->event_attrs);
-	else
-		ret = sysfs_create_group(&dev_info->dev.kobj,
-					 &iio_events_dummy_group);
-	if (ret) {
-		dev_err(&dev_info->dev,
-			"Failed to register sysfs for event attrs");
-		goto error_free_setup_event_lines;
+	if (dev_info->info->event_attrs != NULL) {
+		attr = dev_info->info->event_attrs->attrs;
+		while (*attr++ != NULL)
+			attrcount_orig++;
 	}
+	attrcount = attrcount_orig;
 	if (dev_info->channels) {
 		ret = __iio_add_event_config_attrs(dev_info);
-		if (ret) {
-			if (dev_info->info->event_attrs != NULL)
-				sysfs_remove_group(&dev_info->dev.kobj,
-						   dev_info->info
-						   ->event_attrs);
-			else
-				sysfs_remove_group(&dev_info->dev.kobj,
-						   &iio_events_dummy_group);
+		if (ret < 0)
 			goto error_free_setup_event_lines;
-		}
+		attrcount += ret;
 	}
 
+	dev_info->event_interface->group.name = iio_event_group_name;
+	dev_info->event_interface->group.attrs =
+		kzalloc(sizeof(dev_info->event_interface->group.attrs[0])
+			*(attrcount + 1),
+			GFP_KERNEL);
+	if (dev_info->event_interface->group.attrs == NULL) {
+		ret = -ENOMEM;
+		goto error_free_setup_event_lines;
+	}
+	if (dev_info->info->event_attrs)
+		memcpy(dev_info->event_interface->group.attrs,
+		       dev_info->info->event_attrs->attrs,
+		       sizeof(dev_info->event_interface->group.attrs[0])
+		       *attrcount_orig);
+	attrn = attrcount_orig;
+	/* Add all elements from the list. */
+	list_for_each_entry(p,
+			    &dev_info->event_interface->dev_attr_list,
+			    l)
+		dev_info->event_interface->group.attrs[attrn++] =
+			&p->dev_attr.attr;
+
+	dev_info->groups[dev_info->groupcounter++] =
+		&dev_info->event_interface->group;
+
 	return 0;
 
 error_free_setup_event_lines:
 	__iio_remove_event_config_attrs(dev_info);
-	if (dev_info->info->event_attrs != NULL)
-		sysfs_remove_group(&dev_info->dev.kobj,
-				   dev_info->info->event_attrs);
-	else
-		sysfs_remove_group(&dev_info->dev.kobj,
-				   &iio_events_dummy_group);
 	kfree(dev_info->event_interface);
 error_ret:
 
@@ -984,12 +974,7 @@
 	if (dev_info->event_interface == NULL)
 		return;
 	__iio_remove_event_config_attrs(dev_info);
-	if (dev_info->info->event_attrs != NULL)
-		sysfs_remove_group(&dev_info->dev.kobj,
-				   dev_info->info->event_attrs);
-	else
-		sysfs_remove_group(&dev_info->dev.kobj,
-				   &iio_events_dummy_group);
+	kfree(dev_info->event_interface->group.attrs);
 	kfree(dev_info->event_interface);
 }
 
@@ -997,6 +982,11 @@
 {
 	struct iio_dev *dev_info = container_of(device, struct iio_dev, dev);
 	cdev_del(&dev_info->chrdev);
+	if (dev_info->modes & INDIO_RING_TRIGGERED)
+		iio_device_unregister_trigger_consumer(dev_info);
+	iio_device_unregister_eventset(dev_info);
+	iio_device_unregister_sysfs(dev_info);
+	ida_simple_remove(&iio_ida, dev_info->id);
 	kfree(dev_info);
 }
 
@@ -1021,6 +1011,7 @@
 	dev = kzalloc(alloc_size, GFP_KERNEL);
 
 	if (dev) {
+		dev->dev.groups = dev->groups;
 		dev->dev.type = &iio_dev_type;
 		dev->dev.bus = &iio_bus_type;
 		device_initialize(&dev->dev);
@@ -1104,14 +1095,11 @@
 	/* configure elements for the chrdev */
 	dev_info->dev.devt = MKDEV(MAJOR(iio_devt), dev_info->id);
 
-	ret = device_add(&dev_info->dev);
-	if (ret)
-		goto error_free_ida;
 	ret = iio_device_register_sysfs(dev_info);
 	if (ret) {
 		dev_err(dev_info->dev.parent,
 			"Failed to register sysfs interfaces\n");
-		goto error_del_device;
+		goto error_free_ida;
 	}
 	ret = iio_device_register_eventset(dev_info);
 	if (ret) {
@@ -1122,15 +1110,22 @@
 	if (dev_info->modes & INDIO_RING_TRIGGERED)
 		iio_device_register_trigger_consumer(dev_info);
 
+	ret = device_add(&dev_info->dev);
+	if (ret < 0)
+		goto error_unreg_eventset;
 	cdev_init(&dev_info->chrdev, &iio_ring_fileops);
 	dev_info->chrdev.owner = dev_info->info->driver_module;
 	ret = cdev_add(&dev_info->chrdev, dev_info->dev.devt, 1);
+	if (ret < 0)
+		goto error_del_device;
 	return 0;
 
-error_free_sysfs:
-	iio_device_unregister_sysfs(dev_info);
 error_del_device:
 	device_del(&dev_info->dev);
+error_unreg_eventset:
+	iio_device_unregister_eventset(dev_info);
+error_free_sysfs:
+	iio_device_unregister_sysfs(dev_info);
 error_free_ida:
 	ida_simple_remove(&iio_ida, dev_info->id);
 error_ret:
@@ -1140,11 +1135,6 @@
 
 void iio_device_unregister(struct iio_dev *dev_info)
 {
-	if (dev_info->modes & INDIO_RING_TRIGGERED)
-		iio_device_unregister_trigger_consumer(dev_info);
-	iio_device_unregister_eventset(dev_info);
-	iio_device_unregister_sysfs(dev_info);
-	ida_simple_remove(&iio_ida, dev_info->id);
 	device_unregister(&dev_info->dev);
 }
 EXPORT_SYMBOL(iio_device_unregister);
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 6f14c0d..7a95fbe 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -207,10 +207,10 @@
 static int iio_ring_add_channel_sysfs(struct iio_dev *indio_dev,
 				      const struct iio_chan_spec *chan)
 {
-	int ret;
+	int ret, attrcount = 0;
 	struct iio_ring_buffer *ring = indio_dev->ring;
 
-	ret = __iio_add_chan_devattr("index", "scan_elements",
+	ret = __iio_add_chan_devattr("index",
 				     chan,
 				     &iio_show_scan_index,
 				     NULL,
@@ -220,8 +220,8 @@
 				     &ring->scan_el_dev_attr_list);
 	if (ret)
 		goto error_ret;
-
-	ret = __iio_add_chan_devattr("type", "scan_elements",
+	attrcount++;
+	ret = __iio_add_chan_devattr("type",
 				     chan,
 				     &iio_show_fixed_type,
 				     NULL,
@@ -231,9 +231,9 @@
 				     &ring->scan_el_dev_attr_list);
 	if (ret)
 		goto error_ret;
-
+	attrcount++;
 	if (chan->type != IIO_TIMESTAMP)
-		ret = __iio_add_chan_devattr("en", "scan_elements",
+		ret = __iio_add_chan_devattr("en",
 					     chan,
 					     &iio_scan_el_show,
 					     &iio_scan_el_store,
@@ -242,7 +242,7 @@
 					     &indio_dev->dev,
 					     &ring->scan_el_dev_attr_list);
 	else
-		ret = __iio_add_chan_devattr("en", "scan_elements",
+		ret = __iio_add_chan_devattr("en",
 					     chan,
 					     &iio_scan_el_ts_show,
 					     &iio_scan_el_ts_store,
@@ -250,6 +250,8 @@
 					     0,
 					     &indio_dev->dev,
 					     &ring->scan_el_dev_attr_list);
+	attrcount++;
+	ret = attrcount;
 error_ret:
 	return ret;
 }
@@ -257,66 +259,40 @@
 static void iio_ring_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev,
 						   struct iio_dev_attr *p)
 {
-	sysfs_remove_file_from_group(&indio_dev->dev.kobj,
-				     &p->dev_attr.attr, "scan_elements");
 	kfree(p->dev_attr.attr.name);
 	kfree(p);
 }
 
-static struct attribute *iio_scan_el_dummy_attrs[] = {
-	NULL
-};
-
-static struct attribute_group iio_scan_el_dummy_group = {
-	.name = "scan_elements",
-	.attrs = iio_scan_el_dummy_attrs
-};
-
 static void __iio_ring_attr_cleanup(struct iio_dev *indio_dev)
 {
 	struct iio_dev_attr *p, *n;
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	int anydynamic = !list_empty(&ring->scan_el_dev_attr_list);
+
 	list_for_each_entry_safe(p, n,
 				 &ring->scan_el_dev_attr_list, l)
 		iio_ring_remove_and_free_scan_dev_attr(indio_dev, p);
-
-	if (ring->scan_el_attrs)
-		sysfs_remove_group(&indio_dev->dev.kobj,
-				   ring->scan_el_attrs);
-	else if (anydynamic)
-		sysfs_remove_group(&indio_dev->dev.kobj,
-				   &iio_scan_el_dummy_group);
 }
 
+static const char * const iio_scan_elements_group_name = "scan_elements";
+
 int iio_ring_buffer_register(struct iio_dev *indio_dev,
 			     const struct iio_chan_spec *channels,
 			     int num_channels)
 {
+	struct iio_dev_attr *p;
+	struct attribute **attr;
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	int ret, i;
+	int ret, i, attrn, attrcount, attrcount_orig = 0;
 
-	if (ring->scan_el_attrs) {
-		ret = sysfs_create_group(&indio_dev->dev.kobj,
-					 ring->scan_el_attrs);
-		if (ret) {
-			dev_err(&indio_dev->dev,
-				"Failed to add sysfs scan elements\n");
-			goto error_ret;
-		}
-	} else if (channels) {
-		ret = sysfs_create_group(&indio_dev->dev.kobj,
-					 &iio_scan_el_dummy_group);
-		if (ret)
-			goto error_ret;
-	}
-	if (ring->attrs) {
-		ret = sysfs_create_group(&indio_dev->dev.kobj,
-					 ring->attrs);
-		if (ret)
-			goto error_cleanup_dynamic;
-	}
+	if (ring->attrs)
+		indio_dev->groups[indio_dev->groupcounter++] = ring->attrs;
 
+	if (ring->scan_el_attrs != NULL) {
+		attr = ring->scan_el_attrs->attrs;
+		while (*attr++ != NULL)
+			attrcount_orig++;
+	}
+	attrcount = attrcount_orig;
 	INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
 	if (channels) {
 		/* new magic */
@@ -330,7 +306,8 @@
 			ret = iio_ring_add_channel_sysfs(indio_dev,
 							 &channels[i]);
 			if (ret < 0)
-				goto error_cleanup_group;
+				goto error_cleanup_dynamic;
+			attrcount += ret;
 		}
 		if (indio_dev->masklength && ring->scan_mask == NULL) {
 			ring->scan_mask
@@ -339,18 +316,36 @@
 					  GFP_KERNEL);
 			if (ring->scan_mask == NULL) {
 				ret = -ENOMEM;
-				goto error_cleanup_group;
+				goto error_cleanup_dynamic;
 			}
 		}
 	}
 
+	ring->scan_el_group.name = iio_scan_elements_group_name;
+
+	ring->scan_el_group.attrs
+		= kzalloc(sizeof(ring->scan_el_group.attrs[0])*(attrcount + 1),
+			  GFP_KERNEL);
+	if (ring->scan_el_group.attrs == NULL) {
+		ret = -ENOMEM;
+		goto error_free_scan_mask;
+	}
+	if (ring->scan_el_attrs)
+		memcpy(ring->scan_el_group.attrs, ring->scan_el_attrs,
+		       sizeof(ring->scan_el_group.attrs[0])*attrcount_orig);
+	attrn = attrcount_orig;
+
+	list_for_each_entry(p, &ring->scan_el_dev_attr_list, l)
+		ring->scan_el_group.attrs[attrn++] = &p->dev_attr.attr;
+	indio_dev->groups[indio_dev->groupcounter++] = &ring->scan_el_group;
+
 	return 0;
-error_cleanup_group:
-	if (ring->attrs)
-		sysfs_remove_group(&indio_dev->dev.kobj, ring->attrs);
+
+error_free_scan_mask:
+	kfree(ring->scan_mask);
 error_cleanup_dynamic:
 	__iio_ring_attr_cleanup(indio_dev);
-error_ret:
+
 	return ret;
 }
 EXPORT_SYMBOL(iio_ring_buffer_register);
@@ -358,9 +353,7 @@
 void iio_ring_buffer_unregister(struct iio_dev *indio_dev)
 {
 	kfree(indio_dev->ring->scan_mask);
-	if (indio_dev->ring->attrs)
-		sysfs_remove_group(&indio_dev->dev.kobj,
-				   indio_dev->ring->attrs);
+	kfree(indio_dev->ring->scan_el_group.attrs);
 	__iio_ring_attr_cleanup(indio_dev);
 }
 EXPORT_SYMBOL(iio_ring_buffer_unregister);
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 3e60406..a66dcf7 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -475,8 +475,10 @@
 
 int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
 {
-	return sysfs_create_group(&dev_info->dev.kobj,
-				  &iio_trigger_consumer_attr_group);
+	dev_info->groups[dev_info->groupcounter++] =
+		&iio_trigger_consumer_attr_group;
+
+	return 0;
 }
 
 void iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
@@ -484,8 +486,6 @@
 	/* Clean up and associated but not attached triggers references */
 	if (dev_info->trig)
 		iio_put_trigger(dev_info->trig);
-	sysfs_remove_group(&dev_info->dev.kobj,
-			   &iio_trigger_consumer_attr_group);
 }
 
 int iio_triggered_ring_postenable(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 7a57791..3707772 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -751,9 +751,6 @@
 		indio_dev->info = &tsl2563_info;
 	else
 		indio_dev->info = &tsl2563_info_no_irq;
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto fail1;
 	if (client->irq) {
 		ret = request_threaded_irq(client->irq,
 					   NULL,
@@ -772,12 +769,16 @@
 	/* The interrupt cannot yet be enabled so this is fine without lock */
 	schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto fail3;
+
 	return 0;
 fail3:
 	if (client->irq)
 		free_irq(client->irq, indio_dev);
 fail2:
-	iio_device_unregister(indio_dev);
+	iio_free_device(indio_dev);
 fail1:
 	kfree(chip);
 	return err;
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index bccc579..8cf7308 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -513,7 +513,7 @@
 
 static int __devinit ade7753_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct ade7753_state *st;
 	struct iio_dev *indio_dev;
 
@@ -535,22 +535,19 @@
 	indio_dev->info = &ade7753_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-	regdone = 1;
-
 	/* Get the device into a sane initial state */
 	ret = ade7753_initial_setup(indio_dev);
 	if (ret)
 		goto error_free_dev;
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_dev;
+
 	return 0;
 
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 error_ret:
 	return ret;
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 6f0f464..8adb2a9 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -536,7 +536,7 @@
 
 static int __devinit ade7754_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
+	int ret;
 	struct ade7754_state *st;
 	struct iio_dev *indio_dev;
 
@@ -558,22 +558,18 @@
 	indio_dev->info = &ade7754_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-	regdone = 1;
-
 	/* Get the device into a sane initial state */
 	ret = ade7754_initial_setup(indio_dev);
 	if (ret)
 		goto error_free_dev;
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_dev;
+
 	return 0;
 
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 
 error_ret:
 	return ret;
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index ce513bd..7cbf1cb 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -733,7 +733,7 @@
 
 static int __devinit ade7758_probe(struct spi_device *spi)
 {
-	int i, ret, regdone = 0;
+	int i, ret;
 	struct ade7758_state *st;
 	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
@@ -775,11 +775,6 @@
 	if (ret)
 		goto error_free_tx;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
 	ret = iio_ring_buffer_register(indio_dev,
 				       &ade7758_channels[0],
 				       ARRAY_SIZE(ade7758_channels));
@@ -796,9 +791,13 @@
 	if (spi->irq) {
 		ret = ade7758_probe_trigger(indio_dev);
 		if (ret)
-			goto error_remove_trigger;
+			goto error_uninitialize_ring;
 	}
 
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_remove_trigger;
+
 	return 0;
 
 error_remove_trigger:
@@ -813,10 +812,7 @@
 error_free_rx:
 	kfree(st->rx);
 error_free_dev:
-	if (regdone)
-		iio_device_unregister(indio_dev);
-	else
-		iio_free_device(indio_dev);
+	iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 31723e8..8e44e46 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -480,19 +480,17 @@
 	indio_dev->info = &ade7759_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
+	/* Get the device into a sane initial state */
+	ret = ade7759_initial_setup(indio_dev);
+	if (ret)
+		goto error_free_dev;
+
 	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_free_dev;
 
-	/* Get the device into a sane initial state */
-	ret = ade7759_initial_setup(indio_dev);
-	if (ret)
-		goto error_unreg_dev;
 	return 0;
 
-
-error_unreg_dev:
-	iio_device_unregister(indio_dev);
 error_free_dev:
 	iio_free_device(indio_dev);
 error_ret:
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 5e83227..5c9c409 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -784,6 +784,7 @@
 {
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct ad2s1210_state *st = iio_priv(indio_dev);
+
 	ad2s1210_free_gpios(st);
 	iio_device_unregister(indio_dev);
 
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 7a47f62..8f6ecde 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -9,6 +9,7 @@
 
 #ifndef _IIO_RING_GENERIC_H_
 #define _IIO_RING_GENERIC_H_
+#include <linux/sysfs.h>
 #include "iio.h"
 #include "chrdev.h"
 
@@ -109,7 +110,7 @@
 	const struct iio_ring_access_funcs	*access;
 	const struct iio_ring_setup_ops		*setup_ops;
 	struct list_head			scan_el_dev_attr_list;
-
+	struct attribute_group			scan_el_group;
 	wait_queue_head_t			pollq;
 	bool					stufftoread;
 	unsigned long				flags;