From nobody Sun Feb 8 19:35:32 2026 Received: from smtp72.ord1d.emailsrvr.com (smtp72.ord1d.emailsrvr.com [184.106.54.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B6D6F365A0E for ; Mon, 12 Jan 2026 16:36:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=184.106.54.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768235804; cv=none; b=VNB85PaykKLHxL6HAuV7FyZSOia3klC/Zbw/POAKHKALL7HVJgSalFSqPonj1bkv1eYhhfw5mOT8pLDs+asW4AmpqHBAAHpg8sWGUeZIlHmoAhK+u+Ix0YkoDISdNnAK29uDfoTsa40UOlHNYGSygWUGAUHz+7ihbeE9hnuitsY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768235804; c=relaxed/simple; bh=O7N2yi2NOcxWR5uM9x5rdMSt+C543cwaLFgfHUOtuzY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=dg/PQLIvjs0zPLCmcM/i2VcYLaKpOpPNKzXymYx7b0524VmGeJSxln96PQ0P0INQidStCnXWZlBfo91SfsyRwpBh23clVzKDkj/Os0ODYQXQ9Nwpuqh0EkSaHssA0GEGiiTsCrXX2gBRpnLJW4h7Uu8bXFBJURb6Jp0BUqifADs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mev.co.uk; spf=pass smtp.mailfrom=mev.co.uk; dkim=pass (1024-bit key) header.d=mev.co.uk header.i=@mev.co.uk header.b=pQD7HN6w; arc=none smtp.client-ip=184.106.54.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mev.co.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mev.co.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mev.co.uk header.i=@mev.co.uk header.b="pQD7HN6w" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mev.co.uk; s=20221208-6x11dpa4; t=1768235329; bh=O7N2yi2NOcxWR5uM9x5rdMSt+C543cwaLFgfHUOtuzY=; h=From:To:Subject:Date:From; b=pQD7HN6wILaMTR0uPd9VlJXkHk1nMBlrNCv3FOpx/2oapPfEBpTmFZkLhXLWqI2Np o3DhGJD8JRlvsp7/ASBOFT8Qc+ZFRBabO/ColR9XBy0ap6fv4A0wvfCbPOOI8k9laL beAEDFCc+tmQJDYjs0qk7TFQipyJxCRw5un/WB0A= X-Auth-ID: abbotti@mev.co.uk Received: by smtp10.relay.ord1d.emailsrvr.com (Authenticated sender: abbotti-AT-mev.co.uk) with ESMTPSA id EDB81A02BC; Mon, 12 Jan 2026 11:28:48 -0500 (EST) From: Ian Abbott To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , Ian Abbott , H Hartley Sweeten , stable@vger.kernel.org Subject: [PATCH] comedi: dmm32at: serialize use of paged registers Date: Mon, 12 Jan 2026 16:28:35 +0000 Message-ID: <20260112162835.91688-1-abbotti@mev.co.uk> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Classification-ID: 811417ab-859f-4141-8b86-775e1b337f7e-1-1 Content-Type: text/plain; charset="utf-8" Some of the hardware registers of the DMM-32-AT board are multiplexed, using the least significant two bits of the Miscellaneous Control register to select the function of registers at offsets 12 to 15: 00 =3D> 8254 timer/counter registers are accessible 01 =3D> 8255 digital I/O registers are accessible 10 =3D> Reserved 11 =3D> Calibration registers are accessible The interrupt service routine (`dmm32at_isr()`) clobbers the bottom two bits of the register with value 00, which would interfere with access to the 8255 registers by the `dm32at_8255_io()` function (used for Comedi instruction handling on the digital I/O subdevice). Make use of the generic Comedi device spin-lock `dev->spinlock` (which is otherwise unused by this driver) to serialize access to the miscellaneous control register and paged registers. Fixes: 3c501880ac44 ("Staging: comedi: add dmm32at driver") Cc: Signed-off-by: Ian Abbott --- drivers/comedi/drivers/dmm32at.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/comedi/drivers/dmm32at.c b/drivers/comedi/drivers/dmm3= 2at.c index 644e3b643c79..910cd24b1bed 100644 --- a/drivers/comedi/drivers/dmm32at.c +++ b/drivers/comedi/drivers/dmm32at.c @@ -330,6 +330,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, =20 static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nan= sec) { + unsigned long irq_flags; unsigned char lo1, lo2, hi2; unsigned short both2; =20 @@ -342,6 +343,9 @@ static void dmm32at_setaitimer(struct comedi_device *de= v, unsigned int nansec) /* set counter clocks to 10MHz, disable all aux dio */ outb(0, dev->iobase + DMM32AT_CTRDIO_CFG_REG); =20 + /* serialize access to control register and paged registers */ + spin_lock_irqsave(&dev->spinlock, irq_flags); + /* get access to the clock regs */ outb(DMM32AT_CTRL_PAGE_8254, dev->iobase + DMM32AT_CTRL_REG); =20 @@ -354,6 +358,8 @@ static void dmm32at_setaitimer(struct comedi_device *de= v, unsigned int nansec) outb(lo2, dev->iobase + DMM32AT_CLK2); outb(hi2, dev->iobase + DMM32AT_CLK2); =20 + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + /* enable the ai conversion interrupt and the clock to start scans */ outb(DMM32AT_INTCLK_ADINT | DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL, @@ -363,13 +369,19 @@ static void dmm32at_setaitimer(struct comedi_device *= dev, unsigned int nansec) static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevi= ce *s) { struct comedi_cmd *cmd =3D &s->async->cmd; + unsigned long irq_flags; int ret; =20 dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len); =20 + /* serialize access to control register and paged registers */ + spin_lock_irqsave(&dev->spinlock, irq_flags); + /* reset the interrupt just in case */ outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); =20 + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + /* * wait for circuit to settle * we don't have the 'insn' here but it's not needed @@ -429,8 +441,13 @@ static irqreturn_t dmm32at_isr(int irq, void *d) comedi_handle_events(dev, s); } =20 + /* serialize access to control register and paged registers */ + spin_lock(&dev->spinlock); + /* reset the interrupt */ outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); + + spin_unlock(&dev->spinlock); return IRQ_HANDLED; } =20 @@ -481,14 +498,25 @@ static int dmm32at_ao_insn_write(struct comedi_device= *dev, static int dmm32at_8255_io(struct comedi_device *dev, int dir, int port, int data, unsigned long regbase) { + unsigned long irq_flags; + int ret; + + /* serialize access to control register and paged registers */ + spin_lock_irqsave(&dev->spinlock, irq_flags); + /* get access to the DIO regs */ outb(DMM32AT_CTRL_PAGE_8255, dev->iobase + DMM32AT_CTRL_REG); =20 if (dir) { outb(data, dev->iobase + regbase + port); - return 0; + ret =3D 0; + } else { + ret =3D inb(dev->iobase + regbase + port); } - return inb(dev->iobase + regbase + port); + + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + + return ret; } =20 /* Make sure the board is there and put it to a known state */ --=20 2.51.0