aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-08-29 02:47:57 -0400
committerMark Brown <broonie@kernel.org>2018-09-03 07:23:41 -0400
commit7001cab1dabc0b72b2b672ef58a90ab64f5e2343 (patch)
treef7c53816c6638be385238894556b29c210eda46b
parent5223c9c1cbfc0cd4d0a1b50758e0949af3290fa1 (diff)
spi: tegra20-slink: explicitly enable/disable clock
Depending on the SPI instance one may get an interrupt storm upon requesting resp. interrupt unless the clock is explicitly enabled beforehand. This has been observed trying to bring up instance 4 on T20. Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> Signed-off-by: Mark Brown <broonie@kernel.org> Cc: stable@vger.kernel.org
-rw-r--r--drivers/spi/spi-tegra20-slink.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
index 6f7b946b5ced..1427f343b39a 100644
--- a/drivers/spi/spi-tegra20-slink.c
+++ b/drivers/spi/spi-tegra20-slink.c
@@ -1063,6 +1063,24 @@ static int tegra_slink_probe(struct platform_device *pdev)
1063 goto exit_free_master; 1063 goto exit_free_master;
1064 } 1064 }
1065 1065
1066 /* disabled clock may cause interrupt storm upon request */
1067 tspi->clk = devm_clk_get(&pdev->dev, NULL);
1068 if (IS_ERR(tspi->clk)) {
1069 ret = PTR_ERR(tspi->clk);
1070 dev_err(&pdev->dev, "Can not get clock %d\n", ret);
1071 goto exit_free_master;
1072 }
1073 ret = clk_prepare(tspi->clk);
1074 if (ret < 0) {
1075 dev_err(&pdev->dev, "Clock prepare failed %d\n", ret);
1076 goto exit_free_master;
1077 }
1078 ret = clk_enable(tspi->clk);
1079 if (ret < 0) {
1080 dev_err(&pdev->dev, "Clock enable failed %d\n", ret);
1081 goto exit_free_master;
1082 }
1083
1066 spi_irq = platform_get_irq(pdev, 0); 1084 spi_irq = platform_get_irq(pdev, 0);
1067 tspi->irq = spi_irq; 1085 tspi->irq = spi_irq;
1068 ret = request_threaded_irq(tspi->irq, tegra_slink_isr, 1086 ret = request_threaded_irq(tspi->irq, tegra_slink_isr,
@@ -1071,14 +1089,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
1071 if (ret < 0) { 1089 if (ret < 0) {
1072 dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", 1090 dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
1073 tspi->irq); 1091 tspi->irq);
1074 goto exit_free_master; 1092 goto exit_clk_disable;
1075 }
1076
1077 tspi->clk = devm_clk_get(&pdev->dev, NULL);
1078 if (IS_ERR(tspi->clk)) {
1079 dev_err(&pdev->dev, "can not get clock\n");
1080 ret = PTR_ERR(tspi->clk);
1081 goto exit_free_irq;
1082 } 1093 }
1083 1094
1084 tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); 1095 tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
@@ -1138,6 +1149,8 @@ exit_rx_dma_free:
1138 tegra_slink_deinit_dma_param(tspi, true); 1149 tegra_slink_deinit_dma_param(tspi, true);
1139exit_free_irq: 1150exit_free_irq:
1140 free_irq(spi_irq, tspi); 1151 free_irq(spi_irq, tspi);
1152exit_clk_disable:
1153 clk_disable(tspi->clk);
1141exit_free_master: 1154exit_free_master:
1142 spi_master_put(master); 1155 spi_master_put(master);
1143 return ret; 1156 return ret;
@@ -1150,6 +1163,8 @@ static int tegra_slink_remove(struct platform_device *pdev)
1150 1163
1151 free_irq(tspi->irq, tspi); 1164 free_irq(tspi->irq, tspi);
1152 1165
1166 clk_disable(tspi->clk);
1167
1153 if (tspi->tx_dma_chan) 1168 if (tspi->tx_dma_chan)
1154 tegra_slink_deinit_dma_param(tspi, false); 1169 tegra_slink_deinit_dma_param(tspi, false);
1155 1170