--- initial
+++ final
@@ -1,87 +1,83 @@
 static int spear_adc_probe(struct platform_device *pdev) {
   struct device_node *np = pdev->dev.of_node;
   struct device *dev = &pdev->dev;
   struct spear_adc_info *info;
   struct iio_dev *iodev = NULL;
   int ret = -ENODEV;
   int irq;
-  iodev = iio_device_alloc(sizeof(struct spear_adc_info));
+  iodev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_info));
   if (!iodev) {
     dev_err(dev, "failed allocating iio device\n");
-    ret = -ENOMEM;
-    goto errout1;
+    return -ENOMEM;
   }
   info = iio_priv(iodev);
   info->np = np;
   /*
    * SPEAr600 has a different register layout than other SPEAr SoC's
    * (e.g. SPEAr3xx). Let's provide two register base addresses
    * to support multi-arch kernels.
    */
   info->adc_base_spear6xx = of_iomap(np, 0);
   if (!info->adc_base_spear6xx) {
     dev_err(dev, "failed mapping memory\n");
     ret = -ENOMEM;
-    goto errout2;
+    return ret;
   }
   info->adc_base_spear3xx = (struct adc_regs_spear3xx *)info->adc_base_spear6xx;
   info->clk = clk_get(dev, NULL);
   if (IS_ERR(info->clk)) {
     dev_err(dev, "failed getting clock\n");
     goto errout3;
   }
   ret = clk_prepare_enable(info->clk);
   if (ret) {
     dev_err(dev, "failed enabling clock\n");
     goto errout4;
   }
   irq = platform_get_irq(pdev, 0);
   if ((irq < 0) || (irq >= NR_IRQS)) {
     dev_err(dev, "failed getting interrupt resource\n");
     ret = -EINVAL;
     goto errout5;
   }
   ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info);
   if (ret < 0) {
     dev_err(dev, "failed requesting interrupt\n");
     goto errout5;
   }
   if (of_property_read_u32(np, "sampling-frequency", &info->sampling_freq)) {
     dev_err(dev, "sampling-frequency missing in DT\n");
     ret = -EINVAL;
     goto errout5;
   }
   /*
    * Optional avg_samples defaults to 0, resulting in single data
    * conversion
    */
   of_property_read_u32(np, "average-samples", &info->avg_samples);
   /*
    * Optional vref_external defaults to 0, resulting in internal vref
    * selection
    */
   of_property_read_u32(np, "vref-external", &info->vref_external);
   spear_adc_configure(info);
   platform_set_drvdata(pdev, iodev);
   init_completion(&info->completion);
   iodev->name = MOD_NAME;
   iodev->dev.parent = dev;
   iodev->info = &spear_adc_iio_info;
   iodev->modes = INDIO_DIRECT_MODE;
   iodev->channels = spear_adc_iio_channels;
   iodev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
   ret = iio_device_register(iodev);
   if (ret) goto errout5;
   dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
   return 0;
 errout5:
   clk_disable_unprepare(info->clk);
 errout4:
   clk_put(info->clk);
 errout3:
   iounmap(info->adc_base_spear6xx);
-errout2:
-  iio_device_free(iodev);
-errout1:
   return ret;
 }<sep>@@
expression e,e1,e2,ret;
identifier l1,l2,dev;
@@
	struct device *dev;
	... when != l2
(
-       e = iio_device_alloc(e1);
+       e = devm_iio_device_alloc(dev, e1);
        if (e == NULL)
(
-	{
-               ret = e2;
-               goto l2;
+               return e2;
-       }
|
	{
		...
-               ret = e2;
		...
-               goto l2;
+               return e2;
       }
)
<...
-	goto l1;
+	return ret;
...>
&
e = iio_device_alloc(e1);
... when exists
-l1:
-       iio_device_free(e);
-l2:
        return ret;
)