diff options
-rw-r--r-- | drivers/spi/spi-xilinx.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 026f4c59a941..337fda4e78a6 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
@@ -128,7 +128,6 @@ static void xilinx_spi_rx(struct xilinx_spi *xspi) | |||
128 | static void xspi_init_hw(struct xilinx_spi *xspi) | 128 | static void xspi_init_hw(struct xilinx_spi *xspi) |
129 | { | 129 | { |
130 | void __iomem *regs_base = xspi->regs; | 130 | void __iomem *regs_base = xspi->regs; |
131 | u32 inhibit; | ||
132 | 131 | ||
133 | /* Reset the SPI device */ | 132 | /* Reset the SPI device */ |
134 | xspi->write_fn(XIPIF_V123B_RESET_MASK, | 133 | xspi->write_fn(XIPIF_V123B_RESET_MASK, |
@@ -138,22 +137,15 @@ static void xspi_init_hw(struct xilinx_spi *xspi) | |||
138 | */ | 137 | */ |
139 | xspi->write_fn(XSPI_INTR_TX_EMPTY, | 138 | xspi->write_fn(XSPI_INTR_TX_EMPTY, |
140 | regs_base + XIPIF_V123B_IIER_OFFSET); | 139 | regs_base + XIPIF_V123B_IIER_OFFSET); |
141 | /* Enable the global IPIF interrupt */ | 140 | /* Disable the global IPIF interrupt */ |
142 | if (xspi->irq >= 0) { | 141 | xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); |
143 | xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, | ||
144 | regs_base + XIPIF_V123B_DGIER_OFFSET); | ||
145 | inhibit = XSPI_CR_TRANS_INHIBIT; | ||
146 | } else { | ||
147 | xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); | ||
148 | inhibit = 0; | ||
149 | } | ||
150 | /* Deselect the slave on the SPI bus */ | 142 | /* Deselect the slave on the SPI bus */ |
151 | xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET); | 143 | xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET); |
152 | /* Disable the transmitter, enable Manual Slave Select Assertion, | 144 | /* Disable the transmitter, enable Manual Slave Select Assertion, |
153 | * put SPI controller into master mode, and enable it */ | 145 | * put SPI controller into master mode, and enable it */ |
154 | xspi->write_fn(inhibit | XSPI_CR_MANUAL_SSELECT | | 146 | xspi->write_fn(XSPI_CR_MANUAL_SSELECT | XSPI_CR_MASTER_MODE | |
155 | XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | | 147 | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | XSPI_CR_RXFIFO_RESET, |
156 | XSPI_CR_RXFIFO_RESET, regs_base + XSPI_CR_OFFSET); | 148 | regs_base + XSPI_CR_OFFSET); |
157 | } | 149 | } |
158 | 150 | ||
159 | static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) | 151 | static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) |
@@ -212,6 +204,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
212 | { | 204 | { |
213 | struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); | 205 | struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); |
214 | int remaining_words; /* the number of words left to transfer */ | 206 | int remaining_words; /* the number of words left to transfer */ |
207 | bool use_irq = false; | ||
208 | u16 cr = 0; | ||
215 | 209 | ||
216 | /* We get here with transmitter inhibited */ | 210 | /* We get here with transmitter inhibited */ |
217 | 211 | ||
@@ -220,8 +214,20 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
220 | remaining_words = t->len / xspi->bytes_per_word; | 214 | remaining_words = t->len / xspi->bytes_per_word; |
221 | reinit_completion(&xspi->done); | 215 | reinit_completion(&xspi->done); |
222 | 216 | ||
217 | if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) { | ||
218 | use_irq = true; | ||
219 | xspi->write_fn(XSPI_INTR_TX_EMPTY, | ||
220 | xspi->regs + XIPIF_V123B_IISR_OFFSET); | ||
221 | /* Enable the global IPIF interrupt */ | ||
222 | xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, | ||
223 | xspi->regs + XIPIF_V123B_DGIER_OFFSET); | ||
224 | /* Inhibit irq to avoid spurious irqs on tx_empty*/ | ||
225 | cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); | ||
226 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, | ||
227 | xspi->regs + XSPI_CR_OFFSET); | ||
228 | } | ||
229 | |||
223 | while (remaining_words) { | 230 | while (remaining_words) { |
224 | u16 cr = 0; | ||
225 | int n_words, tx_words, rx_words; | 231 | int n_words, tx_words, rx_words; |
226 | 232 | ||
227 | n_words = min(remaining_words, xspi->buffer_size); | 233 | n_words = min(remaining_words, xspi->buffer_size); |
@@ -234,9 +240,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
234 | * longer | 240 | * longer |
235 | */ | 241 | */ |
236 | 242 | ||
237 | if (xspi->irq >= 0) { | 243 | if (use_irq) { |
238 | cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & | ||
239 | ~XSPI_CR_TRANS_INHIBIT; | ||
240 | xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); | 244 | xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); |
241 | wait_for_completion(&xspi->done); | 245 | wait_for_completion(&xspi->done); |
242 | } else | 246 | } else |
@@ -249,7 +253,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
249 | * transmitter while the Isr refills the transmit register/FIFO, | 253 | * transmitter while the Isr refills the transmit register/FIFO, |
250 | * or make sure it is stopped if we're done. | 254 | * or make sure it is stopped if we're done. |
251 | */ | 255 | */ |
252 | if (xspi->irq >= 0) | 256 | if (use_irq) |
253 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, | 257 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, |
254 | xspi->regs + XSPI_CR_OFFSET); | 258 | xspi->regs + XSPI_CR_OFFSET); |
255 | 259 | ||
@@ -261,6 +265,9 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
261 | remaining_words -= n_words; | 265 | remaining_words -= n_words; |
262 | } | 266 | } |
263 | 267 | ||
268 | if (use_irq) | ||
269 | xspi->write_fn(0, xspi->regs + XIPIF_V123B_DGIER_OFFSET); | ||
270 | |||
264 | return t->len; | 271 | return t->len; |
265 | } | 272 | } |
266 | 273 | ||