From 1cb715ca46946b1ad32735d11830a84a433f2b1b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Apr 2013 00:36:36 +0000 Subject: i2c-designware: move to managed functions (devm_*) This makes the error handling much more simpler than open-coding everything and in addition makes the probe function smaller and tidier. Signed-off-by: Andy Shevchenko Signed-off-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-platdrv.c | 73 ++++++++--------------------- 1 file changed, 19 insertions(+), 54 deletions(-) (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c') diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 0ceb6e1b0f65..c53a3127f694 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -92,7 +92,7 @@ static int dw_i2c_probe(struct platform_device *pdev) { struct dw_i2c_dev *dev; struct i2c_adapter *adap; - struct resource *mem, *ioarea; + struct resource *mem; int irq, r; /* NOTE: driver uses the static register mapping */ @@ -108,32 +108,25 @@ static int dw_i2c_probe(struct platform_device *pdev) return irq; /* -ENXIO */ } - ioarea = request_mem_region(mem->start, resource_size(mem), - pdev->name); - if (!ioarea) { - dev_err(&pdev->dev, "I2C region already claimed\n"); - return -EBUSY; - } + dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; - dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); - if (!dev) { - r = -ENOMEM; - goto err_release_region; - } + dev->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(dev->base)) + return PTR_ERR(dev->base); init_completion(&dev->cmd_complete); mutex_init(&dev->lock); - dev->dev = get_device(&pdev->dev); + dev->dev = &pdev->dev; dev->irq = irq; platform_set_drvdata(pdev, dev); - dev->clk = clk_get(&pdev->dev, NULL); + dev->clk = devm_clk_get(&pdev->dev, NULL); dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; - if (IS_ERR(dev->clk)) { - r = -ENODEV; - goto err_free_mem; - } + if (IS_ERR(dev->clk)) + return PTR_ERR(dev->clk); clk_prepare_enable(dev->clk); dev->functionality = @@ -146,13 +139,6 @@ static int dw_i2c_probe(struct platform_device *pdev) dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; - dev->base = ioremap(mem->start, resource_size(mem)); - if (dev->base == NULL) { - dev_err(&pdev->dev, "failure mapping io resources\n"); - r = -EBUSY; - goto err_unuse_clocks; - } - /* Try first if we can configure the device from ACPI */ r = dw_i2c_acpi_configure(pdev); if (r) { @@ -164,13 +150,14 @@ static int dw_i2c_probe(struct platform_device *pdev) } r = i2c_dw_init(dev); if (r) - goto err_iounmap; + return r; i2c_dw_disable_int(dev); - r = request_irq(dev->irq, i2c_dw_isr, IRQF_SHARED, pdev->name, dev); + r = devm_request_irq(&pdev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED, + pdev->name, dev); if (r) { dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); - goto err_iounmap; + return r; } adap = &dev->adapter; @@ -187,57 +174,35 @@ static int dw_i2c_probe(struct platform_device *pdev) r = i2c_add_numbered_adapter(adap); if (r) { dev_err(&pdev->dev, "failure adding adapter\n"); - goto err_free_irq; + return r; } of_i2c_register_devices(adap); acpi_i2c_register_devices(adap); + /* Increase reference counter */ + get_device(&pdev->dev); + pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_put(&pdev->dev); return 0; - -err_free_irq: - free_irq(dev->irq, dev); -err_iounmap: - iounmap(dev->base); -err_unuse_clocks: - clk_disable_unprepare(dev->clk); - clk_put(dev->clk); - dev->clk = NULL; -err_free_mem: - put_device(&pdev->dev); - kfree(dev); -err_release_region: - release_mem_region(mem->start, resource_size(mem)); - - return r; } static int dw_i2c_remove(struct platform_device *pdev) { struct dw_i2c_dev *dev = platform_get_drvdata(pdev); - struct resource *mem; pm_runtime_get_sync(&pdev->dev); i2c_del_adapter(&dev->adapter); put_device(&pdev->dev); - clk_disable_unprepare(dev->clk); - clk_put(dev->clk); - dev->clk = NULL; - i2c_dw_disable(dev); - free_irq(dev->irq, dev); - kfree(dev); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); return 0; } -- cgit v1.2.2 From efe7d640ef486c4c0c305641dbcacc6918542b76 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 10 Apr 2013 00:36:39 +0000 Subject: i2c-designware: use dynamic adapter numbering on Lynxpoint It is not good idea to mix static and dynamic I2C adapter numbering. In this particular case on Lynxpoint we had graphics I2C adapter which took the first numbers preventing the designware I2C driver from using the adapter numbers it preferred. Since Lynxpoint support was just introduced and there is no hardware available outside Intel we can fix this by switching to use dynamic adapter numbering instead of static. Signed-off-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-platdrv.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c') diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index c53a3127f694..2a596dd1ec66 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -56,20 +56,11 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) static int dw_i2c_acpi_configure(struct platform_device *pdev) { struct dw_i2c_dev *dev = platform_get_drvdata(pdev); - struct acpi_device *adev; - int busno, ret; if (!ACPI_HANDLE(&pdev->dev)) return -ENODEV; - ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); - if (ret) - return -ENODEV; - dev->adapter.nr = -1; - if (adev->pnp.unique_id && !kstrtoint(adev->pnp.unique_id, 0, &busno)) - dev->adapter.nr = busno; - dev->tx_fifo_depth = 32; dev->rx_fifo_depth = 32; return 0; -- cgit v1.2.2 From 43452335224bc0cbd605c6aee82b5c9c33e94cc6 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 10 Apr 2013 00:36:42 +0000 Subject: i2c-designware: switch to use runtime PM autosuspend Using autosuspend helps to reduce the resume latency in situations where another I2C message is going to be started soon. For example with HID over I2C touch panels we get several messages in a short period of time while the touch panel is in use. Signed-off-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-platdrv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c') diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 2a596dd1ec66..dec939aca588 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -173,9 +173,10 @@ static int dw_i2c_probe(struct platform_device *pdev) /* Increase reference counter */ get_device(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); + pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - pm_runtime_put(&pdev->dev); return 0; } -- cgit v1.2.2 From be7fbe6a8b4dd5b75db5a600bcd8de87f4761d85 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 18 Apr 2013 15:43:07 +0200 Subject: i2c: designware-plat: drop superfluous {get|put}_device Driver core already takes care of refcounting, no need to do this on driver level again. Signed-off-by: Wolfram Sang Tested-by: Mika Westerberg --- drivers/i2c/busses/i2c-designware-platdrv.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/i2c/busses/i2c-designware-platdrv.c') diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index dec939aca588..f7549b612ca5 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -170,9 +170,6 @@ static int dw_i2c_probe(struct platform_device *pdev) of_i2c_register_devices(adap); acpi_i2c_register_devices(adap); - /* Increase reference counter */ - get_device(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_active(&pdev->dev); @@ -188,7 +185,6 @@ static int dw_i2c_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); i2c_del_adapter(&dev->adapter); - put_device(&pdev->dev); i2c_dw_disable(dev); -- cgit v1.2.2