]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/workqueue.c
OMAP: dmtimer: enable all timers to be wakeup events
[linux-2.6-omap-h63xx.git] / kernel / workqueue.c
index 2f445833ae371a58d35c56907e2eeb638e75a453..9aedd9fd825b7c332a4a2f53124b57040b013acd 100644 (file)
@@ -416,7 +416,7 @@ void flush_workqueue(struct workqueue_struct *wq)
        might_sleep();
        lock_map_acquire(&wq->lockdep_map);
        lock_map_release(&wq->lockdep_map);
-       for_each_cpu_mask_nr(cpu, *cpu_map)
+       for_each_cpu(cpu, cpu_map)
                flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
 }
 EXPORT_SYMBOL_GPL(flush_workqueue);
@@ -547,7 +547,7 @@ static void wait_on_work(struct work_struct *work)
        wq = cwq->wq;
        cpu_map = wq_cpu_map(wq);
 
-       for_each_cpu_mask_nr(cpu, *cpu_map)
+       for_each_cpu(cpu, cpu_map)
                wait_on_cpu_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
 }
 
@@ -911,7 +911,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
        list_del(&wq->list);
        spin_unlock(&workqueue_lock);
 
-       for_each_cpu_mask_nr(cpu, *cpu_map)
+       for_each_cpu(cpu, cpu_map)
                cleanup_workqueue_thread(per_cpu_ptr(wq->cpu_wq, cpu));
        cpu_maps_update_done();
 
@@ -971,6 +971,8 @@ undo:
 }
 
 #ifdef CONFIG_SMP
+static struct workqueue_struct *work_on_cpu_wq __read_mostly;
+
 struct work_for_cpu {
        struct work_struct work;
        long (*fn)(void *);
@@ -991,8 +993,8 @@ static void do_work_for_cpu(struct work_struct *w)
  * @fn: the function to run
  * @arg: the function arg
  *
- * This will return -EINVAL in the cpu is not online, or the return value
- * of @fn otherwise.
+ * This will return the value @fn returns.
+ * It is up to the caller to ensure that the cpu doesn't go offline.
  */
 long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
 {
@@ -1001,14 +1003,8 @@ long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
        INIT_WORK(&wfc.work, do_work_for_cpu);
        wfc.fn = fn;
        wfc.arg = arg;
-       get_online_cpus();
-       if (unlikely(!cpu_online(cpu)))
-               wfc.ret = -EINVAL;
-       else {
-               schedule_work_on(cpu, &wfc.work);
-               flush_work(&wfc.work);
-       }
-       put_online_cpus();
+       queue_work_on(cpu, work_on_cpu_wq, &wfc.work);
+       flush_work(&wfc.work);
 
        return wfc.ret;
 }
@@ -1025,4 +1021,8 @@ void __init init_workqueues(void)
        hotcpu_notifier(workqueue_cpu_callback, 0);
        keventd_wq = create_workqueue("events");
        BUG_ON(!keventd_wq);
+#ifdef CONFIG_SMP
+       work_on_cpu_wq = create_workqueue("work_on_cpu");
+       BUG_ON(!work_on_cpu_wq);
+#endif
 }