From nobody Tue Apr 7 18:51:41 2026 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 487012264A8 for ; Fri, 27 Feb 2026 10:16:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772187414; cv=none; b=jRNAB8M6+1hDG9/i3dcy/8Db5Np2KwW3+64amldIW5De5KR2YtAP/K6WsN8sPUujVUfRZgYXt9ZwSv7MFIrtY+jbCUAjajh1G3gRSo++wlwp8ezYMBvZSe6eKsvfR4hhdUlHOxzVefgC0/+TWkGFLFrNaE/pulMB4ytNUdX2DYY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772187414; c=relaxed/simple; bh=DgTC8IVFKOsCitk+Wsq6tCWCZGgu8Aot8CLNSdfr03o=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=bEQC/Bu3BkNpAGdkMV00Oouq9BP8nmS3oUU2IsJX9h8W2UT9zgwfRqnsf41ZUM3df78GdAMl5SaAcWNECtS0e4LW4/L54VUyZe3HYEn3X3deMykGf8P0IOImJJgv8FTcJuxbaounGk7OAZ5J6s5VOaMAhWQfQSJ0l0OuDE4Zc9k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=thingy.jp; spf=pass smtp.mailfrom=0x0f.com; dkim=pass (1024-bit key) header.d=thingy.jp header.i=@thingy.jp header.b=HKrHnVJc; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=thingy.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=0x0f.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=thingy.jp header.i=@thingy.jp header.b="HKrHnVJc" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-2ade1806c28so11383825ad.1 for ; Fri, 27 Feb 2026 02:16:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thingy.jp; s=google; t=1772187411; x=1772792211; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=QfJg30mJUVGYxijzk+lCAk658Lta6KCJk/Tcavup9u0=; b=HKrHnVJcumaL0rxNLRGyrAWt7TffkGxV/aQ7Y25iH2mK3xwBUXb5mTKqqG422XcsRC JwLr8x0tBRV8KanDJBBmP+MX8GekBRtO2XCiqwxhxaGC1DCeDvloeSbjceKMVZHbMpuU vOO73wa4nd0I49iOnxc7rvRDYYenmPe1VGTUc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772187411; x=1772792211; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=QfJg30mJUVGYxijzk+lCAk658Lta6KCJk/Tcavup9u0=; b=TYgPnlM0yJVTSyqc/tCIJvdPzUcK6BfFwSJmEA8TUaDDro6AL08FPj/3k60kDpUwUZ JzU4Jqd3Yg7V1ZtsWt2j+rFE3E69Es2gpopJSSS4rQbwE3Yi8AuG1/EvE47QS+RAByXB erNrSELDY01ys74igpjvAkpp+laplrd1ZZHdmEKHTY8SJ1KfBjuvu4bECAjFuUaZbqMs XEUxwUGCpdhl/uIo8VAvFUJQMogtiN353x7WJwSWNN4CMjxvYaUEfToqBFNYMnv6hgNQ DE65yHoYSfxr8dzAVan+Xfp8oIMYZwz2WxxZLLSr3vRQsy/wJaN5XqzfJEYyplk/WydC w4yA== X-Forwarded-Encrypted: i=1; AJvYcCUnnJKppusu6wKAUKPYUm3qszAf+0YWEDLrpMdsF5BBU1qKBltCiNv0+pRjEWA3eLT0n0JGSGFyjnvErQU=@vger.kernel.org X-Gm-Message-State: AOJu0YwPt6DogPtaUiH57RINIvr06K1+UzvSLIGc14SsHLtYUcQtWeyO nCh5EYo4aYClLti9pXkRTb9t3qpgBzu8aRLjOWV4k8zOsPbD82pof60L0aB6PtDSxCo= X-Gm-Gg: ATEYQzwpQNYFAmYuwSmobcmfPeCpEb7vh5xYNgrAJSYSW0h9qgtDV/4GSdqpyM6BxYV 2uRy7sELP+oLEOhwxgSkTCLAWIRtAV64YWOLAImwAIhbjoBl7Pe7Me1inr6CknfwP0dy7+AOGlv I6PSAHf8PJ2e3kJSmMNfS9R8IRaA4aPB7YI/koPYrqny1WMaZx5i+r+Gnn+psblE/dlxctDeRYM vd+nmXQpFnmrHLgtU5WPeC3PYLJRSoGUJQnOsrhiP/anfBHePfdZ41vJbWnVQrWi77P8U8eQqM5 Fd9/qda2yt3pfPh1i5wBtv4B4LxR+4Acx2WZg/3PX7WUCNqa8dzYL8k7UrCTiup0lApfjygO3mR Fg2EflXSMbtuNQuAkrmbgEnvVDa1jnLdZyN2d9UJi3AjMBPLNfrAWcojA8a7Wl1SPnMXo/aLUgY GfERcExka4nul84Ew5b5CcoDj8xfgEc5e9/ogAIsEVtI2Ex+Hu6bzbgFYwiZDoqBGHOTUKZ7ML8 1iZZ+OY4k7JifI= X-Received: by 2002:a17:903:3c23:b0:2a3:e7fe:646e with SMTP id d9443c01a7336-2ae2e3ebfa2mr25339525ad.5.1772187411508; Fri, 27 Feb 2026 02:16:51 -0800 (PST) Received: from kinako.work.home.arpa (p1590226-ipxg00c01sizuokaden.shizuoka.ocn.ne.jp. [153.227.10.226]) by smtp.googlemail.com with ESMTPSA id d9443c01a7336-2adfb5b1035sm74531775ad.7.2026.02.27.02.16.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Feb 2026 02:16:51 -0800 (PST) From: Daniel Palmer To: sudipm.mukherjee@gmail.com, joerg@dorchain.net Cc: geert@linux-m68k.org, linux-m68k@lists.linux-m68k.org, linux-kernel@vger.kernel.org, Daniel Palmer Subject: [PATCH v2] parport: mfc3: Convert to a modern zorro driver Date: Fri, 27 Feb 2026 19:16:43 +0900 Message-ID: <20260227101643.473010-1-daniel@thingy.jp> 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 Content-Type: text/plain; charset="utf-8" Currently this driver causes my Amiga 4000 to crash if it is not a module because it tries to iterate over the zorro devices before that has been setup. Convert the driver over to the modern zorro driver API so it probes like the other zorro drivers and doesn't crash my machine. Claude was able to do the manual work of moving the original code but I had to fix up some mistakes, clean up the allocations to use devm versions and so on. Only build, boot, and "checked the driver is registered correctly" tested as I don't have the card and it seems to be one of the few things winuae doesn't emulate. Using claude to fix it up seemed better than just deleting it considering all of the effort Joerg put in to documenting the hardware etc. Assisted-by: Claude:claude-4.6-sonnet Signed-off-by: Daniel Palmer Reviewed-by: Geert Uytterhoeven --- v2: Clean up how the interrupt works a bit and return IRQ_NONE when the interrupt wasn't for the card as suggested by Geert. I guess this should work but without a way to test it this is best effort. drivers/parport/parport_mfc3.c | 152 ++++++++++++++++----------------- 1 file changed, 72 insertions(+), 80 deletions(-) diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c index bb1817218d7b..21210cb2d8d2 100644 --- a/drivers/parport/parport_mfc3.c +++ b/drivers/parport/parport_mfc3.c @@ -66,12 +66,8 @@ #include #include =20 -/* Maximum Number of Cards supported */ -#define MAX_MFC 5 - #undef DEBUG =20 -static struct parport *this_port[MAX_MFC] =3D {NULL, }; static volatile int dummy; /* for trigger readds */ =20 #define pia(dev) ((struct pia *)(dev->base)) @@ -169,19 +165,17 @@ static unsigned char mfc3_read_status(struct parport = *p) return status; } =20 -static int use_cnt; - static irqreturn_t mfc3_interrupt(int irq, void *dev_id) { - int i; - - for( i =3D 0; i < MAX_MFC; i++) - if (this_port[i] !=3D NULL) - if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */ - dummy =3D pia(this_port[i])->pprb; /* clear irq bit */ - parport_generic_irq(this_port[i]); - } - return IRQ_HANDLED; + struct parport *p =3D dev_id; + + if (pia(p)->crb & 128) { /* Board caused interrupt */ + dummy =3D pia(p)->pprb; /* clear irq bit */ + parport_generic_irq(p); + return IRQ_HANDLED; + } + + return IRQ_NONE; } =20 static void mfc3_enable_irq(struct parport *p) @@ -280,85 +274,83 @@ static struct parport_operations pp_mfc3_ops =3D { =20 /* ----------- Initialisation code --------------------------------- */ =20 -static int __init parport_mfc3_init(void) +static int mfc3_probe(struct zorro_dev *z, const struct zorro_device_id *e= nt) { + unsigned long piabase =3D z->resource.start + PIABASE; + struct device *dev =3D &z->dev; struct parport *p; - int pias =3D 0; struct pia *pp; - struct zorro_dev *z =3D NULL; =20 - if (!MACH_IS_AMIGA) + if (!devm_request_mem_region(dev, piabase, sizeof(struct pia), "PIA")) + return -EBUSY; + + pp =3D ZTWO_VADDR(piabase); + pp->crb =3D 0; + pp->pddrb =3D 255; /* all data pins output */ + pp->crb =3D PIA_DDR | 32 | 8; + dummy =3D pp->pddrb; /* reading clears interrupt */ + pp->cra =3D 0; + pp->pddra =3D 0xe0; /* /RESET, /DIR, /AUTO-FEED output */ + pp->cra =3D PIA_DDR; + pp->ppra =3D 0; /* reset printer */ + udelay(10); + pp->ppra =3D 128; + + p =3D parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS, + PARPORT_DMA_NONE, &pp_mfc3_ops); + if (!p) return -ENODEV; =20 - while ((z =3D zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) { - unsigned long piabase =3D z->resource.start+PIABASE; - if (!request_mem_region(piabase, sizeof(struct pia), "PIA")) - continue; - - pp =3D ZTWO_VADDR(piabase); - pp->crb =3D 0; - pp->pddrb =3D 255; /* all data pins output */ - pp->crb =3D PIA_DDR|32|8; - dummy =3D pp->pddrb; /* reading clears interrupt */ - pp->cra =3D 0; - pp->pddra =3D 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */ - pp->cra =3D PIA_DDR; - pp->ppra =3D 0; /* reset printer */ - udelay(10); - pp->ppra =3D 128; - p =3D parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS, - PARPORT_DMA_NONE, &pp_mfc3_ops); - if (!p) - goto out_port; - - if (p->irq !=3D PARPORT_IRQ_NONE) { - if (use_cnt++ =3D=3D 0) - if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name,= &pp_mfc3_ops)) - goto out_irq; - } - p->dev =3D &z->dev; - - this_port[pias++] =3D p; - pr_info("%s: Multiface III port using irq\n", p->name); - /* XXX: set operating mode */ - - p->private_data =3D (void *)piabase; - parport_announce_port (p); - - if (pias >=3D MAX_MFC) - break; - continue; - - out_irq: - parport_put_port(p); - out_port: - release_mem_region(piabase, sizeof(struct pia)); + if (p->irq !=3D PARPORT_IRQ_NONE) { + if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, + IRQF_SHARED, p->name, p)) + goto err_put_port; } =20 - return pias ? 0 : -ENODEV; + p->dev =3D dev; + p->private_data =3D (void *)piabase; + + zorro_set_drvdata(z, p); + + pr_info("%s: Multiface III port using irq\n", p->name); + /* XXX: set operating mode */ + parport_announce_port(p); + + return 0; + +err_put_port: + parport_put_port(p); + + return -ENODEV; } =20 -static void __exit parport_mfc3_exit(void) +static void mfc3_remove(struct zorro_dev *z) { - int i; - - for (i =3D 0; i < MAX_MFC; i++) { - if (!this_port[i]) - continue; - parport_remove_port(this_port[i]); - if (this_port[i]->irq !=3D PARPORT_IRQ_NONE) { - if (--use_cnt =3D=3D 0)=20 - free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops); - } - release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct= pia)); - parport_put_port(this_port[i]); - } + struct parport *p =3D zorro_get_drvdata(z); + + parport_remove_port(p); + + if (p->irq !=3D PARPORT_IRQ_NONE) + free_irq(IRQ_AMIGA_PORTS, p); + + parport_put_port(p); } =20 +static const struct zorro_device_id mfc3_zorro_tbl[] =3D { + { ZORRO_PROD_BSC_MULTIFACE_III }, + { 0 } +}; +MODULE_DEVICE_TABLE(zorro, mfc3_zorro_tbl); + +static struct zorro_driver mfc3_driver =3D { + .name =3D "parport_mfc3", + .id_table =3D mfc3_zorro_tbl, + .probe =3D mfc3_probe, + .remove =3D mfc3_remove, +}; + +module_driver(mfc3_driver, zorro_register_driver, zorro_unregister_driver); =20 MODULE_AUTHOR("Joerg Dorchain "); MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralle= l Port"); MODULE_LICENSE("GPL"); - -module_init(parport_mfc3_init) -module_exit(parport_mfc3_exit) --=20 2.51.0