| From 0774f91e633f407c9b2c084b74d8d073a13bd46e Mon Sep 17 00:00:00 2001 |
| From: Sowjanya Komatineni <skomatineni@nvidia.com> |
| Date: Tue, 26 Mar 2019 22:56:32 -0700 |
| Subject: spi: tegra114: reset controller on probe |
| |
| [ Upstream commit 019194933339b3e9b486639c8cb3692020844d65 ] |
| |
| 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: Sowjanya Komatineni <skomatineni@nvidia.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/spi/spi-tegra114.c | 32 ++++++++++++++++++-------------- |
| 1 file changed, 18 insertions(+), 14 deletions(-) |
| |
| diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c |
| index a76acedd7e2f4..a1888dc6a938a 100644 |
| --- a/drivers/spi/spi-tegra114.c |
| +++ b/drivers/spi/spi-tegra114.c |
| @@ -1067,27 +1067,19 @@ static int tegra_spi_probe(struct platform_device *pdev) |
| |
| spi_irq = platform_get_irq(pdev, 0); |
| 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"); |
| if (IS_ERR(tspi->clk)) { |
| dev_err(&pdev->dev, "can not get clock\n"); |
| ret = PTR_ERR(tspi->clk); |
| - goto exit_free_irq; |
| + goto exit_free_master; |
| } |
| |
| tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); |
| if (IS_ERR(tspi->rst)) { |
| dev_err(&pdev->dev, "can not get reset\n"); |
| ret = PTR_ERR(tspi->rst); |
| - goto exit_free_irq; |
| + goto exit_free_master; |
| } |
| |
| tspi->max_buf_size = SPI_FIFO_DEPTH << 2; |
| @@ -1095,7 +1087,7 @@ static int tegra_spi_probe(struct platform_device *pdev) |
| |
| ret = tegra_spi_init_dma_param(tspi, true); |
| if (ret < 0) |
| - goto exit_free_irq; |
| + goto exit_free_master; |
| ret = tegra_spi_init_dma_param(tspi, false); |
| if (ret < 0) |
| goto exit_rx_dma_free; |
| @@ -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); |
| goto exit_pm_disable; |
| } |
| + |
| + reset_control_assert(tspi->rst); |
| + udelay(2); |
| + reset_control_deassert(tspi->rst); |
| tspi->def_command1_reg = SPI_M_S; |
| tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); |
| 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; |
| ret = devm_spi_register_master(&pdev->dev, master); |
| if (ret < 0) { |
| dev_err(&pdev->dev, "can not register to master err %d\n", ret); |
| - goto exit_pm_disable; |
| + goto exit_free_irq; |
| } |
| return ret; |
| |
| +exit_free_irq: |
| + free_irq(spi_irq, tspi); |
| exit_pm_disable: |
| pm_runtime_disable(&pdev->dev); |
| if (!pm_runtime_status_suspended(&pdev->dev)) |
| @@ -1136,8 +1142,6 @@ static int tegra_spi_probe(struct platform_device *pdev) |
| tegra_spi_deinit_dma_param(tspi, false); |
| exit_rx_dma_free: |
| tegra_spi_deinit_dma_param(tspi, true); |
| -exit_free_irq: |
| - free_irq(spi_irq, tspi); |
| exit_free_master: |
| spi_master_put(master); |
| return ret; |
| -- |
| 2.20.1 |
| |