1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/kthread.h> 3 #include <linux/wait.h> 4 5 #include "spk_types.h" 6 #include "speakup.h" 7 #include "spk_priv.h" 8 9 DECLARE_WAIT_QUEUE_HEAD(speakup_event); 10 EXPORT_SYMBOL_GPL(speakup_event); 11 12 int speakup_thread(void *data) 13 { 14 unsigned long flags; 15 int should_break; 16 struct bleep our_sound; 17 18 our_sound.active = 0; 19 our_sound.freq = 0; 20 our_sound.jiffies = 0; 21 22 mutex_lock(&spk_mutex); 23 while (1) { 24 DEFINE_WAIT(wait); 25 26 while (1) { 27 spin_lock_irqsave(&speakup_info.spinlock, flags); 28 our_sound = spk_unprocessed_sound; 29 spk_unprocessed_sound.active = 0; 30 prepare_to_wait(&speakup_event, &wait, 31 TASK_INTERRUPTIBLE); 32 should_break = kthread_should_stop() || 33 our_sound.active || 34 (synth && synth->catch_up && synth->alive && 35 (speakup_info.flushing || 36 !synth_buffer_empty())); 37 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 38 if (should_break) 39 break; 40 mutex_unlock(&spk_mutex); 41 schedule(); 42 mutex_lock(&spk_mutex); 43 } 44 finish_wait(&speakup_event, &wait); 45 if (kthread_should_stop()) 46 break; 47 48 if (our_sound.active) 49 kd_mksound(our_sound.freq, our_sound.jiffies); 50 if (synth && synth->catch_up && synth->alive) { 51 /* 52 * It is up to the callee to take the lock, so that it 53 * can sleep whenever it likes 54 */ 55 synth->catch_up(synth); 56 } 57 58 speakup_start_ttys(); 59 } 60 mutex_unlock(&spk_mutex); 61 return 0; 62 } 63