162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/kthread.h> 362306a36Sopenharmony_ci#include <linux/wait.h> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include "spk_types.h" 662306a36Sopenharmony_ci#include "speakup.h" 762306a36Sopenharmony_ci#include "spk_priv.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciDECLARE_WAIT_QUEUE_HEAD(speakup_event); 1062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(speakup_event); 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ciint speakup_thread(void *data) 1362306a36Sopenharmony_ci{ 1462306a36Sopenharmony_ci unsigned long flags; 1562306a36Sopenharmony_ci int should_break; 1662306a36Sopenharmony_ci struct bleep our_sound; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci our_sound.active = 0; 1962306a36Sopenharmony_ci our_sound.freq = 0; 2062306a36Sopenharmony_ci our_sound.jiffies = 0; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci mutex_lock(&spk_mutex); 2362306a36Sopenharmony_ci while (1) { 2462306a36Sopenharmony_ci DEFINE_WAIT(wait); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci while (1) { 2762306a36Sopenharmony_ci spin_lock_irqsave(&speakup_info.spinlock, flags); 2862306a36Sopenharmony_ci our_sound = spk_unprocessed_sound; 2962306a36Sopenharmony_ci spk_unprocessed_sound.active = 0; 3062306a36Sopenharmony_ci prepare_to_wait(&speakup_event, &wait, 3162306a36Sopenharmony_ci TASK_INTERRUPTIBLE); 3262306a36Sopenharmony_ci should_break = kthread_should_stop() || 3362306a36Sopenharmony_ci our_sound.active || 3462306a36Sopenharmony_ci (synth && synth->catch_up && synth->alive && 3562306a36Sopenharmony_ci (speakup_info.flushing || 3662306a36Sopenharmony_ci !synth_buffer_empty())); 3762306a36Sopenharmony_ci spin_unlock_irqrestore(&speakup_info.spinlock, flags); 3862306a36Sopenharmony_ci if (should_break) 3962306a36Sopenharmony_ci break; 4062306a36Sopenharmony_ci mutex_unlock(&spk_mutex); 4162306a36Sopenharmony_ci schedule(); 4262306a36Sopenharmony_ci mutex_lock(&spk_mutex); 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci finish_wait(&speakup_event, &wait); 4562306a36Sopenharmony_ci if (kthread_should_stop()) 4662306a36Sopenharmony_ci break; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (our_sound.active) 4962306a36Sopenharmony_ci kd_mksound(our_sound.freq, our_sound.jiffies); 5062306a36Sopenharmony_ci if (synth && synth->catch_up && synth->alive) { 5162306a36Sopenharmony_ci /* 5262306a36Sopenharmony_ci * It is up to the callee to take the lock, so that it 5362306a36Sopenharmony_ci * can sleep whenever it likes 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci synth->catch_up(synth); 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci speakup_start_ttys(); 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci mutex_unlock(&spk_mutex); 6162306a36Sopenharmony_ci return 0; 6262306a36Sopenharmony_ci} 63