Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: tegra114: add support for interrupt mask

This patch creates tegra_spi_soc_data structure to maintain and implement
SPI HW feature differences between different Tegra chips and also creates
a separate compatible string for T124/T210.

Tegra210 and later has a separate interrupt mask register SPI_INTR_MASK
for enabling or disabling interrupts while Tegra124 and prior uses
interrupt enable bits in SPI_DMA_CTL register.

This patch creates flag has_intr_mask_reg in tegra_spi_soc_data to
identify this and implements accordingly.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Sowjanya Komatineni and committed by
Mark Brown
fa28fd34 9d199231

+48 -5
+48 -5
drivers/spi/spi-tegra114.c
··· 149 149 150 150 #define SPI_TX_FIFO 0x108 151 151 #define SPI_RX_FIFO 0x188 152 + #define SPI_INTR_MASK 0x18c 153 + #define SPI_INTR_ALL_MASK (0x1fUL << 25) 152 154 #define MAX_CHIP_SELECT 4 153 155 #define SPI_FIFO_DEPTH 64 154 156 #define DATA_DIR_TX (1 << 0) ··· 162 160 #define RX_FIFO_FULL_COUNT_ZERO SPI_RX_FIFO_FULL_COUNT(0) 163 161 #define MAX_HOLD_CYCLES 16 164 162 #define SPI_DEFAULT_SPEED 25000000 163 + 164 + struct tegra_spi_soc_data { 165 + bool has_intr_mask_reg; 166 + }; 165 167 166 168 struct tegra_spi_data { 167 169 struct device *dev; ··· 217 211 u32 *tx_dma_buf; 218 212 dma_addr_t tx_dma_phys; 219 213 struct dma_async_tx_descriptor *tx_dma_desc; 214 + const struct tegra_spi_soc_data *soc_data; 220 215 }; 221 216 222 217 static int tegra_spi_runtime_suspend(struct device *dev); ··· 561 554 dma_burst = 8; 562 555 } 563 556 564 - if (tspi->cur_direction & DATA_DIR_TX) 565 - val |= SPI_IE_TX; 557 + if (!tspi->soc_data->has_intr_mask_reg) { 558 + if (tspi->cur_direction & DATA_DIR_TX) 559 + val |= SPI_IE_TX; 566 560 567 - if (tspi->cur_direction & DATA_DIR_RX) 568 - val |= SPI_IE_RX; 561 + if (tspi->cur_direction & DATA_DIR_RX) 562 + val |= SPI_IE_RX; 563 + } 569 564 570 565 tegra_spi_writel(tspi, val, SPI_DMA_CTL); 571 566 tspi->dma_control_reg = val; ··· 854 845 if (ret < 0) { 855 846 dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); 856 847 return ret; 848 + } 849 + 850 + if (tspi->soc_data->has_intr_mask_reg) { 851 + val = tegra_spi_readl(tspi, SPI_INTR_MASK); 852 + val &= ~SPI_INTR_ALL_MASK; 853 + tegra_spi_writel(tspi, val, SPI_INTR_MASK); 857 854 } 858 855 859 856 spin_lock_irqsave(&tspi->lock, flags); ··· 1150 1135 return IRQ_WAKE_THREAD; 1151 1136 } 1152 1137 1138 + static struct tegra_spi_soc_data tegra114_spi_soc_data = { 1139 + .has_intr_mask_reg = false, 1140 + }; 1141 + 1142 + static struct tegra_spi_soc_data tegra124_spi_soc_data = { 1143 + .has_intr_mask_reg = false, 1144 + }; 1145 + 1146 + static struct tegra_spi_soc_data tegra210_spi_soc_data = { 1147 + .has_intr_mask_reg = true, 1148 + }; 1149 + 1153 1150 static const struct of_device_id tegra_spi_of_match[] = { 1154 - { .compatible = "nvidia,tegra114-spi", }, 1151 + { 1152 + .compatible = "nvidia,tegra114-spi", 1153 + .data = &tegra114_spi_soc_data, 1154 + }, { 1155 + .compatible = "nvidia,tegra124-spi", 1156 + .data = &tegra124_spi_soc_data, 1157 + }, { 1158 + .compatible = "nvidia,tegra210-spi", 1159 + .data = &tegra210_spi_soc_data, 1160 + }, 1155 1161 {} 1156 1162 }; 1157 1163 MODULE_DEVICE_TABLE(of, tegra_spi_of_match); ··· 1212 1176 tspi->master = master; 1213 1177 tspi->dev = &pdev->dev; 1214 1178 spin_lock_init(&tspi->lock); 1179 + 1180 + tspi->soc_data = of_device_get_match_data(&pdev->dev); 1181 + if (!tspi->soc_data) { 1182 + dev_err(&pdev->dev, "unsupported tegra\n"); 1183 + ret = -ENODEV; 1184 + goto exit_free_master; 1185 + } 1215 1186 1216 1187 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1217 1188 tspi->base = devm_ioremap_resource(&pdev->dev, r);