mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
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>
This commit is contained in:
parent
7326e38ffe
commit
6f535b9426
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user