From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794064274; b=pPNvtsuIZmp7yXKyJlazY6LC2CgjdvNMvIoXNsIS40kNWYR7sQqt9KxgeqcuLo6NthNn EDkcMXXakoe3wLbaQ5uOrTfZuXG0anLq8fdD0q/rxF5BymGhCO2ffHhbSm29gjYpbHjMg l4gEV040qticLLsH0wAImeQvktY1FmSPLmJ8NChMGIvdRnoPCoBSEz28AMgl2G9g86mFP WfcbTbHqMVlB4nx7Sr/zhQSXhAvIFp2CNbud86E5wly0cQ6Zw0dkYTDsq3g0z7ZZjuy/D nOnnfdzr1K7TrQY9URzJRyJagJ47sxqSjC1SMAFyBpojng3BoJcu13W+cWZ6q7X++hg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794064274; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=Xgg2NnPh9gVHR8+jNs37AK6adFePywHE/OEugF4loRc=; b=kghGV2N95KFHqQv49pYdzyzr6RL4Wkt45MGKl247pcvCaHuHTCb6m8yC0PZax91ihadK dEQtR9uw4JFPOXMQOg/VtJtroONmAQ5GE28Qe4r13iHF/4tYwusjk779NkNnqplPMbyNU e+U4dIcfuz23yMQNjS4kqbHDlEWTm6riBX0m+XMS1lhW/WmSH5KfReftKaZ9CFlFUbwh+ 7ow8bMXPQgaDlLqK66s08fjXSf9q9gqDjyDuSbFb2WanC6OjSrvCm0he8XwuEd7/iJ3hH EdN5pG+NMJjA3vbX0QU3t/ZfPMvN44IBQ2cyOp5AK74aO8N0oGriwIZNbsz997O6FbQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b="Hr4JOdm/"; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 45D0F606A334; Sat, 7 Nov 2026 15:11:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=Hr4JOdm/ Received: by smtp.kernel.org (Postfix) with ESMTPSA id E92341F0089F; Sat, 7 Nov 2026 15:11:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794064274; bh=Xgg2NnPh9gVHR8+jNs37AK6adFePywHE/OEugF4loRc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Hr4JOdm/hZK+6FzZmXT6ne5ofsIIHUoTd/EWLa+yc4M2kXwDuP226lEmjOAOTbZzN pi8S6B4gT57W5UlInldwfzPzJdRg5IBpOPpHF9bdAs3tkQhrBJhlGGaP5xyG0IWWPN WzJ1imv0mdj4mTLOYz1JB0pFI713ALUTOecVE3Xw= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Runyu Xiao , Takashi Iwai , Sasha Levin Subject: [PATCH 7.3 0370/1257] m68k: dmasound: Keep the Q40 IRQ handler registered Date: Sat, 7 Nov 2026 08:44:26 -0500 Message-ID: <20261107134949.780332758@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134939.434104957@linuxfoundation.org> References: <20261107134939.434104957@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Runyu Xiao [ Upstream commit fa2e77ac5bf81a60864e71fc72196227692d7162 ] Q40PlayNextFrame() re-registers the sample IRQ after stopping it. This function can be called with dmasound.lock held and from the sample IRQ handler, so free_irq() and request_irq() can sleep or deadlock. A failed re-registration can also leave playback without an IRQ. Register one handler for the lifetime of the driver and select mono or stereo sample handling inside that handler. Call the frame completion path after releasing dmasound.lock so it can refill the queue safely. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Runyu Xiao Link: https://patch.msgid.link/20260929085400.2068977-1-runyu.xiao@seu.edu.cn Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/oss/dmasound/dmasound_q40.c | 65 ++++++++++++++----------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c index e25a78dd1bf2a..339311e5d8070 100644 --- a/sound/oss/dmasound/dmasound_q40.c +++ b/sound/oss/dmasound/dmasound_q40.c @@ -49,9 +49,8 @@ static int Q40SetFormat(int format); static int Q40SetVolume(int volume); static void Q40PlayNextFrame(int index); static void Q40Play(void); -static irqreturn_t Q40StereoInterrupt(int irq, void *dummy); -static irqreturn_t Q40MonoInterrupt(int irq, void *dummy); -static void Q40Interrupt(void); +static irqreturn_t q40_audio_interrupt(int irq, void *dummy); +static void q40_frame_done(void); /*** Mid level stuff *********************************************************/ @@ -372,8 +371,8 @@ static void Q40Free(void *ptr, unsigned int size) static int __init Q40IrqInit(void) { /* Register interrupt handler. */ - if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, - "DMA sound", Q40Interrupt)) + if (request_irq(Q40_IRQ_SAMPLE, q40_audio_interrupt, 0, + "DMA sound", q40_frame_done)) return 0; return(1); @@ -384,7 +383,7 @@ static int __init Q40IrqInit(void) static void Q40IrqCleanUp(void) { master_outb(0,SAMPLE_ENABLE_REG); - free_irq(Q40_IRQ_SAMPLE, Q40Interrupt); + free_irq(Q40_IRQ_SAMPLE, q40_frame_done); } #endif /* MODULE */ @@ -403,7 +402,6 @@ static void Q40PlayNextFrame(int index) u_char *start; u_long size; u_char speed; - int error; /* used by Q40Play() if all doubts whether there really is something * to be played are already wiped out. @@ -420,15 +418,6 @@ static void Q40PlayNextFrame(int index) speed=(dmasound.hard.speed==10000 ? 0 : 1); master_outb( 0,SAMPLE_ENABLE_REG); - free_irq(Q40_IRQ_SAMPLE, Q40Interrupt); - if (dmasound.soft.stereo) - error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, - "Q40 sound", Q40Interrupt); - else - error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0, - "Q40 sound", Q40Interrupt); - if (error && printk_ratelimit()) - pr_err("Couldn't register sound interrupt\n"); master_outb( speed, SAMPLE_RATE_REG); master_outb( 1,SAMPLE_CLEAR_REG); @@ -456,31 +445,35 @@ static void Q40Play(void) spin_unlock_irqrestore(&dmasound.lock, flags); } -static irqreturn_t Q40StereoInterrupt(int irq, void *dummy) -{ - spin_lock(&dmasound.lock); - if (q40_sc>1){ - *DAC_LEFT=*q40_pp++; - *DAC_RIGHT=*q40_pp++; - q40_sc -=2; - master_outb(1,SAMPLE_CLEAR_REG); - }else Q40Interrupt(); - spin_unlock(&dmasound.lock); - return IRQ_HANDLED; -} -static irqreturn_t Q40MonoInterrupt(int irq, void *dummy) +static irqreturn_t q40_audio_interrupt(int irq, void *dummy) { + bool frame_done = false; + spin_lock(&dmasound.lock); - if (q40_sc>0){ - *DAC_LEFT=*q40_pp; - *DAC_RIGHT=*q40_pp++; - q40_sc --; - master_outb(1,SAMPLE_CLEAR_REG); - }else Q40Interrupt(); + if (dmasound.hard.stereo) { + if (q40_sc > 1) { + *DAC_LEFT = *q40_pp++; + *DAC_RIGHT = *q40_pp++; + q40_sc -= 2; + master_outb(1, SAMPLE_CLEAR_REG); + } else { + frame_done = true; + } + } else if (q40_sc > 0) { + *DAC_LEFT = *q40_pp; + *DAC_RIGHT = *q40_pp++; + q40_sc--; + master_outb(1, SAMPLE_CLEAR_REG); + } else { + frame_done = true; + } spin_unlock(&dmasound.lock); + if (frame_done) + q40_frame_done(); return IRQ_HANDLED; } -static void Q40Interrupt(void) + +static void q40_frame_done(void) { if (!write_sq.active) { /* playing was interrupted and sq_reset() has already cleared -- 2.53.0