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