[PATCH v4 13/31] i2c: tegra: Clean up probe function

Dmitry Osipenko
2020-09-05T20:46:02Z

The driver's probe function code is a bit difficult to read. This patch
reorders code of the probe function, forming groups of code that are easy
to work with. The reset_control_get() now may return -EPROBE_DEFER on
newer Tegra SoCs because they use BPMP driver that provides reset controls
and BPMP doesn't come up early during boot, previously rst was protected
by other checks error checks in the code, hence dev_err_probe() is used
now for the rst.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/i2c/busses/i2c-tegra.c | 120 +++++++++++++++++----------------
1 file changed, 63 insertions(+), 57 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index d6bc23bf765e..d8b7373673ea 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -440,6 +440,9 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)

i2c_dev->tx_dma_chan = chan;

+ i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len +
+ I2C_PACKET_HEADER_SIZE;
+
dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
&dma_phys, GFP_KERNEL | __GFP_NOWARN);
if (!dma_buf) {
@@ -1711,85 +1714,88 @@ static int tegra_i2c_probe(struct platform_device *pdev)
{
struct tegra_i2c_dev *i2c_dev;
struct resource *res;
- void __iomem *base;
- phys_addr_t base_phys;
- int irq;
- int ret;
-
- base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(base))
- return PTR_ERR(base);
-
- base_phys = res->start;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
+ int err;

i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return -ENOMEM;

- i2c_dev->base = base;
- i2c_dev->base_phys = base_phys;
- i2c_dev->adapter.algo = &tegra_i2c_algo;
- i2c_dev->adapter.retries = 1;
- i2c_dev->adapter.timeout = 6 * HZ;
- i2c_dev->irq = irq;
+ platform_set_drvdata(pdev, i2c_dev);
+
+ init_completion(&i2c_dev->msg_complete);
+ init_completion(&i2c_dev->dma_complete);
+
+ i2c_dev->hw = of_device_get_match_data(&pdev->dev);
i2c_dev->cont_id = pdev->id;
i2c_dev->dev = &pdev->dev;

- i2c_dev->rst = devm_reset_control_get_exclusive(&pdev->dev, "i2c");
+ /* initialize virt base of hardware registers */
+ i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(i2c_dev->base))
+ return PTR_ERR(i2c_dev->base);
+
+ /* initialize phys base of hardware registers */
+ i2c_dev->base_phys = res->start;
+
+ /* initialize controller's interrupt */
+ err = platform_get_irq(pdev, 0);
+ if (err < 0)
+ return err;
+
+ i2c_dev->irq = err;
+
+ /* interrupt will be enabled during of transfer time */
+ irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
+
+ err = devm_request_irq(i2c_dev->dev, i2c_dev->irq, tegra_i2c_isr,
+ IRQF_NO_SUSPEND, dev_name(i2c_dev->dev),
+ i2c_dev);
+ if (err)
+ return err;
+
+ /* initialize hardware reset control */
+ i2c_dev->rst = devm_reset_control_get_exclusive(i2c_dev->dev, "i2c");
if (IS_ERR(i2c_dev->rst)) {
- dev_err(&pdev->dev, "missing controller reset\n");
+ dev_err_probe(i2c_dev->dev, PTR_ERR(i2c_dev->rst),
+ "failed to get reset control\n");
return PTR_ERR(i2c_dev->rst);
}

tegra_i2c_parse_dt(i2c_dev);

- ret = tegra_i2c_init_clocks(i2c_dev);
- if (ret)
- return ret;
-
- i2c_dev->hw = of_device_get_match_data(&pdev->dev);
- i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
- i2c_dev->dma_buf_size = i2c_dev->adapter.quirks->max_write_len +
- I2C_PACKET_HEADER_SIZE;
- init_completion(&i2c_dev->msg_complete);
- init_completion(&i2c_dev->dma_complete);
-
- platform_set_drvdata(pdev, i2c_dev);
-
- if (i2c_dev->hw->supports_bus_clear)
- i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
+ err = tegra_i2c_init_clocks(i2c_dev);
+ if (err)
+ return err;

- ret = tegra_i2c_init_dma(i2c_dev);
- if (ret < 0)
+ err = tegra_i2c_init_dma(i2c_dev);
+ if (err)
goto release_clocks;

- ret = tegra_i2c_init_runtime_pm_and_hardware(i2c_dev);
- if (ret)
+ err = tegra_i2c_init_runtime_pm_and_hardware(i2c_dev);
+ if (err)
goto release_dma;

- irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
-
- ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
- IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c_dev);
- if (ret)
- goto release_rpm;
-
- i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
+ i2c_dev->adapter.dev.of_node = i2c_dev->dev->of_node;
+ i2c_dev->adapter.dev.parent = i2c_dev->dev;
+ i2c_dev->adapter.retries = 1;
+ i2c_dev->adapter.timeout = 6 * HZ;
+ i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
i2c_dev->adapter.owner = THIS_MODULE;
i2c_dev->adapter.class = I2C_CLASS_DEPRECATED;
- strlcpy(i2c_dev->adapter.name, dev_name(&pdev->dev),
+ i2c_dev->adapter.algo = &tegra_i2c_algo;
+ i2c_dev->adapter.nr = i2c_dev->cont_id;
+
+ if (i2c_dev->hw->supports_bus_clear)
+ i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
+
+ strlcpy(i2c_dev->adapter.name, dev_name(i2c_dev->dev),
sizeof(i2c_dev->adapter.name));
- i2c_dev->adapter.dev.parent = &pdev->dev;
- i2c_dev->adapter.nr = pdev->id;
- i2c_dev->adapter.dev.of_node = pdev->dev.of_node;

- ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
- if (ret)
- goto release_dma;
+ i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
+
+ err = i2c_add_numbered_adapter(&i2c_dev->adapter);
+ if (err)
+ goto release_rpm;

return 0;

@@ -1800,7 +1806,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
release_clocks:
tegra_i2c_release_clocks(i2c_dev);

- return ret;
+ return err;
}

static int tegra_i2c_remove(struct platform_device *pdev)
--
2.27.0