[PATCH v2 46/53] mfd: ioc3: Add IOC4 ATA/ATAPI cell
From: Imre Kaloz
Date: Tue Oct 13 2026 - 10:36:17 EST
Add an IOC4 cell for pata_sgiioc4: a DEFINE_RES_MEM() over struct
ioc4_ata_regs and a DEFINE_RES_IRQ() for other_ir bit 0
(IOC4_OTHER_IR_ATA_INT). It joins ioc4_cells[] between the kbd and rtc
cells.
The ATA passthrough bit follows the drive's INTRQ line, which stays
asserted until Status is read, unlike the discrete events on the rest
of other_ir. Make it the one level-triggered bit of the other_ir bank.
libata reads Status while servicing the interrupt, so ioc3_irq_ack()'s
W1C write is the only ack needed.
Signed-off-by: Imre Kaloz <kaloz@xxxxxxxxxx>
---
arch/mips/include/asm/sn/ioc4.h | 1 +
drivers/mfd/ioc3.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/arch/mips/include/asm/sn/ioc4.h b/arch/mips/include/asm/sn/ioc4.h
index 781fcfb81b5e..d23676ae82b4 100644
--- a/arch/mips/include/asm/sn/ioc4.h
+++ b/arch/mips/include/asm/sn/ioc4.h
@@ -129,6 +129,7 @@ struct ioc4 {
#define IOC4_OTHER_IR_GEN_INT 0xff000000 /* generic pins */
#define IOC4_OTHER_IR_KBD_INT_BIT 6 /* bit index */
+#define IOC4_OTHER_IR_ATA_INT_BIT 0 /* bit index */
#define IOC4_SSCR_DMA_EN 0x10000000 /* enable ring buffer DMA */
diff --git a/drivers/mfd/ioc3.c b/drivers/mfd/ioc3.c
index 01c919c18b06..b471c90e737c 100644
--- a/drivers/mfd/ioc3.c
+++ b/drivers/mfd/ioc3.c
@@ -850,6 +850,13 @@ static const struct ioc3_variant ioc3_variant = {
(IOC4_SIO_IR_PORT_INT(0) | IOC4_SIO_IR_PORT_INT(1) | \
IOC4_SIO_IR_PORT_INT(2) | IOC4_SIO_IR_PORT_INT(3))
+/*
+ * In other_ir only ATA passthrough is level triggered. It follows the
+ * drive's INTRQ line, which stays asserted until the host reads Status;
+ * the other other_ir bits are discrete events.
+ */
+#define IOC4_OTHER_LVL_MASK IOC4_OTHER_IR_ATA_INT
+
#define IOC4_UART_RES(port) { \
DEFINE_RES_MEM(offsetof(struct ioc4, uart[port]), \
sizeof_field(struct ioc4, uart[port])), \
@@ -869,6 +876,12 @@ static const struct resource ioc4_kbd_resources[] = {
DEFINE_RES_IRQ(IOC4_IRQ_OTHER_BASE + IOC4_OTHER_IR_KBD_INT_BIT)
};
+static const struct resource ioc4_ata_resources[] = {
+ DEFINE_RES_MEM(offsetof(struct ioc4, ata),
+ sizeof_field(struct ioc4, ata)),
+ DEFINE_RES_IRQ(IOC4_IRQ_OTHER_BASE + IOC4_OTHER_IR_ATA_INT_BIT)
+};
+
static const struct resource ioc4_rtc_resources[] = {
DEFINE_RES_MEM(IOC4_BYTEBUS_DEV0, M48T35_REG_SIZE)
};
@@ -898,6 +911,11 @@ static const struct mfd_cell ioc4_cells[] = {
.resources = ioc4_kbd_resources,
.num_resources = ARRAY_SIZE(ioc4_kbd_resources),
},
+ {
+ .name = "pata_sgiioc4",
+ .resources = ioc4_ata_resources,
+ .num_resources = ARRAY_SIZE(ioc4_ata_resources),
+ },
{
.name = "rtc-m48t35-ip35",
.resources = ioc4_rtc_resources,
@@ -974,6 +992,7 @@ static const struct ioc3_irq_bank ioc4_irq_banks[] = {
.ir = offsetof(struct ioc4, other_ir),
.ies = offsetof(struct ioc4, other_ies),
.iec = offsetof(struct ioc4, other_iec),
+ .lvl_mask = IOC4_OTHER_LVL_MASK,
},
};
--
2.47.3