Skip to content

Commit

Permalink
[media] s5p-csis: Convert to the device managed resources
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Mar 8, 2012
1 parent f9331d1 commit a121216
Showing 1 changed file with 24 additions and 57 deletions.
81 changes: 24 additions & 57 deletions drivers/media/video/s5p-fimc/mipi-csis.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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];
Expand Down Expand Up @@ -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;

Expand All @@ -505,66 +502,51 @@ 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++)
state->supplies[i].supply = csis_supply_name[i];

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;
}

Expand All @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit a121216

Please sign in to comment.