Commit 6f535b94 authored by Linus Walleij's avatar Linus Walleij Committed by Wolfram Sang

i2c: stu300: use devm managed resources

Allocate memory for device state using devm_kzalloc(), get the
clock using devm_clk_get(), get the IRQ using devm_request_irq(),
request and remap memory using devm_request_and_ioremap().
All to simplify accounting and letting the kernel do the
garbage-collection.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarWolfram Sang <w.sang@pengutronix.de>
parent 7326e38f
/* /*
* Copyright (C) 2007-2009 ST-Ericsson AB * Copyright (C) 2007-2012 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2 * License terms: GNU General Public License (GPL) version 2
* ST DDC I2C master mode driver, used in e.g. U300 series platforms. * ST DDC I2C master mode driver, used in e.g. U300 series platforms.
* Author: Linus Walleij <linus.walleij@stericsson.com> * Author: Linus Walleij <linus.walleij@stericsson.com>
...@@ -139,8 +139,6 @@ module_param(scl_frequency, uint, 0644); ...@@ -139,8 +139,6 @@ module_param(scl_frequency, uint, 0644);
* struct stu300_dev - the stu300 driver state holder * struct stu300_dev - the stu300 driver state holder
* @pdev: parent platform device * @pdev: parent platform device
* @adapter: corresponding I2C adapter * @adapter: corresponding I2C adapter
* @phybase: location of I/O area in memory
* @physize: size of I/O area in memory
* @clk: hardware block clock * @clk: hardware block clock
* @irq: assigned interrupt line * @irq: assigned interrupt line
* @cmd_issue_lock: this locks the following cmd_ variables * @cmd_issue_lock: this locks the following cmd_ variables
...@@ -155,8 +153,6 @@ module_param(scl_frequency, uint, 0644); ...@@ -155,8 +153,6 @@ module_param(scl_frequency, uint, 0644);
struct stu300_dev { struct stu300_dev {
struct platform_device *pdev; struct platform_device *pdev;
struct i2c_adapter adapter; struct i2c_adapter adapter;
resource_size_t phybase;
resource_size_t physize;
void __iomem *virtbase; void __iomem *virtbase;
struct clk *clk; struct clk *clk;
int irq; int irq;
...@@ -873,64 +869,44 @@ stu300_probe(struct platform_device *pdev) ...@@ -873,64 +869,44 @@ stu300_probe(struct platform_device *pdev)
int ret = 0; int ret = 0;
char clk_name[] = "I2C0"; char clk_name[] = "I2C0";
dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL); dev = devm_kzalloc(&pdev->dev, sizeof(struct stu300_dev), GFP_KERNEL);
if (!dev) { if (!dev) {
dev_err(&pdev->dev, "could not allocate device struct\n"); dev_err(&pdev->dev, "could not allocate device struct\n");
ret = -ENOMEM; return -ENOMEM;
goto err_no_devmem;
} }
bus_nr = pdev->id; bus_nr = pdev->id;
clk_name[3] += (char)bus_nr; clk_name[3] += (char)bus_nr;
dev->clk = clk_get(&pdev->dev, clk_name); dev->clk = devm_clk_get(&pdev->dev, clk_name);
if (IS_ERR(dev->clk)) { if (IS_ERR(dev->clk)) {
ret = PTR_ERR(dev->clk);
dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); dev_err(&pdev->dev, "could not retrieve i2c bus clock\n");
goto err_no_clk; return PTR_ERR(dev->clk);
} }
dev->pdev = pdev; dev->pdev = pdev;
platform_set_drvdata(pdev, dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res)
ret = -ENOENT; return -ENOENT;
goto err_no_resource;
}
dev->phybase = res->start; dev->virtbase = devm_request_and_ioremap(&pdev->dev, res);
dev->physize = resource_size(res);
if (request_mem_region(dev->phybase, dev->physize,
NAME " I/O Area") == NULL) {
ret = -EBUSY;
goto err_no_ioregion;
}
dev->virtbase = ioremap(dev->phybase, dev->physize);
dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual " dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
"base %p\n", bus_nr, dev->virtbase); "base %p\n", bus_nr, dev->virtbase);
if (!dev->virtbase) { if (!dev->virtbase)
ret = -ENOMEM; return -ENOMEM;
goto err_no_ioremap;
}
dev->irq = platform_get_irq(pdev, 0); dev->irq = platform_get_irq(pdev, 0);
if (request_irq(dev->irq, stu300_irh, 0, ret = devm_request_irq(&pdev->dev, dev->irq, stu300_irh, 0, NAME, dev);
NAME, dev)) { if (ret < 0)
ret = -EIO; return ret;
goto err_no_irq;
}
dev->speed = scl_frequency; dev->speed = scl_frequency;
clk_prepare_enable(dev->clk); clk_prepare_enable(dev->clk);
ret = stu300_init_hw(dev); ret = stu300_init_hw(dev);
clk_disable(dev->clk); clk_disable(dev->clk);
if (ret != 0) { if (ret != 0) {
dev_err(&dev->pdev->dev, "error initializing hardware.\n"); dev_err(&dev->pdev->dev, "error initializing hardware.\n");
goto err_init_hw; return -EIO;
} }
/* IRQ event handling initialization */ /* IRQ event handling initialization */
...@@ -952,30 +928,13 @@ stu300_probe(struct platform_device *pdev) ...@@ -952,30 +928,13 @@ stu300_probe(struct platform_device *pdev)
/* i2c device drivers may be active on return from add_adapter() */ /* i2c device drivers may be active on return from add_adapter() */
ret = i2c_add_numbered_adapter(adap); ret = i2c_add_numbered_adapter(adap);
if (ret) { if (ret) {
dev_err(&dev->pdev->dev, "failure adding ST Micro DDC " dev_err(&pdev->dev, "failure adding ST Micro DDC "
"I2C adapter\n"); "I2C adapter\n");
goto err_add_adapter; return ret;
} }
return 0;
err_add_adapter: platform_set_drvdata(pdev, dev);
err_init_hw: return 0;
clk_unprepare(dev->clk);
free_irq(dev->irq, dev);
err_no_irq:
iounmap(dev->virtbase);
err_no_ioremap:
release_mem_region(dev->phybase, dev->physize);
err_no_ioregion:
platform_set_drvdata(pdev, NULL);
err_no_resource:
clk_put(dev->clk);
err_no_clk:
kfree(dev);
err_no_devmem:
dev_err(&pdev->dev, "failed to add " NAME " adapter: %d\n",
pdev->id);
return ret;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1016,13 +975,7 @@ stu300_remove(struct platform_device *pdev) ...@@ -1016,13 +975,7 @@ stu300_remove(struct platform_device *pdev)
i2c_del_adapter(&dev->adapter); i2c_del_adapter(&dev->adapter);
/* Turn off everything */ /* Turn off everything */
stu300_wr8(0x00, dev->virtbase + I2C_CR); stu300_wr8(0x00, dev->virtbase + I2C_CR);
free_irq(dev->irq, dev);
iounmap(dev->virtbase);
release_mem_region(dev->phybase, dev->physize);
clk_unprepare(dev->clk);
clk_put(dev->clk);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
kfree(dev);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment