[media] s5p-csis: Convert to the device managed resources
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Tue, 14 Feb 2012 16:23:46 +0000 (13:23 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 8 Mar 2012 10:41:43 +0000 (07:41 -0300)
The devm_* functions are used in the platform device probe() for data
that is freed on driver removal. The managed device layer takes care
of undoing actions taken in the probe callback() and freeing resources
on driver detach. This eliminates the need for manually releasing
resources and simplifies error handling.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/s5p-fimc/mipi-csis.c

index 58c40750abc21a4fdea9ce16caa18dc7db7385f4..a903138b18dad41ebd6b79f1e4879a138744a837 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
  *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki, <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -100,7 +100,6 @@ enum {
  * @pads: CSIS pads array
  * @sd: v4l2_subdev associated with CSIS device instance
  * @pdev: CSIS platform device
- * @regs_res: requested I/O register memory resource
  * @regs: mmaped I/O registers memory
  * @clock: CSIS clocks
  * @irq: requested s5p-mipi-csis irq number
@@ -113,7 +112,6 @@ struct csis_state {
        struct media_pad pads[CSIS_PADS_NUM];
        struct v4l2_subdev sd;
        struct platform_device *pdev;
-       struct resource *regs_res;
        void __iomem *regs;
        struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
        struct clk *clock[NUM_CSIS_CLOCKS];
@@ -490,12 +488,11 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
 {
        struct s5p_platform_mipi_csis *pdata;
        struct resource *mem_res;
-       struct resource *regs_res;
        struct csis_state *state;
        int ret = -ENOMEM;
        int i;
 
-       state = kzalloc(sizeof(*state), GFP_KERNEL);
+       state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
        if (!state)
                return -ENOMEM;
 
@@ -505,52 +502,27 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
        pdata = pdev->dev.platform_data;
        if (pdata == NULL || pdata->phy_enable == NULL) {
                dev_err(&pdev->dev, "Platform data not fully specified\n");
-               goto e_free;
+               return -EINVAL;
        }
 
        if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
            pdata->lanes > CSIS0_MAX_LANES) {
-               ret = -EINVAL;
                dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
                        pdata->lanes);
-               goto e_free;
+               return -EINVAL;
        }
 
        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem_res) {
-               dev_err(&pdev->dev, "Failed to get IO memory region\n");
-               goto e_free;
-       }
-
-       regs_res = request_mem_region(mem_res->start, resource_size(mem_res),
-                                     pdev->name);
-       if (!regs_res) {
-               dev_err(&pdev->dev, "Failed to request IO memory region\n");
-               goto e_free;
+       state->regs = devm_request_and_ioremap(&pdev->dev, mem_res);
+       if (state->regs == NULL) {
+               dev_err(&pdev->dev, "Failed to request and remap io memory\n");
+               return -ENXIO;
        }
-       state->regs_res = regs_res;
-
-       state->regs = ioremap(mem_res->start, resource_size(mem_res));
-       if (!state->regs) {
-               dev_err(&pdev->dev, "Failed to remap IO region\n");
-               goto e_reqmem;
-       }
-
-       ret = s5pcsis_clk_get(state);
-       if (ret)
-               goto e_unmap;
-
-       clk_enable(state->clock[CSIS_CLK_MUX]);
-       if (pdata->clk_rate)
-               clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
-       else
-               dev_WARN(&pdev->dev, "No clock frequency specified!\n");
 
        state->irq = platform_get_irq(pdev, 0);
        if (state->irq < 0) {
-               ret = state->irq;
                dev_err(&pdev->dev, "Failed to get irq\n");
-               goto e_clkput;
+               return state->irq;
        }
 
        for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
@@ -558,13 +530,23 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
 
        ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
                                 state->supplies);
+       if (ret)
+               return ret;
+
+       ret = s5pcsis_clk_get(state);
        if (ret)
                goto e_clkput;
 
-       ret = request_irq(state->irq, s5pcsis_irq_handler, 0,
-                         dev_name(&pdev->dev), state);
+       clk_enable(state->clock[CSIS_CLK_MUX]);
+       if (pdata->clk_rate)
+               clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
+       else
+               dev_WARN(&pdev->dev, "No clock frequency specified!\n");
+
+       ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
+                              0, dev_name(&pdev->dev), state);
        if (ret) {
-               dev_err(&pdev->dev, "request_irq failed\n");
+               dev_err(&pdev->dev, "Interrupt request failed\n");
                goto e_regput;
        }
 
@@ -583,7 +565,7 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
        ret = media_entity_init(&state->sd.entity,
                                CSIS_PADS_NUM, state->pads, 0);
        if (ret < 0)
-               goto e_irqfree;
+               goto e_clkput;
 
        /* This allows to retrieve the platform device id by the host driver */
        v4l2_set_subdevdata(&state->sd, pdev);
@@ -592,22 +574,13 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, &state->sd);
 
        pm_runtime_enable(&pdev->dev);
-
        return 0;
 
-e_irqfree:
-       free_irq(state->irq, state);
 e_regput:
        regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
 e_clkput:
        clk_disable(state->clock[CSIS_CLK_MUX]);
        s5pcsis_clk_put(state);
-e_unmap:
-       iounmap(state->regs);
-e_reqmem:
-       release_mem_region(regs_res->start, resource_size(regs_res));
-e_free:
-       kfree(state);
        return ret;
 }
 
@@ -709,21 +682,15 @@ static int __devexit s5pcsis_remove(struct platform_device *pdev)
 {
        struct v4l2_subdev *sd = platform_get_drvdata(pdev);
        struct csis_state *state = sd_to_csis_state(sd);
-       struct resource *res = state->regs_res;
 
        pm_runtime_disable(&pdev->dev);
        s5pcsis_suspend(&pdev->dev);
        clk_disable(state->clock[CSIS_CLK_MUX]);
        pm_runtime_set_suspended(&pdev->dev);
-
        s5pcsis_clk_put(state);
        regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
 
        media_entity_cleanup(&state->sd.entity);
-       free_irq(state->irq, state);
-       iounmap(state->regs);
-       release_mem_region(res->start, resource_size(res));
-       kfree(state);
 
        return 0;
 }