summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémy Dufour2011-02-07 16:09:24 +0100
committerJérémy Dufour2011-02-08 15:11:04 +0100
commita7f383e1716317c82bd8b7e972787c69926285ec (patch)
tree66f0e8d206eb9bae8e8855149036aa52716a67aa
parentd5ace8af50961704dc48921aadaa87a1445109f5 (diff)
cleo/linux/drivers/spi: lock IRQ when doing a spin_lock, refs #2287
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/spi/spc300_spi.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/spi/spc300_spi.c b/cleopatre/linux-2.6.25.10-spc300/drivers/spi/spc300_spi.c
index d2330e338d..f794c1427e 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/spi/spc300_spi.c
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/spi/spc300_spi.c
@@ -401,8 +401,9 @@ static void spc300_spi_work(struct work_struct *work)
struct spc300_transfer grptransfer;
uint8_t bpw;
int status;
+ unsigned long flags;
- spin_lock_irq(&ss->lock);
+ spin_lock_irqsave(&ss->lock, flags);
ss->busy = 1;
//Empty the message queue
@@ -411,7 +412,7 @@ static void spc300_spi_work(struct work_struct *work)
//Restore msg queue
msg = list_first_entry(&ss->queue, struct spi_message, queue);
list_del_init(&msg->queue);
- spin_unlock_irq(&ss->lock);
+ spin_unlock_irqrestore(&ss->lock, flags);
spi = msg->spi;
status = 0;
@@ -569,11 +570,11 @@ static void spc300_spi_work(struct work_struct *work)
//Call SPI device driver that transfer is ending
msg->complete(msg->context);
- spin_lock_irq(&ss->lock);
+ spin_lock_irqsave(&ss->lock, flags);
}
ss->busy = 0;
- spin_unlock_irq(&ss->lock);
+ spin_unlock_irqrestore(&ss->lock, flags);
}
/**
@@ -776,20 +777,21 @@ static int __exit spc300_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct spc300_spi *ss = spi_master_get_devdata(master);
+ unsigned long flags;
//Remove work queue
flush_workqueue(ss->workqueue);
destroy_workqueue(ss->workqueue);
//TODO:Stop hardware
- spin_lock_irq(&ss->lock);
+ spin_lock_irqsave(&ss->lock, flags);
spi_writel(ss, SER, 0); //No chip selected
spi_writel(ss, REG_MASK, SPI_BF(EMPT_TX,1) | //Mask all IRQ sources
SPI_BF(FULL_TX,1) |
SPI_BF(EMPT_RX,1) |
SPI_BF(FULL_RX,1) |
SPI_BF(RX,1));
- spin_unlock_irq(&ss->lock);
+ spin_unlock_irqrestore(&ss->lock, flags);
//Unregister IRQ
free_irq(ss->irq, master);