From a55eb9ac6d79baee2931f63357a256f36e9854bd Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 10 May 2010 13:31:36 +0900 Subject: [PATCH] --- yaml --- r: 198519 b: refs/heads/master c: 1f1f584c9a1dd234041573d2d1c42620b3966607 h: refs/heads/master i: 198517: b533e93ad8d30255a9d2b3122376e56807f8afed 198515: 7cd79975373f2bcc0667f460727e0f6d2f0e5738 198511: 42815a1dafffdadd5e0fd446999c3d2ea5a2910c v: v3 --- [refs] | 2 +- trunk/arch/arm/plat-samsung/adc.c | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 709e3a9f81a8..fd07dc7b3573 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6a399547242df3b12f13d637a95f63eaa82f9385 +refs/heads/master: 1f1f584c9a1dd234041573d2d1c42620b3966607 diff --git a/trunk/arch/arm/plat-samsung/adc.c b/trunk/arch/arm/plat-samsung/adc.c index 210030d5cfe1..04d9521ddc9f 100644 --- a/trunk/arch/arm/plat-samsung/adc.c +++ b/trunk/arch/arm/plat-samsung/adc.c @@ -66,6 +66,7 @@ struct adc_device { struct s3c_adc_client *cur; struct s3c_adc_client *ts_pend; void __iomem *regs; + spinlock_t lock; unsigned int prescale; @@ -74,7 +75,7 @@ struct adc_device { static struct adc_device *adc_dev; -static LIST_HEAD(adc_pending); +static LIST_HEAD(adc_pending); /* protected by adc_device.lock */ #define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg) @@ -145,7 +146,7 @@ int s3c_adc_start(struct s3c_adc_client *client, if (client->is_ts && adc->ts_pend) return -EAGAIN; - local_irq_save(flags); + spin_lock_irqsave(&adc->lock, flags); client->channel = channel; client->nr_samples = nr_samples; @@ -157,7 +158,8 @@ int s3c_adc_start(struct s3c_adc_client *client, if (!adc->cur) s3c_adc_try(adc); - local_irq_restore(flags); + + spin_unlock_irqrestore(&adc->lock, flags); return 0; } @@ -237,6 +239,10 @@ EXPORT_SYMBOL_GPL(s3c_adc_register); void s3c_adc_release(struct s3c_adc_client *client) { + unsigned long flags; + + spin_lock_irqsave(&adc_dev->lock, flags); + /* We should really check that nothing is in progress. */ if (adc_dev->cur == client) adc_dev->cur = NULL; @@ -255,6 +261,8 @@ void s3c_adc_release(struct s3c_adc_client *client) if (adc_dev->cur == NULL) s3c_adc_try(adc_dev); + + spin_unlock_irqrestore(&adc_dev->lock, flags); kfree(client); } EXPORT_SYMBOL_GPL(s3c_adc_release); @@ -264,7 +272,6 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) struct adc_device *adc = pw; struct s3c_adc_client *client = adc->cur; enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data; - unsigned long flags; unsigned data0, data1; if (!client) { @@ -296,12 +303,12 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) client->select_cb(client, 1); s3c_adc_convert(adc); } else { - local_irq_save(flags); + spin_lock(&adc->lock); (client->select_cb)(client, 0); adc->cur = NULL; s3c_adc_try(adc); - local_irq_restore(flags); + spin_unlock(&adc->lock); } exit: @@ -326,6 +333,8 @@ static int s3c_adc_probe(struct platform_device *pdev) return -ENOMEM; } + spin_lock_init(&adc->lock); + adc->pdev = pdev; adc->prescale = S3C2410_ADCCON_PRSCVL(49); @@ -407,13 +416,17 @@ static int __devexit s3c_adc_remove(struct platform_device *pdev) static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) { struct adc_device *adc = platform_get_drvdata(pdev); + unsigned long flags; u32 con; + spin_lock_irqsave(&adc->lock, flags); + con = readl(adc->regs + S3C2410_ADCCON); con |= S3C2410_ADCCON_STDBM; writel(con, adc->regs + S3C2410_ADCCON); disable_irq(adc->irq); + spin_unlock_irqrestore(&adc->lock, flags); clk_disable(adc->clk); return 0; @@ -422,6 +435,7 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) static int s3c_adc_resume(struct platform_device *pdev) { struct adc_device *adc = platform_get_drvdata(pdev); + unsigned long flags; clk_enable(adc->clk); enable_irq(adc->irq);