* [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD
@ 2026-11-11 16:37 Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 1/7] zorro: warp mfd: add the CS-Lab Warp multifunction parent Paolo Pisati
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
The CS-Lab Warp 1260 is an A1200 trapdoor multifunction accelerator: it
contains a 68060, an FPGA, an ARM co-processor and several sub-devices
hanging off them. The 68k drives the IDE interface and the RTG display
controller directly, through the FPGA; the ARM owns most of the rest -
USB, SD card, WiFi, audio, the Kickstart slots, the CPU clock, fan
control and the board telemetry - and the 68k reaches it through a
dual-port RAM mailbox.
pata_cswarp, merged in 7.4-rc1, binds the board's Zorro device for the
IDE window alone. This series puts an mfd parent on the device
instead, hands the IDE window to pata_cswarp as a cell, and uses the
mailbox for a first set of board functions, exposed as sysfs
attributes on the Zorro device:
1-3 the mfd parent, pata_cswarp as its first cell, defconfig
4 the dual-port RAM command channel and the board identity
5-7 voltages and temperatures, fan duty cycle, Kickstart slot
selection
The layout - an mfd parent in drivers/zorro/ handing cells to the
function drivers - is modelled on Geert's Zorro MFD experiments [1],
which were the inspiration for this series.
The RFC [2] got no replies, so its questions still stand:
- Geert, does this fit where you wanted to take the Zorro MFD work?
Should the parent stay in drivers/zorro/, as in your experiments,
or move to drivers/mfd/? Lee, I have Cc'd you for this one.
- Would you rather see the voltages, temperatures and fan in hwmon
than as plain sysfs attributes?
- Writing kickslot makes the ARM reset the machine on the spot. Is a
sysfs attribute acceptable for that?
Changes since the RFC:
- Rebased on v7.4-rc2, which has pata_cswarp and its defconfig patch.
- Dropped the WiFi configuration patch. The board commits the SSID and
the passphrase together when the passphrase arrives, so writing the
passphrase alone clears the SSID: two independent attributes cannot
express that.
- Documented the attributes in
Documentation/ABI/testing/sysfs-driver-warp-mfd and added a
MAINTAINERS entry.
- Created the attributes through .driver.dev_groups.
- pata_cswarp: mapped the cell with devm_ioremap_resource().
- The store callback takes a size_t count, the driver includes what it
uses, and the probe banner prints the board window with %pR.
Tested on a Warp 1260 (firmware 20.27) on top of v7.4-rc2. Every patch
builds warp-mfd and pata_cswarp with W=1 for m68k.
I wrote the original version of this driver myself, by hand. An LLM
coding assistant came in later: it was used to review that code
against CS-Lab's AmigaOS sources, to write several of the fixes folded
into these patches and the ABI documentation, to split the work into
this series and to draft the commit messages. I reviewed every change
and tested the result on my Warp 1260.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git/log/?h=zorro-mfd
[2] https://lore.kernel.org/r/20261021172910.134838-1-p.pisati@gmail.com
Paolo Pisati (7):
zorro: warp mfd: add the CS-Lab Warp multifunction parent
ata: pata_cswarp: bind to the Warp mfd cell instead of the Zorro
device
m68k: defconfig: enable WARP_MFD
zorro: warp mfd: add the dual-port RAM command channel and expose the
board identity
zorro: warp mfd: expose the voltage and temperature sensors
zorro: warp mfd: expose the fan duty cycle
zorro: warp mfd: expose the Kickstart slot selection
.../ABI/testing/sysfs-driver-warp-mfd | 53 ++
MAINTAINERS | 8 +
arch/m68k/configs/amiga_defconfig | 1 +
arch/m68k/configs/multi_defconfig | 1 +
drivers/ata/Kconfig | 2 +-
drivers/ata/pata_cswarp.c | 48 +-
drivers/zorro/Kconfig | 30 ++
drivers/zorro/Makefile | 2 +
drivers/zorro/warp-mfd.c | 473 ++++++++++++++++++
drivers/zorro/warp-mfd.h | 148 ++++++
10 files changed, 734 insertions(+), 32 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-driver-warp-mfd
create mode 100644 drivers/zorro/warp-mfd.c
create mode 100644 drivers/zorro/warp-mfd.h
base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 1/7] zorro: warp mfd: add the CS-Lab Warp multifunction parent
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 2/7] ata: pata_cswarp: bind to the Warp mfd cell instead of the Zorro device Paolo Pisati
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
The Warp 1260 is an A1200 trapdoor accelerator whose single Zorro device
fronts several functions: an ARM co-processor reached through a
dual-port RAM window, and an IDE interface and an RTG display controller
that the 68k drives directly.
pata_cswarp claims the whole device for the IDE window alone, which
leaves no way for anything else on the board to get a driver.
Add a parent that owns the Zorro device and describes the functions as
mfd cells, starting with the IDE window as a "warp-pata" cell.
Only the window layout is described here; the dual-port RAM protocol
arrives with its first user.
pata_cswarp is converted in the next patch.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
MAINTAINERS | 7 ++++
drivers/zorro/Kconfig | 30 ++++++++++++++
drivers/zorro/Makefile | 2 +
drivers/zorro/warp-mfd.c | 89 ++++++++++++++++++++++++++++++++++++++++
drivers/zorro/warp-mfd.h | 19 +++++++++
5 files changed, 147 insertions(+)
create mode 100644 drivers/zorro/warp-mfd.c
create mode 100644 drivers/zorro/warp-mfd.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 222b7fc2c3aa..cfabc4609c9d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7173,6 +7173,13 @@ L: linux-crypto@vger.kernel.org
S: Maintained
F: tools/crypto/tcrypt/tcrypt_speed_compare.py
+CS-LAB WARP MULTIFUNCTION DRIVER
+M: Paolo Pisati <p.pisati@gmail.com>
+L: linux-m68k@lists.linux-m68k.org
+S: Maintained
+F: drivers/zorro/warp-mfd.c
+F: drivers/zorro/warp-mfd.h
+
CS3308 MEDIA DRIVER
M: Hans Verkuil <hverkuil@kernel.org>
L: linux-media@vger.kernel.org
diff --git a/drivers/zorro/Kconfig b/drivers/zorro/Kconfig
index 41475ad46e45..c9ab9fb4b9ee 100644
--- a/drivers/zorro/Kconfig
+++ b/drivers/zorro/Kconfig
@@ -17,3 +17,33 @@ config ZORRO_NAMES
When in doubt, say Y.
+# Zorro multifunction drivers
+
+config WARP_MFD
+ tristate "CS-Lab Warp multifunction driver"
+ depends on ZORRO
+ select MFD_CORE
+ help
+ The CS-Lab Warp 1260 is an A1200 trapdoor accelerator. Besides the
+ 68060 it carries an FPGA and an ARM co-processor; its control
+ registers, the dual-port RAM and the IDE interface share one Zorro
+ device, which this driver binds to.
+
+ The 68k drives these through the FPGA: the on-board IDE interface and
+ an RTG display controller.
+
+ The co-processor owns the rest, reached over the dual-port RAM: two
+ USB host ports, an SD card slot, an ESP32 WiFi bridge,
+ an audio mixer, the Kickstart slot selection, the CPU clock and turbo
+ levels, thermal regulation of the fan, and the board telemetry.
+
+ This driver hands the IDE window to pata_cswarp - which needs
+ idemode=native set in Warp Configuration to be of any use - and
+ exposes the configuration and telemetry reachable over the dual-port
+ RAM in sysfs: voltages, temperatures, fan, firmware version and
+ Kickstart slot. Nothing else on the list has a driver yet.
+
+ If you have a CS-Lab Warp 1260 board, say Y. Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called warp-mfd.
diff --git a/drivers/zorro/Makefile b/drivers/zorro/Makefile
index 91ba82e633e7..6fe7cc1822dc 100644
--- a/drivers/zorro/Makefile
+++ b/drivers/zorro/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_ZORRO) += zorro.o zorro-driver.o zorro-sysfs.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_ZORRO_NAMES) += names.o
+obj-$(CONFIG_WARP_MFD) += warp-mfd.o
+
hostprogs := gen-devlist
# Files generated that shall be removed upon make clean
diff --git a/drivers/zorro/warp-mfd.c b/drivers/zorro/warp-mfd.c
new file mode 100644
index 000000000000..94af7c9d0ea5
--- /dev/null
+++ b/drivers/zorro/warp-mfd.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CS-Lab Warp multifunction driver
+ *
+ * Copyright 2026 Paolo Pisati <p.pisati@gmail.com>
+ *
+ * The Warp 1260 is an A1200 trapdoor accelerator made by CS-Lab. Besides the
+ * 68060 it carries an ARM co-processor which owns most of the peripherals,
+ * and the IDE interface and RTG display controller, which the 68k drives
+ * directly.
+ *
+ * This driver claims the Zorro device and hands the IDE window to pata_cswarp
+ * as an mfd cell.
+ */
+
+#include <linux/array_size.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+
+#include <linux/zorro.h>
+
+#include <linux/mfd/core.h>
+
+#include "warp-mfd.h"
+
+static const struct mfd_cell warp_mfd_cells[] = {
+ {
+ .name = "warp-pata",
+ .num_resources = 1,
+ .resources = (const struct resource []) {
+ DEFINE_RES_MEM_NAMED(WARP_OFFSET_ATA, WARP_ATA_SIZE,
+ "pata"),
+ }
+ }
+};
+
+static int warp_mfd_probe(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
+{
+ int error;
+
+ dev_info(&z->dev, "Warp at %pR\n", &z->resource);
+
+ error = mfd_add_devices(&z->dev, z->dev.id, warp_mfd_cells,
+ ARRAY_SIZE(warp_mfd_cells), &z->resource,
+ 0, NULL);
+ if (error) {
+ dev_err(&z->dev, "mfd_add_devices() failed %d\n", error);
+ return error;
+ }
+ return 0;
+}
+
+static void warp_mfd_remove(struct zorro_dev *z)
+{
+ mfd_remove_devices(&z->dev);
+}
+
+static const struct zorro_device_id warp_mfd_ids[] = {
+ { .id = ZORRO_PROD_CSLAB_WARP_1260 },
+ { }
+};
+MODULE_DEVICE_TABLE(zorro, warp_mfd_ids);
+
+static struct zorro_driver warp_mfd_driver = {
+ .name = "warp-mfd",
+ .id_table = warp_mfd_ids,
+ .probe = warp_mfd_probe,
+ .remove = warp_mfd_remove
+};
+
+static int __init warp_mfd_init(void)
+{
+ return zorro_register_driver(&warp_mfd_driver);
+}
+
+static void __exit warp_mfd_exit(void)
+{
+ zorro_unregister_driver(&warp_mfd_driver);
+}
+
+module_init(warp_mfd_init);
+module_exit(warp_mfd_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paolo Pisati <p.pisati@gmail.com>");
+MODULE_DESCRIPTION("CS-Lab Warp multifunction driver");
diff --git a/drivers/zorro/warp-mfd.h b/drivers/zorro/warp-mfd.h
new file mode 100644
index 000000000000..3f44f2b57c76
--- /dev/null
+++ b/drivers/zorro/warp-mfd.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * CS-Lab Warp - board window layout
+ *
+ * Copyright 2026 Paolo Pisati <p.pisati@gmail.com>
+ */
+
+#ifndef _WARP_MFD_H
+#define _WARP_MFD_H
+
+/* Offsets from the start of the board's Zorro window. */
+#define WARP_OFFSET_DPREG_CR 0x1000 /* dual-port interrupt control reg */
+#define WARP_OFFSET_DPRAM 0x2000 /* dual-port RAM */
+#define WARP_OFFSET_ATA 0x6000 /* on-board IDE interface */
+
+#define WARP_DPRAM_SIZE 0x2000
+#define WARP_ATA_SIZE 0x1800
+
+#endif /* _WARP_MFD_H */
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 2/7] ata: pata_cswarp: bind to the Warp mfd cell instead of the Zorro device
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 1/7] zorro: warp mfd: add the CS-Lab Warp multifunction parent Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 3/7] m68k: defconfig: enable WARP_MFD Paolo Pisati
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
Now that warp-mfd owns the device and hands the window out as the
"warp-pata" cell, take it from there.
PATA_CSWARP depends on WARP_MFD from here on.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
drivers/ata/Kconfig | 2 +-
drivers/ata/pata_cswarp.c | 48 ++++++++++++++-------------------------
2 files changed, 18 insertions(+), 32 deletions(-)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 9704ed688775..407b79bf9405 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -1035,7 +1035,7 @@ config PATA_GAYLE
config PATA_CSWARP
tristate "Amiga CS Warp PATA support"
- depends on M68K && AMIGA && ZORRO
+ depends on WARP_MFD
help
This option enables support for the on-board IDE interface on
CS-Lab Warp Expansion Card (NOTE that idemode=native has to be
diff --git a/drivers/ata/pata_cswarp.c b/drivers/ata/pata_cswarp.c
index 58fe6d0012dc..41b4c93052cf 100644
--- a/drivers/ata/pata_cswarp.c
+++ b/drivers/ata/pata_cswarp.c
@@ -14,14 +14,12 @@
#include <linux/ata.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
-#include <linux/device-id/zorro.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/libata.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/zorro.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -32,8 +30,6 @@
#define DRV_NAME "pata_cswarp"
-#define WARP_OFFSET_ATA 0x6000
-
static const struct scsi_host_template pata_cswarp_sht = {
ATA_PIO_SHT(DRV_NAME),
};
@@ -92,33 +88,27 @@ static struct ata_port_operations pata_cswarp_ops = {
.set_mode = pata_cswarp_set_mode,
};
-static int pata_cswarp_probe(struct zorro_dev *z,
- const struct zorro_device_id *ent)
+static int pata_cswarp_probe(struct platform_device *pdev)
{
static const char board_name[] = "csWarp";
struct ata_host *host;
struct ata_port *ap;
struct resource *res;
void __iomem *base;
- unsigned long board = z->resource.start;
- dev_info(&z->dev, "%s IDE controller (board: 0x%lx)\n", board_name,
- board);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pata");
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
- res = devm_request_mem_region(&z->dev, board + WARP_OFFSET_ATA, 0x1800,
- DRV_NAME);
- if (!res)
- return -ENXIO;
+ dev_info(&pdev->dev, "%s IDE controller (board: %pR)\n", board_name,
+ res);
- host = ata_host_alloc(&z->dev, 1);
+ host = ata_host_alloc(&pdev->dev, 1);
if (!host)
return -ENXIO;
ap = host->ports[0];
- base = devm_ioremap(&z->dev, board + WARP_OFFSET_ATA, 0x1800);
- if (!base)
- return -ENOMEM;
-
ap->ops = &pata_cswarp_ops;
ap->pio_mask = ATA_PIO4;
@@ -145,34 +135,29 @@ static int pata_cswarp_probe(struct zorro_dev *z,
IRQF_SHARED, &pata_cswarp_sht);
}
-static void pata_cswarp_remove(struct zorro_dev *z)
+static void pata_cswarp_remove(struct platform_device *pdev)
{
- struct ata_host *host = dev_get_drvdata(&z->dev);
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
ata_host_detach(host);
}
-static const struct zorro_device_id pata_cswarp_zorro_tbl[] = {
- { .id = ZORRO_PROD_CSLAB_WARP_1260 },
- { }
-};
-MODULE_DEVICE_TABLE(zorro, pata_cswarp_zorro_tbl);
-
-static struct zorro_driver pata_cswarp_driver = {
- .name = "pata_cswarp",
- .id_table = pata_cswarp_zorro_tbl,
+static struct platform_driver pata_cswarp_driver = {
+ .driver = {
+ .name = "warp-pata",
+ },
.probe = pata_cswarp_probe,
.remove = pata_cswarp_remove,
};
static int __init pata_cswarp_init(void)
{
- return zorro_register_driver(&pata_cswarp_driver);
+ return platform_driver_register(&pata_cswarp_driver);
}
static void __exit pata_cswarp_unregister(void)
{
- zorro_unregister_driver(&pata_cswarp_driver);
+ platform_driver_unregister(&pata_cswarp_driver);
}
module_init(pata_cswarp_init);
@@ -181,3 +166,4 @@ module_exit(pata_cswarp_unregister);
MODULE_AUTHOR("Andrzej Rogozynski");
MODULE_DESCRIPTION("low-level driver for CSWarp PATA");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:warp-pata");
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 3/7] m68k: defconfig: enable WARP_MFD
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 1/7] zorro: warp mfd: add the CS-Lab Warp multifunction parent Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 2/7] ata: pata_cswarp: bind to the Warp mfd cell instead of the Zorro device Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 4/7] zorro: warp mfd: add the dual-port RAM command channel and expose the board identity Paolo Pisati
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
Enable the CS-Lab Warp multifunction driver in the Amiga and multi
defconfigs, which pata_cswarp now depends on.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
arch/m68k/configs/amiga_defconfig | 1 +
arch/m68k/configs/multi_defconfig | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index e2d474e8cb8f..75d91d502545 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -20,6 +20,7 @@ CONFIG_AMIGA=y
CONFIG_ZORRO=y
CONFIG_AMIGA_PCMCIA=y
CONFIG_ZORRO_NAMES=y
+CONFIG_WARP_MFD=y
CONFIG_HEARTBEAT=y
CONFIG_PROC_HARDWARE=y
CONFIG_AMIGA_BUILTIN_SERIAL=y
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 1bbd2aa653c0..120dc68d492c 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -31,6 +31,7 @@ CONFIG_ZORRO=y
CONFIG_AMIGA_PCMCIA=y
CONFIG_ATARI_ROM_ISA=y
CONFIG_ZORRO_NAMES=y
+CONFIG_WARP_MFD=y
CONFIG_HEARTBEAT=y
CONFIG_PROC_HARDWARE=y
CONFIG_NATFEAT=y
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 4/7] zorro: warp mfd: add the dual-port RAM command channel and expose the board identity
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
` (2 preceding siblings ...)
2026-11-11 16:37 ` [PATCH v1 3/7] m68k: defconfig: enable WARP_MFD Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 5/7] zorro: warp mfd: expose the voltage and temperature sensors Paolo Pisati
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
The ARM co-processor is reached through a dual-port RAM window and an
interrupt control register: the 68k writes a command frame, rings the
ARM, and the ARM acknowledges and then answers in the same buffer,
raising a flag for each on the shared IRQ_AMIGA_PORTS line.
The protocol header describes only what the driver uses: the control
bits, GetDiag and its reply frame, laid out as the 68k sees it, with
static_assert()s pinning the offsets - the firmware decides them, not
the compiler.
Use it for the first attributes: boardname, hwver and fmwver, read from
a fresh diagnostic frame on every access.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
.../ABI/testing/sysfs-driver-warp-mfd | 16 ++
MAINTAINERS | 1 +
drivers/zorro/warp-mfd.c | 259 +++++++++++++++++-
drivers/zorro/warp-mfd.h | 120 +++++++-
4 files changed, 392 insertions(+), 4 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-driver-warp-mfd
diff --git a/Documentation/ABI/testing/sysfs-driver-warp-mfd b/Documentation/ABI/testing/sysfs-driver-warp-mfd
new file mode 100644
index 000000000000..8996d1961b96
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-warp-mfd
@@ -0,0 +1,16 @@
+What: /sys/bus/zorro/devices/zorro<N>/boardname
+Date: November 2026
+KernelVersion: 7.5
+Contact: Paolo Pisati <p.pisati@gmail.com>
+Description:
+ (RO) Name of the CS-Lab Warp board, as reported by its ARM
+ co-processor.
+
+What: /sys/bus/zorro/devices/zorro<N>/fmwver
+What: /sys/bus/zorro/devices/zorro<N>/hwver
+Date: November 2026
+KernelVersion: 7.5
+Contact: Paolo Pisati <p.pisati@gmail.com>
+Description:
+ (RO) Firmware and hardware version, as four hexadecimal digits:
+ an fmwver of 2027 is firmware release 20.27.
diff --git a/MAINTAINERS b/MAINTAINERS
index cfabc4609c9d..7b5e01300418 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7177,6 +7177,7 @@ CS-LAB WARP MULTIFUNCTION DRIVER
M: Paolo Pisati <p.pisati@gmail.com>
L: linux-m68k@lists.linux-m68k.org
S: Maintained
+F: Documentation/ABI/testing/sysfs-driver-warp-mfd
F: drivers/zorro/warp-mfd.c
F: drivers/zorro/warp-mfd.h
diff --git a/drivers/zorro/warp-mfd.c b/drivers/zorro/warp-mfd.c
index 94af7c9d0ea5..61866f678b61 100644
--- a/drivers/zorro/warp-mfd.c
+++ b/drivers/zorro/warp-mfd.c
@@ -9,22 +9,50 @@
* and the IDE interface and RTG display controller, which the 68k drives
* directly.
*
- * This driver claims the Zorro device and hands the IDE window to pata_cswarp
- * as an mfd cell.
+ * This driver claims the Zorro device, talks to the co-processor over the
+ * dual-port RAM to expose the board's configuration and telemetry in sysfs,
+ * and hands the IDE window to pata_cswarp as an mfd cell.
*/
#include <linux/array_size.h>
+#include <linux/completion.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
#include <linux/ioport.h>
+#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
#include <linux/zorro.h>
+#include <asm/amigaints.h>
#include <linux/mfd/core.h>
#include "warp-mfd.h"
+/**
+ * struct warp_mfd - per-board state
+ * @dev: the zorro device we hang off
+ * @dpram: mapped dual-port RAM, shared with the ARM co-processor
+ * @reg_cr: mapped dual-port interrupt control register
+ * @recv: completed when the ARM acknowledges a message
+ * @reply: completed when the ARM has a reply waiting in @dpram
+ * @lock: serialises use of @dpram, which is one shared buffer
+ */
+struct warp_mfd {
+ struct device *dev;
+ void __iomem *dpram;
+ void __iomem *reg_cr;
+ struct completion recv;
+ struct completion reply;
+ struct mutex lock; /* serialises @dpram */
+};
+
static const struct mfd_cell warp_mfd_cells[] = {
{
.name = "warp-pata",
@@ -36,13 +64,235 @@ static const struct mfd_cell warp_mfd_cells[] = {
}
};
+static irqreturn_t warp_irq(int irq, void *data)
+{
+ struct warp_mfd *warp = data;
+ u32 cr = z_readl(warp->reg_cr);
+ irqreturn_t ret = IRQ_NONE;
+
+ /*
+ * More than one of these can be latched by the time we run - the ARM
+ * acknowledges and answers a GetDiag in quick succession - so test
+ * them all. Returning after the first would leave the others set and
+ * their waiter asleep until it times out.
+ */
+ if (cr & DPREG_CR_MR_ARM) {
+ z_writel(DPREG_CR_CLR | DPREG_CR_MR_ARM, warp->reg_cr);
+ /* the ARM has taken the message out of the dual-port RAM */
+ complete(&warp->recv);
+ ret = IRQ_HANDLED;
+ }
+
+ if (cr & DPREG_CR_MP_68K) {
+ z_writel(DPREG_CR_CLR | DPREG_CR_MP_68K, warp->reg_cr);
+ /* the ARM has left a reply in the dual-port RAM */
+ complete(&warp->reply);
+ ret = IRQ_HANDLED;
+ }
+
+ if (cr & DPREG_CR_IF_ETHRX) {
+ z_writel(DPREG_CR_CLR | DPREG_CR_IF_ETHRX, warp->reg_cr);
+ /*
+ * Acknowledged only. There is no network driver behind this
+ * yet; the ARM stops re-raising it once the flag is cleared.
+ */
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+/*
+ * The AmigaOS library waits on SIGBREAKF_CTRL_C alongside the ARM's signal,
+ * so a user can always break out of a stalled exchange. We have no such
+ * escape from inside a sysfs store, so bound the wait instead - and stay
+ * interruptible, which is the part of that behaviour worth keeping.
+ */
+#define WARP_MSG_TIMEOUT msecs_to_jiffies(2000)
+
+/* send a message to the ARM coprocessor, optionally waiting for a reply */
+static int warp_send_msg(struct warp_mfd *warp, bool wait_reply)
+{
+ struct completion *done = wait_reply ? &warp->reply : &warp->recv;
+ long ret;
+
+ /* a previous exchange may have timed out and completed late */
+ reinit_completion(done);
+
+ /* enable 68k & ARM interrupts */
+ z_writel(DPREG_CR_SET | DPREG_CR_IE_68K | DPREG_CR_IE_ARM, warp->reg_cr);
+
+ /* send irq to ARM */
+ z_writel(DPREG_CR_SET | DPREG_CR_MP_ARM, warp->reg_cr);
+
+ /* wait for a reply, or just wait for a receiver ack */
+ ret = wait_for_completion_interruptible_timeout(done,
+ WARP_MSG_TIMEOUT);
+
+ /* disable ARM & 68k interrupts */
+ z_writel(DPREG_CR_CLR | DPREG_CR_IE_68K | DPREG_CR_IE_ARM, warp->reg_cr);
+
+ if (ret < 0)
+ return ret;
+ if (!ret) {
+ dev_err(warp->dev, "no answer from the ARM co-processor\n");
+ return -ETIMEDOUT;
+ }
+ return 0;
+}
+
+/*
+ * Submit one command frame and, when @rpl is given, collect the answer.
+ */
+static int warp_exec_cmd(struct warp_mfd *warp, const union warp_cmd *cmd,
+ union warp_reply *rpl)
+{
+ int ret;
+
+ ret = mutex_lock_interruptible(&warp->lock);
+ if (ret)
+ return ret;
+
+ z_memcpy_toio(warp->dpram, cmd, sizeof(*cmd));
+ ret = warp_send_msg(warp, rpl);
+ if (!ret && rpl)
+ z_memcpy_fromio(rpl, warp->dpram, sizeof(*rpl));
+
+ mutex_unlock(&warp->lock);
+ return ret;
+}
+
+static int warp_get_status(struct warp_mfd *warp, union warp_reply *rpl)
+{
+ union warp_cmd *cmd;
+ int ret;
+
+ cmd = kzalloc_obj(*cmd);
+ if (!cmd)
+ return -ENOMEM;
+ cmd->hdr.cmd = WARP_CMD_GET_DIAG;
+ ret = warp_exec_cmd(warp, cmd, rpl);
+ kfree(cmd);
+ if (ret)
+ return ret;
+
+ /*
+ * The dual-port RAM still holds the last frame written to it. If the
+ * board answered something else - or did not answer and we picked up
+ * a stale completion - the bytes look like a perfectly good reading.
+ * The vendor library checks this on every command; so do we.
+ */
+ if (rpl->hdr.rpl != WARP_RPL_DIAG) {
+ dev_err(warp->dev, "unexpected reply %u, wanted a diag frame\n",
+ rpl->hdr.rpl);
+ return -EIO;
+ }
+ return 0;
+}
+
+#define warp_config_uint_attr(name, field, format_string) \
+static ssize_t name##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ int ret; \
+ struct warp_mfd *warp = dev_get_drvdata(dev); \
+ union warp_reply *rpl; \
+ \
+ rpl = kmalloc_obj(*rpl); \
+ if (!rpl) \
+ return -ENOMEM; \
+ ret = warp_get_status(warp, rpl); \
+ if (ret) \
+ goto out; \
+ ret = sysfs_emit(buf, format_string "\n", rpl->diag.field); \
+out: \
+ kfree(rpl); \
+ return ret; \
+} \
+static DEVICE_ATTR_RO(name)
+
+#define warp_config_string_attr(name, field) \
+static ssize_t name##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ int ret; \
+ struct warp_mfd *warp = dev_get_drvdata(dev); \
+ union warp_reply *rpl; \
+ \
+ rpl = kmalloc_obj(*rpl); \
+ if (!rpl) \
+ return -ENOMEM; \
+ ret = warp_get_status(warp, rpl); \
+ if (ret) \
+ goto out; \
+ ret = sysfs_emit(buf, "%.*s\n", (int)sizeof(rpl->diag.field), \
+ rpl->diag.field); \
+out: \
+ kfree(rpl); \
+ return ret; \
+} \
+static DEVICE_ATTR_RO(name)
+
+warp_config_string_attr(boardname, board_name);
+warp_config_uint_attr(fmwver, fmw_ver, "%04X");
+warp_config_uint_attr(hwver, hw_ver, "%04X");
+
+static struct attribute *warp_attrs[] = {
+ /* RO attr */
+ &dev_attr_boardname.attr,
+ &dev_attr_fmwver.attr,
+ &dev_attr_hwver.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(warp);
+
static int warp_mfd_probe(struct zorro_dev *z,
const struct zorro_device_id *ent)
{
+ unsigned long base = z->resource.start;
+ struct warp_mfd *warp;
int error;
dev_info(&z->dev, "Warp at %pR\n", &z->resource);
+ warp = devm_kzalloc(&z->dev, sizeof(*warp), GFP_KERNEL);
+ if (!warp)
+ return -ENOMEM;
+ warp->dev = &z->dev;
+ mutex_init(&warp->lock);
+ init_completion(&warp->recv);
+ init_completion(&warp->reply);
+ zorro_set_drvdata(z, warp);
+
+ if (!devm_request_mem_region(&z->dev, base + WARP_OFFSET_DPREG_CR,
+ sizeof(u32), "warp-mfd")) {
+ dev_err(&z->dev, "cannot reserve the interrupt control register\n");
+ return -EBUSY;
+ }
+
+ if (!devm_request_mem_region(&z->dev, base + WARP_OFFSET_DPRAM,
+ WARP_DPRAM_SIZE, "warp-mfd")) {
+ dev_err(&z->dev, "cannot reserve the dual-port RAM window\n");
+ return -EBUSY;
+ }
+
+ warp->dpram = devm_ioremap(&z->dev, base + WARP_OFFSET_DPRAM,
+ WARP_DPRAM_SIZE);
+ warp->reg_cr = devm_ioremap(&z->dev, base + WARP_OFFSET_DPREG_CR,
+ sizeof(u32));
+ if (!warp->dpram || !warp->reg_cr) {
+ dev_err(&z->dev, "cannot map the dual-port RAM window\n");
+ return -ENOMEM;
+ }
+
+ error = devm_request_irq(&z->dev, IRQ_AMIGA_PORTS, warp_irq,
+ IRQF_SHARED, "warp-mfd", warp);
+ if (error) {
+ dev_err(&z->dev, "cannot request irq %u\n", IRQ_AMIGA_PORTS);
+ return error;
+ }
+
error = mfd_add_devices(&z->dev, z->dev.id, warp_mfd_cells,
ARRAY_SIZE(warp_mfd_cells), &z->resource,
0, NULL);
@@ -68,7 +318,10 @@ static struct zorro_driver warp_mfd_driver = {
.name = "warp-mfd",
.id_table = warp_mfd_ids,
.probe = warp_mfd_probe,
- .remove = warp_mfd_remove
+ .remove = warp_mfd_remove,
+ .driver = {
+ .dev_groups = warp_groups,
+ },
};
static int __init warp_mfd_init(void)
diff --git a/drivers/zorro/warp-mfd.h b/drivers/zorro/warp-mfd.h
index 3f44f2b57c76..366848545ea4 100644
--- a/drivers/zorro/warp-mfd.h
+++ b/drivers/zorro/warp-mfd.h
@@ -1,13 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * CS-Lab Warp - board window layout
+ * CS-Lab Warp - 68k <-> ARM dual-port RAM protocol
*
* Copyright 2026 Paolo Pisati <p.pisati@gmail.com>
+ *
+ * The Warp boards pair the 68k with an ARM co-processor. The two talk
+ * through a dual-port RAM window and a shared interrupt control register,
+ * both of which sit at fixed offsets inside the board's Zorro space.
+ *
+ * This describes only the small part of that interface this driver uses:
+ * the control register bits, the handful of commands behind the sysfs
+ * attributes, and the diagnostic reply. The board firmware implements many
+ * more commands - see the vendor sources for the full protocol.
+ *
+ * Multi-byte fields are laid out as the 68k sees them, and the wire format
+ * assumes 2-byte alignment for 32-bit members. That is what m68k gcc does
+ * by default, so no packing attribute is needed here - but it does mean the
+ * kernel must not be built with -malign-int, which would push every 32-bit
+ * member to a 4-byte boundary and desynchronise the layout from the board.
+ * The static_assert()s at the end of this file catch that.
*/
#ifndef _WARP_MFD_H
#define _WARP_MFD_H
+#include <linux/bits.h>
+#include <linux/build_bug.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+
/* Offsets from the start of the board's Zorro window. */
#define WARP_OFFSET_DPREG_CR 0x1000 /* dual-port interrupt control reg */
#define WARP_OFFSET_DPRAM 0x2000 /* dual-port RAM */
@@ -16,4 +37,101 @@
#define WARP_DPRAM_SIZE 0x2000
#define WARP_ATA_SIZE 0x1800
+/*
+ * Interrupt control register. Writes are read-modify-write requests rather
+ * than plain stores: OR in DPREG_CR_SET to set the named bits, or write them
+ * with DPREG_CR_CLR to clear them. Reads return the raw bit state.
+ */
+#define DPREG_CR_SET 0x80000000 /* set the bits in this word */
+#define DPREG_CR_CLR 0x00000000 /* clear the bits in this word */
+#define DPREG_CR_IE_ARM BIT(0) /* ARM irq enable */
+#define DPREG_CR_IE_68K BIT(1) /* 68k irq enable */
+#define DPREG_CR_MP_ARM BIT(2) /* message pending (ARM) */
+#define DPREG_CR_MP_68K BIT(3) /* message pending (68k) */
+#define DPREG_CR_MR_ARM BIT(4) /* message received (ARM) */
+#define DPREG_CR_MR_68K BIT(5) /* message received (68k) */
+#define DPREG_CR_IE_ETHRX BIT(6) /* ethernet rx irq enable */
+#define DPREG_CR_IF_ETHRX BIT(9) /* ethernet rx irq flag */
+
+#define WARP_BOARDNAME_LEN 32
+#define WARP_WIFI_SSID_LEN 128
+#define WARP_WIFI_PASS_LEN 128
+
+/* Command opcodes. Only the ones this driver issues are listed. */
+enum warp_cmd_id {
+ WARP_CMD_GET_DIAG = 6,
+};
+
+/* Reply opcodes, as reported in struct warp_rpl_hdr::rpl. */
+enum warp_rpl_id {
+ WARP_RPL_NOP = 0,
+ WARP_RPL_DIAG = 1,
+};
+
+struct warp_cmd_hdr {
+ u32 cmd; /* enum warp_cmd_id */
+};
+
+union warp_cmd {
+ struct warp_cmd_hdr hdr;
+};
+
+struct warp_rpl_hdr {
+ u32 rpl;
+};
+
+/*
+ * Reply to WARP_CMD_GET_DIAG. Fields this driver does not expose are kept
+ * so the ones after them land at the right offset.
+ *
+ * turbo_level and tz_corr_secs are reported by the firmware but no longer
+ * maintained by it; treat their contents as stale.
+ */
+struct warp_diag {
+ struct warp_rpl_hdr hdr;
+ u32 vcc5v; /* binary32 */
+ u32 vbatt; /* binary32 */
+ u32 t60_ntc; /* binary32 */
+ u32 t60_internal; /* binary32 */
+ u32 t_arm; /* binary32 */
+ u32 hw_ver;
+ u32 fmw_ver;
+ u32 turbo_level; /* obsolete, stale */
+ u32 fan_percent;
+ char board_name[WARP_BOARDNAME_LEN] __nonstring;
+ u32 kickstart_nr;
+ u32 usb_dev_status[2];
+ char wifi_ssid[WARP_WIFI_SSID_LEN] __nonstring;
+ char wifi_pass[WARP_WIFI_PASS_LEN] __nonstring;
+ u32 native_ide_enabled;
+ s32 temp_reg_cpu;
+ s32 temp_reg_min_pwm;
+ u8 ide_ior_as;
+ u8 ide_ior_ng;
+ u8 ide_iow_as;
+ u8 ide_iow_ng;
+ u8 ide_ack_as;
+ s32 tz_corr_secs; /* obsolete */
+ u8 board_type;
+ u32 wifi_state;
+ u32 cpu_freq_mhz; /* binary32 */
+ u32 cpu_clk_phase_shift_deg; /* binary32 */
+};
+
+union warp_reply {
+ struct warp_rpl_hdr hdr;
+ struct warp_diag diag;
+};
+
+/*
+ * The board decides these offsets, not the compiler. If a toolchain change
+ * moves them, every field past the first mismatch decodes as garbage, so
+ * fail the build instead.
+ */
+static_assert(offsetof(struct warp_diag, board_name) == 40);
+static_assert(offsetof(struct warp_diag, wifi_ssid) == 84);
+static_assert(offsetof(struct warp_diag, wifi_pass) == 212);
+static_assert(offsetof(struct warp_diag, wifi_state) == 364);
+static_assert(sizeof(struct warp_diag) == 376);
+
#endif /* _WARP_MFD_H */
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 5/7] zorro: warp mfd: expose the voltage and temperature sensors
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
` (3 preceding siblings ...)
2026-11-11 16:37 ` [PATCH v1 4/7] zorro: warp mfd: add the dual-port RAM command channel and expose the board identity Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 6/7] zorro: warp mfd: expose the fan duty cycle Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 7/7] zorro: warp mfd: expose the Kickstart slot selection Paolo Pisati
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
The diagnostic frame carries the 5 V rail, the backup battery and three
temperatures - the 68060, its NTC and the ARM - as IEEE-754 binary32.
Decode the bit pattern with integer arithmetic into milli-units.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
.../ABI/testing/sysfs-driver-warp-mfd | 19 +++++
drivers/zorro/warp-mfd.c | 80 +++++++++++++++++++
drivers/zorro/warp-mfd.h | 4 +
3 files changed, 103 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-driver-warp-mfd b/Documentation/ABI/testing/sysfs-driver-warp-mfd
index 8996d1961b96..fec712b8b9b0 100644
--- a/Documentation/ABI/testing/sysfs-driver-warp-mfd
+++ b/Documentation/ABI/testing/sysfs-driver-warp-mfd
@@ -14,3 +14,22 @@ Contact: Paolo Pisati <p.pisati@gmail.com>
Description:
(RO) Firmware and hardware version, as four hexadecimal digits:
an fmwver of 2027 is firmware release 20.27.
+
+What: /sys/bus/zorro/devices/zorro<N>/t60int
+What: /sys/bus/zorro/devices/zorro<N>/t60ext
+What: /sys/bus/zorro/devices/zorro<N>/tarm
+Date: November 2026
+KernelVersion: 7.5
+Contact: Paolo Pisati <p.pisati@gmail.com>
+Description:
+ (RO) Temperatures in degrees Celsius, with one decimal: t60int
+ is the 68060, t60ext its NTC, tarm the ARM co-processor.
+
+What: /sys/bus/zorro/devices/zorro<N>/vbatt
+What: /sys/bus/zorro/devices/zorro<N>/vcc5v
+Date: November 2026
+KernelVersion: 7.5
+Contact: Paolo Pisati <p.pisati@gmail.com>
+Description:
+ (RO) Voltages in volts, with two decimals: vbatt is the backup
+ battery, vcc5v the 5 V rail.
diff --git a/drivers/zorro/warp-mfd.c b/drivers/zorro/warp-mfd.c
index 61866f678b61..d407c786d44b 100644
--- a/drivers/zorro/warp-mfd.c
+++ b/drivers/zorro/warp-mfd.c
@@ -15,6 +15,7 @@
*/
#include <linux/array_size.h>
+#include <linux/bits.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/init.h>
@@ -22,6 +23,7 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/jiffies.h>
+#include <linux/limits.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
@@ -190,6 +192,73 @@ static int warp_get_status(struct warp_mfd *warp, union warp_reply *rpl)
return 0;
}
+/*
+ * The board reports its sensors as IEEE-754 binary32: decode the
+ * bit pattern by hand and carry the result as milli-units.
+ */
+static int warp_f32_to_milli(u32 bits)
+{
+ int exp = (bits >> 23) & 0xff;
+ u32 frac = bits & GENMASK(22, 0);
+ int shift = exp - 127 - 23;
+ s64 v;
+
+ /*
+ * inf, NaN, zero and subnormals all round to nothing useful here, and
+ * so does anything of 2^23 or more: that is already past what an int
+ * holds in milli-units, let alone what a sensor reports.
+ */
+ if (exp == 0xff || exp == 0 || shift >= 0)
+ return 0;
+ if (shift <= -63) /* smaller than a milli-unit */
+ return 0;
+
+ v = ((s64)(frac | BIT(23)) * 1000) >> -shift;
+ if (v > INT_MAX) /* a shift of -1 or -2 can still overflow */
+ return 0;
+
+ return (bits & BIT(31)) ? -(int)v : (int)v;
+}
+
+/* Render milli-units with @dec decimal places, rounded, as WarpDiag shows them. */
+static int warp_print_milli(char *buf, int milli, unsigned int dec)
+{
+ unsigned int scale = (dec == 1) ? 100 : 10;
+ unsigned int units = (dec == 1) ? 10 : 100;
+ const char *sign = "";
+ unsigned int v;
+
+ if (milli < 0) {
+ sign = "-";
+ milli = -milli;
+ }
+ v = ((unsigned int)milli + scale / 2) / scale;
+
+ return sysfs_emit(buf, "%s%u.%0*u\n", sign, v / units, dec, v % units);
+}
+
+#define warp_config_sensor_attr(name, field, dec) \
+static ssize_t name##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ int ret; \
+ struct warp_mfd *warp = dev_get_drvdata(dev); \
+ union warp_reply *rpl; \
+ \
+ rpl = kmalloc_obj(*rpl); \
+ if (!rpl) \
+ return -ENOMEM; \
+ ret = warp_get_status(warp, rpl); \
+ if (ret) \
+ goto out; \
+ ret = warp_print_milli(buf, \
+ warp_f32_to_milli(rpl->diag.field), dec);\
+out: \
+ kfree(rpl); \
+ return ret; \
+} \
+static DEVICE_ATTR_RO(name)
+
#define warp_config_uint_attr(name, field, format_string) \
static ssize_t name##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -236,12 +305,23 @@ static DEVICE_ATTR_RO(name)
warp_config_string_attr(boardname, board_name);
warp_config_uint_attr(fmwver, fmw_ver, "%04X");
warp_config_uint_attr(hwver, hw_ver, "%04X");
+/* board sensors: volts to 2 decimals, temperatures to 1, as WarpDiag shows them */
+warp_config_sensor_attr(t60int, t60_internal, 1);
+warp_config_sensor_attr(t60ext, t60_ntc, 1);
+warp_config_sensor_attr(tarm, t_arm, 1);
+warp_config_sensor_attr(vbatt, vbatt, 2);
+warp_config_sensor_attr(vcc5v, vcc5v, 2);
static struct attribute *warp_attrs[] = {
/* RO attr */
&dev_attr_boardname.attr,
&dev_attr_fmwver.attr,
&dev_attr_hwver.attr,
+ &dev_attr_t60int.attr,
+ &dev_attr_t60ext.attr,
+ &dev_attr_tarm.attr,
+ &dev_attr_vbatt.attr,
+ &dev_attr_vcc5v.attr,
NULL
};
diff --git a/drivers/zorro/warp-mfd.h b/drivers/zorro/warp-mfd.h
index 366848545ea4..4fa09fa972d4 100644
--- a/drivers/zorro/warp-mfd.h
+++ b/drivers/zorro/warp-mfd.h
@@ -84,6 +84,10 @@ struct warp_rpl_hdr {
* Reply to WARP_CMD_GET_DIAG. Fields this driver does not expose are kept
* so the ones after them land at the right offset.
*
+ * The board reports its sensors as IEEE-754 binary32. They are kept as raw
+ * bit patterns because the kernel cannot use the FPU; warp_f32_to_milli()
+ * decodes them with integer arithmetic.
+ *
* turbo_level and tz_corr_secs are reported by the firmware but no longer
* maintained by it; treat their contents as stale.
*/
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 6/7] zorro: warp mfd: expose the fan duty cycle
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
` (4 preceding siblings ...)
2026-11-11 16:37 ` [PATCH v1 5/7] zorro: warp mfd: expose the voltage and temperature sensors Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 7/7] zorro: warp mfd: expose the Kickstart slot selection Paolo Pisati
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
The diagnostic frame also reports the fan drive as a percentage.
Expose it as fanspeedpercent.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
Documentation/ABI/testing/sysfs-driver-warp-mfd | 7 +++++++
drivers/zorro/warp-mfd.c | 2 ++
2 files changed, 9 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-driver-warp-mfd b/Documentation/ABI/testing/sysfs-driver-warp-mfd
index fec712b8b9b0..a8213affb153 100644
--- a/Documentation/ABI/testing/sysfs-driver-warp-mfd
+++ b/Documentation/ABI/testing/sysfs-driver-warp-mfd
@@ -33,3 +33,10 @@ Contact: Paolo Pisati <p.pisati@gmail.com>
Description:
(RO) Voltages in volts, with two decimals: vbatt is the backup
battery, vcc5v the 5 V rail.
+
+What: /sys/bus/zorro/devices/zorro<N>/fanspeedpercent
+Date: November 2026
+KernelVersion: 7.5
+Contact: Paolo Pisati <p.pisati@gmail.com>
+Description:
+ (RO) Fan drive, as a percentage.
diff --git a/drivers/zorro/warp-mfd.c b/drivers/zorro/warp-mfd.c
index d407c786d44b..a438faeaa232 100644
--- a/drivers/zorro/warp-mfd.c
+++ b/drivers/zorro/warp-mfd.c
@@ -303,6 +303,7 @@ out: \
static DEVICE_ATTR_RO(name)
warp_config_string_attr(boardname, board_name);
+warp_config_uint_attr(fanspeedpercent, fan_percent, "%u");
warp_config_uint_attr(fmwver, fmw_ver, "%04X");
warp_config_uint_attr(hwver, hw_ver, "%04X");
/* board sensors: volts to 2 decimals, temperatures to 1, as WarpDiag shows them */
@@ -315,6 +316,7 @@ warp_config_sensor_attr(vcc5v, vcc5v, 2);
static struct attribute *warp_attrs[] = {
/* RO attr */
&dev_attr_boardname.attr,
+ &dev_attr_fanspeedpercent.attr,
&dev_attr_fmwver.attr,
&dev_attr_hwver.attr,
&dev_attr_t60int.attr,
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 7/7] zorro: warp mfd: expose the Kickstart slot selection
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
` (5 preceding siblings ...)
2026-11-11 16:37 ` [PATCH v1 6/7] zorro: warp mfd: expose the fan duty cycle Paolo Pisati
@ 2026-11-11 16:37 ` Paolo Pisati
6 siblings, 0 replies; 8+ messages in thread
From: Paolo Pisati @ 2026-11-11 16:37 UTC (permalink / raw)
To: Geert Uytterhoeven, Damien Le Moal, Niklas Cassel
Cc: linux-m68k, linux-ide, linux-kernel, Lee Jones, mfd
The board keeps several Kickstart images and the ARM boots the 68k from
the selected one.
Writing kickslot makes the ARM reset the machine on the spot. That is
how the board works, not a crash.
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
---
.../ABI/testing/sysfs-driver-warp-mfd | 11 +++++
drivers/zorro/warp-mfd.c | 49 +++++++++++++++++++
drivers/zorro/warp-mfd.h | 7 +++
3 files changed, 67 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-driver-warp-mfd b/Documentation/ABI/testing/sysfs-driver-warp-mfd
index a8213affb153..8cb7df076e15 100644
--- a/Documentation/ABI/testing/sysfs-driver-warp-mfd
+++ b/Documentation/ABI/testing/sysfs-driver-warp-mfd
@@ -40,3 +40,14 @@ KernelVersion: 7.5
Contact: Paolo Pisati <p.pisati@gmail.com>
Description:
(RO) Fan drive, as a percentage.
+
+What: /sys/bus/zorro/devices/zorro<N>/kickslot
+Date: November 2026
+KernelVersion: 7.5
+Contact: Paolo Pisati <p.pisati@gmail.com>
+Description:
+ (RW) Kickstart slot the ARM boots the 68k from. The board keeps
+ several Kickstart images.
+
+ Writing a slot number selects it and makes the ARM reset the
+ machine at once: that is how the board works, not a crash.
diff --git a/drivers/zorro/warp-mfd.c b/drivers/zorro/warp-mfd.c
index a438faeaa232..637ff4eccca3 100644
--- a/drivers/zorro/warp-mfd.c
+++ b/drivers/zorro/warp-mfd.c
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/jiffies.h>
+#include <linux/kstrtox.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -302,6 +303,52 @@ out: \
} \
static DEVICE_ATTR_RO(name)
+static ssize_t kickslot_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ struct warp_mfd *warp = dev_get_drvdata(dev);
+ union warp_reply *rpl;
+
+ rpl = kmalloc_obj(*rpl);
+ if (!rpl)
+ return -ENOMEM;
+ ret = warp_get_status(warp, rpl);
+ if (ret)
+ goto out;
+ ret = sysfs_emit(buf, "%u\n", rpl->diag.kickstart_nr);
+out:
+ kfree(rpl);
+ return ret;
+}
+
+/*
+ * WARNING:
+ * changing softkick slot will initiate a forced reboot - your Amiga is not
+ * crashing, it's the ARM MCU that is abruptly pulling the plug
+ */
+static ssize_t kickslot_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct warp_mfd *warp = dev_get_drvdata(dev);
+ union warp_cmd *cmd;
+ int ret;
+
+ cmd = kzalloc_obj(*cmd);
+ if (!cmd)
+ return -ENOMEM;
+ cmd->hdr.cmd = WARP_CMD_SELECT_KICK;
+ ret = kstrtou8(buf, 10, &cmd->select_kick.kick_nr);
+ if (ret)
+ goto done;
+ ret = warp_exec_cmd(warp, cmd, NULL);
+done:
+ kfree(cmd);
+ return ret ? ret : count;
+}
+static DEVICE_ATTR_RW(kickslot);
+
warp_config_string_attr(boardname, board_name);
warp_config_uint_attr(fanspeedpercent, fan_percent, "%u");
warp_config_uint_attr(fmwver, fmw_ver, "%04X");
@@ -324,6 +371,8 @@ static struct attribute *warp_attrs[] = {
&dev_attr_tarm.attr,
&dev_attr_vbatt.attr,
&dev_attr_vcc5v.attr,
+ /* RW attr */
+ &dev_attr_kickslot.attr,
NULL
};
diff --git a/drivers/zorro/warp-mfd.h b/drivers/zorro/warp-mfd.h
index 4fa09fa972d4..6bc7b38b5e4b 100644
--- a/drivers/zorro/warp-mfd.h
+++ b/drivers/zorro/warp-mfd.h
@@ -59,6 +59,7 @@
/* Command opcodes. Only the ones this driver issues are listed. */
enum warp_cmd_id {
+ WARP_CMD_SELECT_KICK = 5,
WARP_CMD_GET_DIAG = 6,
};
@@ -72,8 +73,14 @@ struct warp_cmd_hdr {
u32 cmd; /* enum warp_cmd_id */
};
+struct warp_cmd_select_kick {
+ struct warp_cmd_hdr hdr;
+ u8 kick_nr;
+};
+
union warp_cmd {
struct warp_cmd_hdr hdr;
+ struct warp_cmd_select_kick select_kick;
};
struct warp_rpl_hdr {
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-11-11 16:37 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 16:37 [PATCH v1 0/7] zorro: add a CS-Lab Warp 1260 MFD Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 1/7] zorro: warp mfd: add the CS-Lab Warp multifunction parent Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 2/7] ata: pata_cswarp: bind to the Warp mfd cell instead of the Zorro device Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 3/7] m68k: defconfig: enable WARP_MFD Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 4/7] zorro: warp mfd: add the dual-port RAM command channel and expose the board identity Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 5/7] zorro: warp mfd: expose the voltage and temperature sensors Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 6/7] zorro: warp mfd: expose the fan duty cycle Paolo Pisati
2026-11-11 16:37 ` [PATCH v1 7/7] zorro: warp mfd: expose the Kickstart slot selection Paolo Pisati
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®