summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/imx31/spi-imx31.c33
1 files changed, 14 insertions, 19 deletions
diff --git a/firmware/target/arm/imx31/spi-imx31.c b/firmware/target/arm/imx31/spi-imx31.c
index 34dac9b6a7..bc2e4d31e0 100644
--- a/firmware/target/arm/imx31/spi-imx31.c
+++ b/firmware/target/arm/imx31/spi-imx31.c
@@ -121,6 +121,7 @@ static bool spi_set_context(struct spi_module_desc *desc,
121 /* Keep reserved and start bits cleared. Keep enabled bit. */ 121 /* Keep reserved and start bits cleared. Keep enabled bit. */
122 base[CONREG] = 122 base[CONREG] =
123 (node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC)); 123 (node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC));
124
124 return true; 125 return true;
125} 126}
126 127
@@ -166,19 +167,20 @@ static int tx_fill_fifo(struct spi_module_desc * const desc,
166static bool start_transfer(struct spi_module_desc * const desc, 167static bool start_transfer(struct spi_module_desc * const desc,
167 struct spi_transfer_desc * const xfer) 168 struct spi_transfer_desc * const xfer)
168{ 169{
169 volatile unsigned long * const base = desc->base;
170 unsigned long intreg;
171
172 if (!spi_set_context(desc, xfer)) 170 if (!spi_set_context(desc, xfer))
173 { 171 {
174 xfer->count = -1; 172 xfer->count = -1;
175 return false; 173 return false;
176 } 174 }
177 175
176 volatile unsigned long * const base = desc->base;
177
178 base[CONREG] |= CSPI_CONREG_EN; /* Enable module */ 178 base[CONREG] |= CSPI_CONREG_EN; /* Enable module */
179 179
180 desc->rxcount = xfer->count; 180 desc->rxcount = xfer->count;
181 181
182 unsigned long intreg;
183
182 intreg = (xfer->count < 8) ? 184 intreg = (xfer->count < 8) ?
183 CSPI_INTREG_TCEN : /* Trans. complete: TX will run out in prefill */ 185 CSPI_INTREG_TCEN : /* Trans. complete: TX will run out in prefill */
184 CSPI_INTREG_THEN; /* INT when TX half-empty */ 186 CSPI_INTREG_THEN; /* INT when TX half-empty */
@@ -197,9 +199,8 @@ static bool start_transfer(struct spi_module_desc * const desc,
197} 199}
198 200
199/* Common code for interrupt handlers */ 201/* Common code for interrupt handlers */
200static void spi_interrupt(enum spi_module_number spi) 202static void spi_interrupt(struct spi_module_desc * const desc)
201{ 203{
202 struct spi_module_desc *desc = &spi_descs[spi];
203 volatile unsigned long * const base = desc->base; 204 volatile unsigned long * const base = desc->base;
204 unsigned long intreg = base[INTREG]; 205 unsigned long intreg = base[INTREG];
205 struct spi_transfer_desc *xfer = desc->head; 206 struct spi_transfer_desc *xfer = desc->head;
@@ -323,29 +324,28 @@ static void spi_interrupt(enum spi_module_number spi)
323#if (SPI_MODULE_MASK & USE_CSPI1_MODULE) 324#if (SPI_MODULE_MASK & USE_CSPI1_MODULE)
324static __attribute__((interrupt("IRQ"))) void CSPI1_HANDLER(void) 325static __attribute__((interrupt("IRQ"))) void CSPI1_HANDLER(void)
325{ 326{
326 spi_interrupt(CSPI1_NUM); 327 spi_interrupt(&spi_descs[CSPI1_NUM]);
327} 328}
328#endif 329#endif
329 330
330#if (SPI_MODULE_MASK & USE_CSPI2_MODULE) 331#if (SPI_MODULE_MASK & USE_CSPI2_MODULE)
331static __attribute__((interrupt("IRQ"))) void CSPI2_HANDLER(void) 332static __attribute__((interrupt("IRQ"))) void CSPI2_HANDLER(void)
332{ 333{
333 spi_interrupt(CSPI2_NUM); 334 spi_interrupt(&spi_descs[CSPI2_NUM]);
334} 335}
335#endif 336#endif
336 337
337#if (SPI_MODULE_MASK & USE_CSPI3_MODULE) 338#if (SPI_MODULE_MASK & USE_CSPI3_MODULE)
338static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void) 339static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void)
339{ 340{
340 spi_interrupt(CSPI3_NUM); 341 spi_interrupt(&spi_descs[CSPI3_NUM]);
341} 342}
342#endif 343#endif
343 344
344/* Initialize the SPI driver */ 345/* Initialize the SPI driver */
345void INIT_ATTR spi_init(void) 346void INIT_ATTR spi_init(void)
346{ 347{
347 unsigned i; 348 for (int i = 0; i < SPI_NUM_CSPI; i++)
348 for (i = 0; i < SPI_NUM_CSPI; i++)
349 { 349 {
350 struct spi_module_desc * const desc = &spi_descs[i]; 350 struct spi_module_desc * const desc = &spi_descs[i];
351 ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT); 351 ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT);
@@ -396,10 +396,6 @@ void spi_enable_node(const struct spi_node *node, bool enable)
396/* Send and/or receive data on the specified node */ 396/* Send and/or receive data on the specified node */
397bool spi_transfer(struct spi_transfer_desc *xfer) 397bool spi_transfer(struct spi_transfer_desc *xfer)
398{ 398{
399 bool retval;
400 struct spi_module_desc * desc;
401 int oldlevel;
402
403 if (xfer->count == 0) 399 if (xfer->count == 0)
404 return true; /* No data? No problem. */ 400 return true; /* No data? No problem. */
405 401
@@ -410,9 +406,9 @@ bool spi_transfer(struct spi_transfer_desc *xfer)
410 return false; 406 return false;
411 } 407 }
412 408
413 oldlevel = disable_irq_save(); 409 bool retval = true;
414 410 unsigned long cpsr = disable_irq_save();
415 desc = &spi_descs[xfer->node->num]; 411 struct spi_module_desc * const desc = &spi_descs[xfer->node->num];
416 412
417 if (desc->head == NULL) 413 if (desc->head == NULL)
418 { 414 {
@@ -434,10 +430,9 @@ bool spi_transfer(struct spi_transfer_desc *xfer)
434 desc->tail->next = xfer; /* Add to tail */ 430 desc->tail->next = xfer; /* Add to tail */
435 desc->tail = xfer; /* New tail */ 431 desc->tail = xfer; /* New tail */
436 xfer->next = xfer; /* Self-reference terminate */ 432 xfer->next = xfer; /* Self-reference terminate */
437 retval = true;
438 } 433 }
439 434
440 restore_irq(oldlevel); 435 restore_irq(cpsr);
441 436
442 return retval; 437 return retval;
443} 438}