aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-omap-100k.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-07-10 10:40:19 -0400
committerMark Brown <broonie@linaro.org>2013-07-15 06:39:30 -0400
commite8153ab3d7ab33aad872fd36f91a22a1071ceabf (patch)
tree9ba05f05d2917487067647ce3c77bf08ccb34ea3 /drivers/spi/spi-omap-100k.c
parent69ea672a13a9b702ea3dc84de0cd9e1f4a088217 (diff)
spi/omap-100k: Factor message transfer function out of work queue
In preparation for removing the custom workqueue. Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-omap-100k.c')
-rw-r--r--drivers/spi/spi-omap-100k.c133
1 files changed, 68 insertions, 65 deletions
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
index 3b42a4ba8fa2..5999285f4cbd 100644
--- a/drivers/spi/spi-omap-100k.c
+++ b/drivers/spi/spi-omap-100k.c
@@ -321,10 +321,76 @@ static int omap1_spi100k_setup(struct spi_device *spi)
321 return ret; 321 return ret;
322} 322}
323 323
324static int omap1_spi100k_transfer_one_message(struct spi_master *master,
325 struct spi_message *m)
326{
327 struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
328 struct spi_device *spi = m->spi;
329 struct spi_transfer *t = NULL;
330 int cs_active = 0;
331 int par_override = 0;
332 int status = 0;
333
334 list_for_each_entry(t, &m->transfers, transfer_list) {
335 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
336 status = -EINVAL;
337 break;
338 }
339 if (par_override || t->speed_hz || t->bits_per_word) {
340 par_override = 1;
341 status = omap1_spi100k_setup_transfer(spi, t);
342 if (status < 0)
343 break;
344 if (!t->speed_hz && !t->bits_per_word)
345 par_override = 0;
346 }
347
348 if (!cs_active) {
349 omap1_spi100k_force_cs(spi100k, 1);
350 cs_active = 1;
351 }
352
353 if (t->len) {
354 unsigned count;
355
356 count = omap1_spi100k_txrx_pio(spi, t);
357 m->actual_length += count;
358
359 if (count != t->len) {
360 status = -EIO;
361 break;
362 }
363 }
364
365 if (t->delay_usecs)
366 udelay(t->delay_usecs);
367
368 /* ignore the "leave it on after last xfer" hint */
369
370 if (t->cs_change) {
371 omap1_spi100k_force_cs(spi100k, 0);
372 cs_active = 0;
373 }
374 }
375
376 /* Restore defaults if they were overriden */
377 if (par_override) {
378 par_override = 0;
379 status = omap1_spi100k_setup_transfer(spi, NULL);
380 }
381
382 if (cs_active)
383 omap1_spi100k_force_cs(spi100k, 0);
384
385 m->status = status;
386 m->complete(m->context);
387
388 return status;
389}
390
324static void omap1_spi100k_work(struct work_struct *work) 391static void omap1_spi100k_work(struct work_struct *work)
325{ 392{
326 struct omap1_spi100k *spi100k; 393 struct omap1_spi100k *spi100k;
327 int status = 0;
328 394
329 spi100k = container_of(work, struct omap1_spi100k, work); 395 spi100k = container_of(work, struct omap1_spi100k, work);
330 spin_lock_irq(&spi100k->lock); 396 spin_lock_irq(&spi100k->lock);
@@ -340,11 +406,6 @@ static void omap1_spi100k_work(struct work_struct *work)
340 */ 406 */
341 while (!list_empty(&spi100k->msg_queue)) { 407 while (!list_empty(&spi100k->msg_queue)) {
342 struct spi_message *m; 408 struct spi_message *m;
343 struct spi_device *spi;
344 struct spi_transfer *t = NULL;
345 int cs_active = 0;
346 struct omap1_spi100k_cs *cs;
347 int par_override = 0;
348 409
349 m = container_of(spi100k->msg_queue.next, struct spi_message, 410 m = container_of(spi100k->msg_queue.next, struct spi_message,
350 queue); 411 queue);
@@ -352,62 +413,7 @@ static void omap1_spi100k_work(struct work_struct *work)
352 list_del_init(&m->queue); 413 list_del_init(&m->queue);
353 spin_unlock_irq(&spi100k->lock); 414 spin_unlock_irq(&spi100k->lock);
354 415
355 spi = m->spi; 416 omap1_spi100k_transfer_one_message(m->spi->master, m);
356 cs = spi->controller_state;
357
358 list_for_each_entry(t, &m->transfers, transfer_list) {
359 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
360 status = -EINVAL;
361 break;
362 }
363 if (par_override || t->speed_hz || t->bits_per_word) {
364 par_override = 1;
365 status = omap1_spi100k_setup_transfer(spi, t);
366 if (status < 0)
367 break;
368 if (!t->speed_hz && !t->bits_per_word)
369 par_override = 0;
370 }
371
372 if (!cs_active) {
373 omap1_spi100k_force_cs(spi100k, 1);
374 cs_active = 1;
375 }
376
377 if (t->len) {
378 unsigned count;
379
380 count = omap1_spi100k_txrx_pio(spi, t);
381 m->actual_length += count;
382
383 if (count != t->len) {
384 status = -EIO;
385 break;
386 }
387 }
388
389 if (t->delay_usecs)
390 udelay(t->delay_usecs);
391
392 /* ignore the "leave it on after last xfer" hint */
393
394 if (t->cs_change) {
395 omap1_spi100k_force_cs(spi100k, 0);
396 cs_active = 0;
397 }
398 }
399
400 /* Restore defaults if they were overriden */
401 if (par_override) {
402 par_override = 0;
403 status = omap1_spi100k_setup_transfer(spi, NULL);
404 }
405
406 if (cs_active)
407 omap1_spi100k_force_cs(spi100k, 0);
408
409 m->status = status;
410 m->complete(m->context);
411 417
412 spin_lock_irq(&spi100k->lock); 418 spin_lock_irq(&spi100k->lock);
413 } 419 }
@@ -415,9 +421,6 @@ static void omap1_spi100k_work(struct work_struct *work)
415 clk_disable(spi100k->ick); 421 clk_disable(spi100k->ick);
416 clk_disable(spi100k->fck); 422 clk_disable(spi100k->fck);
417 spin_unlock_irq(&spi100k->lock); 423 spin_unlock_irq(&spi100k->lock);
418
419 if (status < 0)
420 printk(KERN_WARNING "spi transfer failed with %d\n", status);
421} 424}
422 425
423static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m) 426static int omap1_spi100k_transfer(struct spi_device *spi, struct spi_message *m)