[PATCH] ARM: SAMSUNG: Clean up timed-out adc transaction
Huisung Kang
hs1218.kang at samsung.com
Fri Feb 10 21:52:40 EST 2012
From: Sung-Taek Lim <stk.lim at samsung.com>
This patch tries to clean up timed-out adc transaction.
Otherwise, time-out adc transaction remains as adc->cur permanently
and may block other incoming adc transactions.
Signed-off-by: Sung-Taek Lim <stk.lim at samsung.com>
Signed-off-by: KeyYoung Park <keyyoung.park at samsung.com>
Signed-off-by: Huisung Kang <hs1218.kang at samsung.com>
---
arch/arm/plat-samsung/adc.c | 54 +++++++++++++++++++++++-------------------
1 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index e4e965c..fccc644 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -185,6 +185,34 @@ int s3c_adc_start(struct s3c_adc_client *client, } EXPORT_SYMBOL_GPL(s3c_adc_start);
+static void s3c_adc_stop(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;
+ if (adc_dev->ts_pend == client)
+ adc_dev->ts_pend = NULL;
+ else {
+ struct list_head *p, *n;
+ struct s3c_adc_client *tmp;
+
+ list_for_each_safe(p, n, &adc_pending) {
+ tmp = list_entry(p, struct s3c_adc_client, pend);
+ if (tmp == client)
+ list_del(&tmp->pend);
+ }
+ }
+
+ if (adc_dev->cur == NULL)
+ s3c_adc_try(adc_dev);
+
+ spin_unlock_irqrestore(&adc_dev->lock, flags); }
+
static void s3c_convert_done(struct s3c_adc_client *client,
unsigned v, unsigned u, unsigned *left) { @@ -207,6 +235,7 @@ int s3c_adc_read(struct s3c_adc_client
*client, unsigned int ch)
ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
if (client->result < 0) {
+ s3c_adc_stop(client);
ret = -ETIMEDOUT;
goto err;
}
@@ -259,30 +288,7 @@ 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;
- if (adc_dev->ts_pend == client)
- adc_dev->ts_pend = NULL;
- else {
- struct list_head *p, *n;
- struct s3c_adc_client *tmp;
-
- list_for_each_safe(p, n, &adc_pending) {
- tmp = list_entry(p, struct s3c_adc_client, pend);
- if (tmp == client)
- list_del(&tmp->pend);
- }
- }
-
- if (adc_dev->cur == NULL)
- s3c_adc_try(adc_dev);
-
- spin_unlock_irqrestore(&adc_dev->lock, flags);
+ s3c_adc_stop(client);
kfree(client);
}
EXPORT_SYMBOL_GPL(s3c_adc_release);
--
1.7.1
More information about the linux-arm-kernel
mailing list