update adc driver: interrupt add spin_lock
authorkfx <kfx@rock-chips.com>
Mon, 20 Jun 2011 02:06:28 +0000 (10:06 +0800)
committerkfx <kfx@rock-chips.com>
Mon, 20 Jun 2011 02:06:28 +0000 (10:06 +0800)
drivers/adc/core.c
drivers/adc/plat/rk29_adc.c
include/linux/adc.h

index dea19cc744d9d46ecabf1a2092bb756087cdc3eb..0756c7ea4f80eb76070076104dc395d146e24854 100755 (executable)
@@ -91,14 +91,14 @@ static int
 adc_enqueue_request(struct adc_host *adc, struct adc_request *req)
 {
        int head, tail;
-
-       mutex_lock(&adc->queue_mutex);
-
+       unsigned long flags;
+       
+       spin_lock_irqsave(&adc->lock, flags);
        head = adc->queue_head;
        tail = adc->queue_tail;
 
        if (adc->queue[tail]) {
-               mutex_unlock(&adc->queue_mutex);
+               spin_unlock_irqrestore(&adc->lock,flags);
                dev_err(adc->dev, "ADC queue is full, dropping request\n");
                return -EBUSY;
        }
@@ -108,7 +108,7 @@ adc_enqueue_request(struct adc_host *adc, struct adc_request *req)
                trigger_next_adc_job_if_any(adc);
        adc->queue_tail = (tail + 1) & (MAX_ADC_FIFO_DEPTH - 1);
 
-       mutex_unlock(&adc->queue_mutex);
+       spin_unlock_irqrestore(&adc->lock,flags);
 
        return 0;
 }
@@ -169,6 +169,7 @@ EXPORT_SYMBOL(adc_sync_read);
 
 int adc_async_read(struct adc_client *client)
 {
+       int ret = 0;
        struct adc_request *req = NULL;
        
        if(client == NULL) {
@@ -190,7 +191,11 @@ int adc_async_read(struct adc_client *client)
        req->client = client;
        req->status = ASYNC_READ;
 
-       return adc_enqueue_request(client->adc, req);
+       ret = adc_enqueue_request(client->adc, req);
+       if(ret < 0)
+               kfree(req);
+
+       return ret;
 }
 EXPORT_SYMBOL(adc_async_read);
 
@@ -198,11 +203,12 @@ void adc_core_irq_handle(struct adc_host *adc)
 {
        struct adc_request *req;
        int head, res;
-
+       spin_lock(adc->lock);
        head = adc->queue_head;
 
        req = adc->queue[head];
        if (WARN_ON(!req)) {
+               spin_unlock(&adc->lock);
                dev_err(adc->dev, "adc irq: ADC queue empty!\n");
                return;
        }
@@ -218,6 +224,7 @@ void adc_core_irq_handle(struct adc_host *adc)
                kfree(req);
                req = NULL;
        }
+       spin_unlock(&adc->lock);
 }
 EXPORT_SYMBOL(adc_core_irq_handle);
 
index 6bf01ba8c56f0df4d31b46cd0519fae83ee01058..2471abafff0b46fd7c16acb9f64fdb9e25b7492d 100755 (executable)
@@ -123,7 +123,7 @@ static int rk29_adc_probe(struct platform_device *pdev)
        adc = adc_alloc_host(sizeof(struct rk29_adc_device), &pdev->dev);\r
        if (!adc)\r
                return -ENOMEM;\r
-       mutex_init(&adc->queue_mutex);\r
+       spin_lock_init(&adc->lock);\r
        adc->dev = &pdev->dev;\r
        adc->is_suspended = 0;\r
        adc->ops = &rk29_adc_ops;\r
index d9ed72afbe0ffe18a3f9e0a5fa1a90fefc22dbed..22c781fbd3054cf9e6438756e6ca8edf7954d7c2 100755 (executable)
@@ -49,7 +49,7 @@ struct adc_host {
        struct adc_request *queue[MAX_ADC_FIFO_DEPTH];\r
        int queue_head;\r
        int queue_tail;\r
-       struct mutex queue_mutex;\r
+       spinlock_t                      lock;\r
        struct adc_client *cur;\r
        const struct adc_ops *ops;\r
        unsigned long           private[0];\r