diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2013-10-02 10:45:25 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-10-07 06:29:22 -0400 |
commit | 3b3a80019ff194e86e740ec2f013a8915efd1ccf (patch) | |
tree | 77302f92a25ec4ebadfea270c00572d7592d8d8a /drivers/spi/spi-ti-qspi.c | |
parent | 633795b992ebae2a78890c0cfa5c17058eb93817 (diff) |
spi: ti-qspi: one only one interrupt handler
The here used irq and threaded irq handler is a complete non-sense. After
the status register is read and the source disabled it schedules a thread
(the irq thread) to read the status from the variable, invoke complete()
and then renable the interrupt. Again: schedule a thread which invokes
_only_ complete().
This patch removes this non-sense and we remain with one handler which
invokes complete() if needed.
The device remove path should now disable the interupts.
This has been compile time tested.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-ti-qspi.c')
-rw-r--r-- | drivers/spi/spi-ti-qspi.c | 39 |
1 files changed, 6 insertions, 33 deletions
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 7a45c3e665f8..a61aeb9bb823 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
@@ -41,9 +41,6 @@ struct ti_qspi_regs { | |||
41 | struct ti_qspi { | 41 | struct ti_qspi { |
42 | struct completion transfer_complete; | 42 | struct completion transfer_complete; |
43 | 43 | ||
44 | /* IRQ synchronization */ | ||
45 | spinlock_t lock; | ||
46 | |||
47 | /* list synchronization */ | 44 | /* list synchronization */ |
48 | struct mutex list_lock; | 45 | struct mutex list_lock; |
49 | 46 | ||
@@ -57,7 +54,6 @@ struct ti_qspi { | |||
57 | u32 spi_max_frequency; | 54 | u32 spi_max_frequency; |
58 | u32 cmd; | 55 | u32 cmd; |
59 | u32 dc; | 56 | u32 dc; |
60 | u32 stat; | ||
61 | }; | 57 | }; |
62 | 58 | ||
63 | #define QSPI_PID (0x0) | 59 | #define QSPI_PID (0x0) |
@@ -397,13 +393,12 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id) | |||
397 | { | 393 | { |
398 | struct ti_qspi *qspi = dev_id; | 394 | struct ti_qspi *qspi = dev_id; |
399 | u16 int_stat; | 395 | u16 int_stat; |
396 | u32 stat; | ||
400 | 397 | ||
401 | irqreturn_t ret = IRQ_HANDLED; | 398 | irqreturn_t ret = IRQ_HANDLED; |
402 | 399 | ||
403 | spin_lock(&qspi->lock); | ||
404 | |||
405 | int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); | 400 | int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); |
406 | qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); | 401 | stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); |
407 | 402 | ||
408 | if (!int_stat) { | 403 | if (!int_stat) { |
409 | dev_dbg(qspi->dev, "No IRQ triggered\n"); | 404 | dev_dbg(qspi->dev, "No IRQ triggered\n"); |
@@ -411,35 +406,14 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id) | |||
411 | goto out; | 406 | goto out; |
412 | } | 407 | } |
413 | 408 | ||
414 | ret = IRQ_WAKE_THREAD; | ||
415 | |||
416 | ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); | ||
417 | ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, | 409 | ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, |
418 | QSPI_INTR_STATUS_ENABLED_CLEAR); | 410 | QSPI_INTR_STATUS_ENABLED_CLEAR); |
419 | 411 | if (stat & WC) | |
412 | complete(&qspi->transfer_complete); | ||
420 | out: | 413 | out: |
421 | spin_unlock(&qspi->lock); | ||
422 | |||
423 | return ret; | 414 | return ret; |
424 | } | 415 | } |
425 | 416 | ||
426 | static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id) | ||
427 | { | ||
428 | struct ti_qspi *qspi = dev_id; | ||
429 | unsigned long flags; | ||
430 | |||
431 | spin_lock_irqsave(&qspi->lock, flags); | ||
432 | |||
433 | if (qspi->stat & WC) | ||
434 | complete(&qspi->transfer_complete); | ||
435 | |||
436 | spin_unlock_irqrestore(&qspi->lock, flags); | ||
437 | |||
438 | ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); | ||
439 | |||
440 | return IRQ_HANDLED; | ||
441 | } | ||
442 | |||
443 | static int ti_qspi_runtime_resume(struct device *dev) | 417 | static int ti_qspi_runtime_resume(struct device *dev) |
444 | { | 418 | { |
445 | struct ti_qspi *qspi; | 419 | struct ti_qspi *qspi; |
@@ -499,7 +473,6 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
499 | return irq; | 473 | return irq; |
500 | } | 474 | } |
501 | 475 | ||
502 | spin_lock_init(&qspi->lock); | ||
503 | mutex_init(&qspi->list_lock); | 476 | mutex_init(&qspi->list_lock); |
504 | 477 | ||
505 | qspi->base = devm_ioremap_resource(&pdev->dev, r); | 478 | qspi->base = devm_ioremap_resource(&pdev->dev, r); |
@@ -508,8 +481,7 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
508 | goto free_master; | 481 | goto free_master; |
509 | } | 482 | } |
510 | 483 | ||
511 | ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr, | 484 | ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, |
512 | ti_qspi_threaded_isr, 0, | ||
513 | dev_name(&pdev->dev), qspi); | 485 | dev_name(&pdev->dev), qspi); |
514 | if (ret < 0) { | 486 | if (ret < 0) { |
515 | dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", | 487 | dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", |
@@ -547,6 +519,7 @@ static int ti_qspi_remove(struct platform_device *pdev) | |||
547 | { | 519 | { |
548 | struct ti_qspi *qspi = platform_get_drvdata(pdev); | 520 | struct ti_qspi *qspi = platform_get_drvdata(pdev); |
549 | 521 | ||
522 | ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); | ||
550 | spi_unregister_master(qspi->master); | 523 | spi_unregister_master(qspi->master); |
551 | 524 | ||
552 | return 0; | 525 | return 0; |