@@ -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)
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(-)