[linux-yocto] [PATCH 27/39] i2c-axxia: Use managed functions devm_*
Charlie Paul
cpaul.windriver at gmail.com
Tue Apr 22 13:59:39 PDT 2014
From: Anders Berg <anders.berg at lsi.com>
Use the devm_ functions for resource allocation to simplify error handling.
Signed-off-by: Anders Berg <anders.berg at lsi.com>
---
drivers/i2c/busses/i2c-axxia.c | 98 +++++++++++++++-------------------------
1 file changed, 36 insertions(+), 62 deletions(-)
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index 8cc972d..c2b84a4 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -116,12 +116,8 @@ struct axxia_i2c_dev {
struct i2c_adapter adapter;
/* clock reference for i2c input clock */
struct clk *i2c_clk;
- /* ioremapped registers cookie */
- void __iomem *base;
/* pointer to register struct */
struct i2c_regs __iomem *regs;
- /* irq number */
- int irq;
/* xfer completion object */
struct completion msg_complete;
/* pointer to current message */
@@ -488,11 +484,11 @@ axxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
static u32
axxia_i2c_func(struct i2c_adapter *adap)
{
- return I2C_FUNC_I2C |
+ u32 caps = (I2C_FUNC_I2C |
I2C_FUNC_10BIT_ADDR |
I2C_FUNC_SMBUS_EMUL |
- I2C_FUNC_SMBUS_BLOCK_DATA;
-
+ I2C_FUNC_SMBUS_BLOCK_DATA);
+ return caps;
}
static const struct i2c_algorithm axxia_i2c_algo = {
@@ -505,49 +501,42 @@ axxia_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct axxia_i2c_dev *idev = NULL;
- struct clk *i2c_clk = NULL;
- void __iomem *base = NULL;
- u32 bus = pdev->id;
- int irq = 0;
+ struct resource *res;
+ void __iomem *base;
+ int irq;
int ret = 0;
- base = of_iomap(np, 0);
- if (!base) {
- dev_err(&pdev->dev, "failed to iomap registers\n");
- ret = -ENOMEM;
- goto err_cleanup;
- }
+ idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
+ if (!idev)
+ return -ENOMEM;
- irq = irq_of_parse_and_map(np, 0);
- if (irq == 0) {
- dev_err(&pdev->dev, "no irq property\n");
- ret = -EINVAL;
- goto err_cleanup;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "can't get device io-resource\n");
+ return -ENOENT;
}
- i2c_clk = clk_get(&pdev->dev, "i2c");
- if (IS_ERR(i2c_clk)) {
- dev_err(&pdev->dev, "missing bus clock");
- ret = PTR_ERR(i2c_clk);
- goto err_cleanup;
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "can't get irq number\n");
+ return -ENOENT;
}
- idev = kzalloc(sizeof(struct axxia_i2c_dev), GFP_KERNEL);
- if (!idev) {
- ret = -ENOMEM;
- goto err_cleanup;
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ idev->i2c_clk = devm_clk_get(&pdev->dev, "i2c");
+ if (IS_ERR(idev->i2c_clk)) {
+ dev_err(&pdev->dev, "missing I2C bus clock");
+ return PTR_ERR(idev->i2c_clk);
}
- idev->base = base;
- idev->regs = (struct __iomem i2c_regs*) base;
- idev->i2c_clk = i2c_clk;
+ idev->regs = (struct i2c_regs __iomem *) base;
idev->dev = &pdev->dev;
init_completion(&idev->msg_complete);
- of_property_read_u32(np, "bus", &bus);
-
of_property_read_u32(np, "clock-frequency", &idev->bus_clk_rate);
-
if (idev->bus_clk_rate == 0)
idev->bus_clk_rate = 100000; /* default clock rate */
@@ -556,48 +545,37 @@ axxia_i2c_probe(struct platform_device *pdev)
ret = axxia_i2c_init(idev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize i2c controller");
- goto err_cleanup;
+ return ret;
}
- ret = request_irq(irq, axxia_i2c_isr, 0, pdev->name, idev);
+ ret = devm_request_irq(&pdev->dev, irq, axxia_i2c_isr, 0,
+ pdev->name, idev);
if (ret) {
- dev_err(&pdev->dev, "Failed to request irq %i\n", idev->irq);
- goto err_cleanup;
+ dev_err(&pdev->dev, "can't claim irq %d\n", irq);
+ return ret;
}
- idev->irq = irq;
clk_enable(idev->i2c_clk);
i2c_set_adapdata(&idev->adapter, idev);
+ strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
idev->adapter.owner = THIS_MODULE;
idev->adapter.class = I2C_CLASS_HWMON;
- snprintf(idev->adapter.name, sizeof(idev->adapter.name),
- "Axxia I2C%u", bus);
idev->adapter.algo = &axxia_i2c_algo;
idev->adapter.dev.parent = &pdev->dev;
- idev->adapter.nr = bus;
idev->adapter.dev.of_node = pdev->dev.of_node;
- ret = i2c_add_numbered_adapter(&idev->adapter);
+ ret = i2c_add_adapter(&idev->adapter);
if (ret) {
dev_err(&pdev->dev, "Failed to add I2C adapter\n");
- goto err_cleanup;
+ return ret;
}
+ platform_set_drvdata(pdev, idev);
+
of_i2c_register_devices(&idev->adapter);
return 0;
-
-err_cleanup:
- if (!IS_ERR_OR_NULL(i2c_clk))
- clk_put(i2c_clk);
- if (base)
- iounmap(base);
- if (idev && idev->irq)
- free_irq(irq, idev);
- kfree(idev);
-
- return ret;
}
static int
@@ -605,10 +583,6 @@ axxia_i2c_remove(struct platform_device *pdev)
{
struct axxia_i2c_dev *idev = platform_get_drvdata(pdev);
i2c_del_adapter(&idev->adapter);
- free_irq(idev->irq, idev);
- clk_put(idev->i2c_clk);
- iounmap(idev->base);
- kfree(idev);
return 0;
}
--
1.7.9.5
More information about the linux-yocto
mailing list