Commit 1955cfc8 authored by Sowjanya Komatineni's avatar Sowjanya Komatineni Committed by Greg Kroah-Hartman

spi: tegra114: reset controller on probe

[ Upstream commit 01919493 ]

Fixes: SPI driver can be built as module so perform SPI controller reset
on probe to make sure it is in valid state before initiating transfer.
Signed-off-by: default avatarSowjanya Komatineni <skomatineni@nvidia.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent ddd85a2f
...@@ -1067,27 +1067,19 @@ static int tegra_spi_probe(struct platform_device *pdev) ...@@ -1067,27 +1067,19 @@ static int tegra_spi_probe(struct platform_device *pdev)
spi_irq = platform_get_irq(pdev, 0); spi_irq = platform_get_irq(pdev, 0);
tspi->irq = spi_irq; tspi->irq = spi_irq;
ret = request_threaded_irq(tspi->irq, tegra_spi_isr,
tegra_spi_isr_thread, IRQF_ONESHOT,
dev_name(&pdev->dev), tspi);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
tspi->irq);
goto exit_free_master;
}
tspi->clk = devm_clk_get(&pdev->dev, "spi"); tspi->clk = devm_clk_get(&pdev->dev, "spi");
if (IS_ERR(tspi->clk)) { if (IS_ERR(tspi->clk)) {
dev_err(&pdev->dev, "can not get clock\n"); dev_err(&pdev->dev, "can not get clock\n");
ret = PTR_ERR(tspi->clk); ret = PTR_ERR(tspi->clk);
goto exit_free_irq; goto exit_free_master;
} }
tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) { if (IS_ERR(tspi->rst)) {
dev_err(&pdev->dev, "can not get reset\n"); dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst); ret = PTR_ERR(tspi->rst);
goto exit_free_irq; goto exit_free_master;
} }
tspi->max_buf_size = SPI_FIFO_DEPTH << 2; tspi->max_buf_size = SPI_FIFO_DEPTH << 2;
...@@ -1095,7 +1087,7 @@ static int tegra_spi_probe(struct platform_device *pdev) ...@@ -1095,7 +1087,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
ret = tegra_spi_init_dma_param(tspi, true); ret = tegra_spi_init_dma_param(tspi, true);
if (ret < 0) if (ret < 0)
goto exit_free_irq; goto exit_free_master;
ret = tegra_spi_init_dma_param(tspi, false); ret = tegra_spi_init_dma_param(tspi, false);
if (ret < 0) if (ret < 0)
goto exit_rx_dma_free; goto exit_rx_dma_free;
...@@ -1117,18 +1109,32 @@ static int tegra_spi_probe(struct platform_device *pdev) ...@@ -1117,18 +1109,32 @@ static int tegra_spi_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret); dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret);
goto exit_pm_disable; goto exit_pm_disable;
} }
reset_control_assert(tspi->rst);
udelay(2);
reset_control_deassert(tspi->rst);
tspi->def_command1_reg = SPI_M_S; tspi->def_command1_reg = SPI_M_S;
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
ret = request_threaded_irq(tspi->irq, tegra_spi_isr,
tegra_spi_isr_thread, IRQF_ONESHOT,
dev_name(&pdev->dev), tspi);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
tspi->irq);
goto exit_pm_disable;
}
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
ret = devm_spi_register_master(&pdev->dev, master); ret = devm_spi_register_master(&pdev->dev, master);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "can not register to master err %d\n", ret); dev_err(&pdev->dev, "can not register to master err %d\n", ret);
goto exit_pm_disable; goto exit_free_irq;
} }
return ret; return ret;
exit_free_irq:
free_irq(spi_irq, tspi);
exit_pm_disable: exit_pm_disable:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev)) if (!pm_runtime_status_suspended(&pdev->dev))
...@@ -1136,8 +1142,6 @@ static int tegra_spi_probe(struct platform_device *pdev) ...@@ -1136,8 +1142,6 @@ static int tegra_spi_probe(struct platform_device *pdev)
tegra_spi_deinit_dma_param(tspi, false); tegra_spi_deinit_dma_param(tspi, false);
exit_rx_dma_free: exit_rx_dma_free:
tegra_spi_deinit_dma_param(tspi, true); tegra_spi_deinit_dma_param(tspi, true);
exit_free_irq:
free_irq(spi_irq, tspi);
exit_free_master: exit_free_master:
spi_master_put(master); spi_master_put(master);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment