*/
static void ap_tasklet_fn(unsigned long);
static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0);
-static atomic_t ap_poll_requests = ATOMIC_INIT(0);
static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
static struct task_struct *ap_poll_kthread = NULL;
static DEFINE_MUTEX(ap_poll_thread_mutex);
ap_dev->reply->message, ap_dev->reply->length);
switch (status.response_code) {
case AP_RESPONSE_NORMAL:
- atomic_dec(&ap_poll_requests);
ap_dev->queue_count--;
if (ap_dev->queue_count > 0)
mod_timer(&ap_dev->timeout,
if (!status.queue_empty || ap_dev->queue_count <= 0)
break;
/* The card shouldn't forget requests but who knows. */
- atomic_sub(ap_dev->queue_count, &ap_poll_requests);
ap_dev->queue_count = 0;
list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
ap_dev->requestq_count += ap_dev->pendingq_count;
ap_msg->message, ap_msg->length, ap_msg->special);
switch (status.response_code) {
case AP_RESPONSE_NORMAL:
- atomic_inc(&ap_poll_requests);
ap_dev->queue_count++;
if (ap_dev->queue_count == 1)
mod_timer(&ap_dev->timeout,
ap_sm_wait(wait);
}
+static int ap_pending_requests(void)
+{
+ struct ap_device *ap_dev;
+ int id, pending = 0;
+
+ for (id = 0; pending == 0 && id < AP_DEVICES; id++) {
+ spin_lock_bh(&ap_device_list_lock);
+ list_for_each_entry(ap_dev, &ap_device_list, list) {
+ spin_lock_bh(&ap_dev->lock);
+ if (ap_dev->queue_count)
+ pending = 1;
+ spin_unlock_bh(&ap_dev->lock);
+ if (pending)
+ break;
+ }
+ spin_unlock_bh(&ap_device_list_lock);
+ }
+
+ return pending;
+}
+
/**
* ap_poll_thread(): Thread that polls for finished requests.
* @data: Unused pointer
while (!kthread_should_stop()) {
add_wait_queue(&ap_poll_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- if (ap_suspend_flag ||
- atomic_read(&ap_poll_requests) <= 0) {
+ if (ap_suspend_flag || !ap_pending_requests()) {
schedule();
try_to_freeze();
}
continue;
}
ap_tasklet_fn(0);
- } while (!kthread_should_stop());
+ }
+
return 0;
}
spin_unlock_bh(&ap_device_list_lock);
if (ap_drv->remove)
ap_drv->remove(ap_dev);
- spin_lock_bh(&ap_dev->lock);
- atomic_sub(ap_dev->queue_count, &ap_poll_requests);
- spin_unlock_bh(&ap_dev->lock);
return 0;
}