diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2012-07-16 13:30:12 +0200 |
---|---|---|
committer | Wolfram Sang <w.sang@pengutronix.de> | 2012-07-16 13:48:51 +0200 |
commit | 6f535b94261b16343cfbc4576a941bd7901b96e1 (patch) | |
tree | 4dd6d6e3183c030728b5cdf330b4c9ffa1dd7607 /drivers/i2c/busses/i2c-stu300.c | |
parent | i2c: i2c-ocores: support for 16bit and 32bit IO (diff) | |
download | linux-6f535b94261b16343cfbc4576a941bd7901b96e1.tar.xz linux-6f535b94261b16343cfbc4576a941bd7901b96e1.zip |
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: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c/busses/i2c-stu300.c')
-rw-r--r-- | drivers/i2c/busses/i2c-stu300.c | 83 |
1 files changed, 18 insertions, 65 deletions
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 80dd1c074a08..580a0c04cb42 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 ST-Ericsson AB + * Copyright (C) 2007-2012 ST-Ericsson AB * License terms: GNU General Public License (GPL) version 2 * ST DDC I2C master mode driver, used in e.g. U300 series platforms. * Author: Linus Walleij <linus.walleij@stericsson.com> @@ -139,8 +139,6 @@ module_param(scl_frequency, uint, 0644); * struct stu300_dev - the stu300 driver state holder * @pdev: parent platform device * @adapter: corresponding I2C adapter - * @phybase: location of I/O area in memory - * @physize: size of I/O area in memory * @clk: hardware block clock * @irq: assigned interrupt line * @cmd_issue_lock: this locks the following cmd_ variables @@ -155,8 +153,6 @@ module_param(scl_frequency, uint, 0644); struct stu300_dev { struct platform_device *pdev; struct i2c_adapter adapter; - resource_size_t phybase; - resource_size_t physize; void __iomem *virtbase; struct clk *clk; int irq; @@ -873,64 +869,44 @@ stu300_probe(struct platform_device *pdev) int ret = 0; 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) { dev_err(&pdev->dev, "could not allocate device struct\n"); - ret = -ENOMEM; - goto err_no_devmem; + return -ENOMEM; } bus_nr = pdev->id; 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)) { - ret = PTR_ERR(dev->clk); dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); - goto err_no_clk; + return PTR_ERR(dev->clk); } dev->pdev = pdev; - platform_set_drvdata(pdev, dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENOENT; - goto err_no_resource; - } + if (!res) + return -ENOENT; - dev->phybase = res->start; - 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->virtbase = devm_request_and_ioremap(&pdev->dev, res); dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual " "base %p\n", bus_nr, dev->virtbase); - if (!dev->virtbase) { - ret = -ENOMEM; - goto err_no_ioremap; - } + if (!dev->virtbase) + return -ENOMEM; dev->irq = platform_get_irq(pdev, 0); - if (request_irq(dev->irq, stu300_irh, 0, - NAME, dev)) { - ret = -EIO; - goto err_no_irq; - } + ret = devm_request_irq(&pdev->dev, dev->irq, stu300_irh, 0, NAME, dev); + if (ret < 0) + return ret; dev->speed = scl_frequency; clk_prepare_enable(dev->clk); ret = stu300_init_hw(dev); clk_disable(dev->clk); - if (ret != 0) { dev_err(&dev->pdev->dev, "error initializing hardware.\n"); - goto err_init_hw; + return -EIO; } /* IRQ event handling initialization */ @@ -952,30 +928,13 @@ stu300_probe(struct platform_device *pdev) /* i2c device drivers may be active on return from add_adapter() */ ret = i2c_add_numbered_adapter(adap); if (ret) { - dev_err(&dev->pdev->dev, "failure adding ST Micro DDC " + dev_err(&pdev->dev, "failure adding ST Micro DDC " "I2C adapter\n"); - goto err_add_adapter; + return ret; } - return 0; - err_add_adapter: - err_init_hw: - 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; + platform_set_drvdata(pdev, dev); + return 0; } #ifdef CONFIG_PM @@ -1016,13 +975,7 @@ stu300_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); /* Turn off everything */ 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); - kfree(dev); return 0; } |