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