Linux Serial subsystem development
 help / color / mirror / Atom feed
* [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines
@ 2026-10-13 13:16 Imre Kaloz
  2026-10-13 13:16 ` [PATCH v2 31/53] mfd: ioc3: Add support for IOC4 Imre Kaloz
  2026-10-13 13:35 ` [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Niklas Cassel
  0 siblings, 2 replies; 4+ messages in thread
From: Imre Kaloz @ 2026-10-13 13:16 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: linux-mips, linux-kernel, Lee Jones, Greg Kroah-Hartman,
	Jiri Slaby, mfd, linux-serial, Alexandre Belloni, linux-rtc,
	Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, netdev, Damien Le Moal, Niklas Cassel, linux-ide,
	Pavel Machek, linux-leds, Bjorn Helgaas, linux-pci,
	Christoph Hellwig

This series adds support for the SGI machines built around the Bedrock
hub (IP35), such as Fuel and Tezro, to the IP27 platform code.

Patches 1-5 fix the config space accessors and slot setup of the
Bridge, XBridge and PIC driver: device numbers past the last slot,
slots the PROM leaves unconfigured, the type 1 IOC3 write, posted
config writes and slots whose devio window the PROM maps elsewhere.

Patches 6-22 teach the IP27 code the Bedrock hub: detection, the node
address layout and register windows, the node id, CPU slots, memory
banks, both PIs and the kernel load address.

Patches 23-32 add the crossbar, bridge and I/O parts of these machines:
PXBow, XBridge, PIC and IOC4.

Patches 33-44 add the L1 system controller and what it provides, the
Origin 300 IO8 serial interrupts, the Odyssey graphics widget, the
KLCONFIG console and a topology package id per CPU.

Patches 45-47 add a libata driver for the IOC4 ATA/ATAPI controller,
which carries the DVD-ROM of Tezro and Origin 350 I-bricks. It drives
PIO4 and multiword DMA mode 2.

Patch 48 updates ip27_defconfig to the onboard hardware of these
machines, dropping add-in card drivers and enabling USB and PS/2
input. Patch 49 enables the IOC4 ATA driver in it.

Patches 50-53 add a driver for the Fuel and Tezro front-panel LEDs,
which the L1 sets, as white:status and red:fault. The red LED blinks
on panic, and a Tezro shows the OS state on its L1 display.

The series applies on top of "[PATCH v2] MIPS: SGI-IP27: print the NMI
dump on an nbcon console", which the NMI dump needs to reach the 8250
console.

Tested on SGI Fuel and Tezro, the Fuel with an LSI 53C1030 and an NVMe
drive behind a PCI-X-to-PCIe bridge in slots the PROM leaves
unconfigured, on a 4GB Tezro with an LSI SAS1064 on a PCI-X bus, and
for patch 5 also on an Octane. Patches 50-53 were tested on a Tezro
only, and patch 48 was only built.

On IP27 (Hub) machines:
- patch 22 moves the kernel up by 144KB, and the 144KB below it stays
  reserved and unused;
- with patch 26 SWIOTLB takes 64MB of node 0 on a multi-node Origin,
  and ZONE_DMA32 spans the first 2GB;
- the XBridge and PIC DMA address forms (patch 26) and the w1 change
  (patch 39) do nothing on a Hub with classic Bridges;
- patches 1-5 change the config space handling of its Bridges as well.

Given I have no IP27 boxes, none of this was booted on one.
ip27_defconfig builds at every patch, ip30_defconfig at every patch
that changes code it builds.

An XBridge or PIC on a Bedrock hub takes its board setup from the
first board part number the L1 reports that the setup table knows
(patch 35), so on a machine with several bricks every such bridge gets
that one board's setup.

Patch 42 registers the Odyssey graphics widget as the "sgi-odyssey"
platform device used by the Odyssey DRM driver, a separate series, and
passes it the master widget id as the "sgi,master-widget" property.

checkpatch reports "spaces required around that ':'" in patches 14 and
21 for the GAS numeric local labels 1: and 2: in assembler macros.

Changes in v2:
- New patches 1-5 (Bridge config space and slot fixes), 37 (Origin
  300 IO8 serial interrupts), 45-47 and 49 (IOC4 ATA/ATAPI), 48
  (ip27_defconfig update) and 50-53 (front-panel LEDs).
- Patch 15 (was 10): slot 0 takes master_nasid as its node, not 0.
- Patch 24 (was 19): also enables the SGI 1-wire master and the DS250x
  slave the Bridge probe waits for.
- Patch 25 (was 20): comment and message name the IOC3 on the 32-bit
  window behind an XBridge or PIC.
- Patch 26 (was 21), retitled (Christoph Hellwig): an XBridge or PIC
  device with a 64-bit DMA mask uses the 64-bit direct form with bit 55
  set, other devices the 32-bit window with SWIOTLB and ZONE_DMA32; a
  PIC bus in PCI-X mode uses the direct form only; the IOC3 and IOC4
  always use the window, with byte swapping off; an IOC3 or IOC4 MFD
  cell maps through its PCI parent.
- Patch 29 (was 24): the PIC slot count goes through bridge_nslots()
  from patch 1.
- Patch 30 (was 25): probe fails without a platform device id.
- Patch 31 (was 26): probe fails on a PCI id without variant data;
  const mfd_cell array; MAINTAINERS covers sgi-ioc3-serial.h; the IOC4
  register layout includes the ATA/ATAPI block; the IOC4 firmware
  revision is printed, and the serial ports need revision 62 or later;
  the PCI id is PCI_DEVICE_ID_SGI_IOC4, which patch 26 adds.
- Patch 36 (was 31): const mfd_cell array.
- Patch 38 (was 32): the random fallback address is set with
  eth_hw_addr_random().
- Patch 42 (was 36): passes the "sgi,master-widget" property.
- Patch 43 (was 37): the PROM's console baud rate is printed unsigned,
  so 38400 does not come out negative.
- mfd subjects capitalised; rebased onto v7.3-rc7 and the NMI v2 patch.
- v1: https://lore.kernel.org/all/cover.1790857966.git.kaloz@kernel.org/

Imre Kaloz (53):
  MIPS: PCI: xtalk-bridge: refuse device numbers past the last slot
  MIPS: PCI: xtalk-bridge: assign slots the PROM leaves unconfigured
  MIPS: PCI: xtalk-bridge: write a type 1 IOC3 through the type 1 window
  MIPS: PCI: xtalk-bridge: flush config space writes
  MIPS: PCI: xtalk-bridge: reassign slots whose devio window maps
    elsewhere
  MIPS: Xtalk: guard the widget identification table from assembly
  MIPS: SGI-IP27: dump the NMI save areas the CPU scan recorded
  MIPS: SGI-IP27: add REMOTE_HUB_PI_S()/REMOTE_HUB_PI_L()
  MIPS: SGI-IP27: detect Bedrock hubs at boot
  MIPS: SGI-IP27: widen Kconfig for the Bedrock-based machines
  MIPS: SGI-IP27: fold the dead SN1 arm out of klconfig.h
  MIPS: SGI-IP27: choose the node address layout at runtime
  MIPS: SGI-IP27: add the Bedrock hub register windows
  MIPS: SGI-IP27: decode a Bedrock hub's node id and system size
  MIPS: SGI-IP27: put a Bedrock hub's boot CPU in slot 0
  MIPS: SGI-IP27: lay out node memory in 1GB banks on Bedrock hubs
  MIPS: SGI-IP27: reserve the bottom 64MB of node 0 on Bedrock hubs
  MIPS: SGI-IP27: route interrupt masks and slices through both PIs
  MIPS: SGI-IP27: address a CPU's own PI for NMI, IPI and RT counter
  MIPS: SGI-IP27: take a CPU's node from the CPU table in per_cpu_init()
  MIPS: SGI-IP27: resolve the mapped-kernel node shift at runtime
  MIPS: SGI-IP27: load the kernel at node offset 0x40000
  MIPS: SGI-IP27: xbow_probe(): recognize KLTYPE_PBRICK_XBOW
  MIPS: ip27_defconfig: enable the IOC3 MFD, its cell drivers and tg3
  net: ethernet: sgi: ioc3-eth: apply the DMA attributes only to 64-bit
    addresses
  MIPS: SGI-IP27: pick the XBridge and PIC DMA address form by mask
  MIPS: SGI-IP27: recognize the PXBow crossbar
  MIPS: PCI: xtalk-bridge: recognize the PIC widget's 64-bit-only
    registers
  MIPS: PCI: xtalk-bridge: match PIC's register-level differences
  rtc: m48t35: support the SGI IP35 timekeeper's 1968 year base
  mfd: ioc3: Add support for IOC4
  MIPS: SGI-IP27: dispatch the early console between IOC3 and IOC4
  MIPS: SGI-IP27: add L1 system controller support
  MIPS: SGI-IP27: wire the L1 into reset and the Ethernet address
  MIPS: PCI: xtalk-bridge: take the board part number from the L1
  mfd: ioc3: Add IP34 system-board entry to ioc3_infos[]
  mfd: ioc3: Cross the serial IRQs on the Origin 300 IO8
  net: ethernet: sgi: ioc3-eth: fall back to the platform MAC address
  MIPS: SGI-IP27: don't register a w1 master on an XBridge or PIC
  MIPS: SGI-IP27: report a Bedrock machine as SGI IP35
  MIPS: SGI-IP27: identify the machine by the L1 brick type
  MIPS: SGI-IP27: register the Odyssey graphics widget
  MIPS: SGI-IP27: take the console from the KLCONFIG header on IP35
  MIPS: SGI-IP27: give each CPU its own topology package id
  ata: add pata_sgiioc4 driver for the SGI IOC4 ATA/ATAPI controller
  mfd: ioc3: Add IOC4 ATA/ATAPI cell
  MAINTAINERS: add an entry for the SGI IOC4 ATA driver
  MIPS: ip27_defconfig: update for the onboard hardware
  MIPS: ip27_defconfig: enable pata_sgiioc4 and the DVD-ROM path
  MIPS: SGI-IP27: add L1 front-panel LED and display requests
  leds: Add driver for the SGI Fuel and Tezro front-panel LEDs
  MIPS: SGI-IP27: show the OS state on the Fuel and Tezro front panels
  MIPS: ip27_defconfig: enable the Fuel and Tezro front-panel LEDs

 MAINTAINERS                                   |   7 +
 arch/mips/Kconfig                             |  13 +-
 arch/mips/configs/ip27_defconfig              | 192 +---
 .../include/asm/mach-ip27/kernel-entry-init.h |  33 +-
 arch/mips/include/asm/pci/bridge.h            |  88 +-
 arch/mips/include/asm/sn/addrs.h              |  39 +-
 arch/mips/include/asm/sn/agent.h              |   5 +-
 arch/mips/include/asm/sn/arch.h               |   8 +
 arch/mips/include/asm/sn/intr.h               |  14 +-
 arch/mips/include/asm/sn/ioc4.h               | 143 +++
 arch/mips/include/asm/sn/klconfig.h           |  19 +-
 arch/mips/include/asm/sn/kldir.h              |   1 +
 arch/mips/include/asm/sn/l1.h                 |  38 +
 arch/mips/include/asm/sn/mapped_kernel.h      |   6 +-
 arch/mips/include/asm/sn/sn0/addrs.h          |   8 +-
 arch/mips/include/asm/sn/sn0/hub.h            |  37 +-
 arch/mips/include/asm/sn/sn0/hubni.h          |   3 +
 arch/mips/include/asm/sn/sn1/addrs.h          |  22 +
 arch/mips/include/asm/sn/sn1/hub.h            |  40 +
 arch/mips/include/asm/sn/sn1/kldir.h          |  14 +
 arch/mips/include/asm/xtalk/xwidget.h         |  11 +-
 arch/mips/pci/pci-xtalk-bridge.c              | 467 ++++++++-
 arch/mips/sgi-ip27/Makefile                   |   4 +-
 arch/mips/sgi-ip27/Platform                   |  11 +-
 arch/mips/sgi-ip27/ip27-berr.c                |   4 +-
 arch/mips/sgi-ip27/ip27-console.c             |  47 +-
 arch/mips/sgi-ip27/ip27-init.c                | 178 +++-
 arch/mips/sgi-ip27/ip27-irq.c                 |  17 +-
 arch/mips/sgi-ip27/ip27-l1.c                  | 884 ++++++++++++++++++
 arch/mips/sgi-ip27/ip27-memory.c              |  55 +-
 arch/mips/sgi-ip27/ip27-nmi.c                 |  54 +-
 arch/mips/sgi-ip27/ip27-reset.c               |  47 +-
 arch/mips/sgi-ip27/ip27-smp.c                 |  41 +-
 arch/mips/sgi-ip27/ip27-timer.c               |  12 +-
 arch/mips/sgi-ip27/ip27-xtalk.c               | 138 ++-
 drivers/ata/Kconfig                           |  10 +
 drivers/ata/Makefile                          |   1 +
 drivers/ata/pata_sgiioc4.c                    | 311 ++++++
 drivers/leds/Kconfig                          |  12 +
 drivers/leds/Makefile                         |   1 +
 drivers/leds/leds-ip35.c                      | 144 +++
 drivers/mfd/ioc3.c                            | 455 ++++++++-
 drivers/net/ethernet/sgi/ioc3-eth.c           |  44 +-
 drivers/rtc/rtc-m48t35.c                      |  33 +-
 drivers/tty/serial/8250/8250_ioc3.c           |   5 +-
 include/linux/pci_ids.h                       |   1 +
 include/linux/platform_data/sgi-ioc3-serial.h |  13 +
 include/linux/platform_data/xtalk-bridge.h    |   2 +
 48 files changed, 3334 insertions(+), 398 deletions(-)
 create mode 100644 arch/mips/include/asm/sn/ioc4.h
 create mode 100644 arch/mips/include/asm/sn/l1.h
 create mode 100644 arch/mips/include/asm/sn/sn1/addrs.h
 create mode 100644 arch/mips/include/asm/sn/sn1/hub.h
 create mode 100644 arch/mips/include/asm/sn/sn1/kldir.h
 create mode 100644 arch/mips/sgi-ip27/ip27-l1.c
 create mode 100644 drivers/ata/pata_sgiioc4.c
 create mode 100644 drivers/leds/leds-ip35.c
 create mode 100644 include/linux/platform_data/sgi-ioc3-serial.h


base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
prerequisite-patch-id: 642054c4c189f29a3f589a119d2311c20e395a23
-- 
2.47.3


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 31/53] mfd: ioc3: Add support for IOC4
  2026-10-13 13:16 [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Imre Kaloz
@ 2026-10-13 13:16 ` Imre Kaloz
  2026-10-13 13:35 ` [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Niklas Cassel
  1 sibling, 0 replies; 4+ messages in thread
From: Imre Kaloz @ 2026-10-13 13:16 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: linux-mips, linux-kernel, Lee Jones, Greg Kroah-Hartman,
	Jiri Slaby, mfd, linux-serial

IOC4 is IOC3's successor on IP35 Origin 350-class boards. Its serial and
PS/2 cores reuse IOC3's drivers and its interrupt status splits into two
banks. The serial ports need IOC4 firmware revision 62 or later and are
not registered on older firmware.

The serial, interrupt and GPIO register definitions in asm/sn/ioc4.h
follow include/linux/ioc4.h and drivers/tty/serial/ioc4_serial.c, removed
by commit f7bc6e42bf12 ("drivers: remove the SGI SN2 IOC4 base support")
and commit a017ef17cfd8 ("tty/serial: remove the ioc4_serial driver").

Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
 MAINTAINERS                                   |   1 +
 arch/mips/include/asm/sn/ioc4.h               | 142 ++++++++
 drivers/mfd/ioc3.c                            | 323 +++++++++++++++---
 drivers/tty/serial/8250/8250_ioc3.c           |   5 +-
 include/linux/platform_data/sgi-ioc3-serial.h |  13 +
 5 files changed, 438 insertions(+), 46 deletions(-)
 create mode 100644 arch/mips/include/asm/sn/ioc4.h
 create mode 100644 include/linux/platform_data/sgi-ioc3-serial.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f53047aa8d3c..a30c09a55c72 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18219,6 +18219,7 @@ F:	arch/mips/
 F:	drivers/platform/mips/
 F:	include/dt-bindings/mips/
 F:	include/linux/platform_data/pic32.h
+F:	include/linux/platform_data/sgi-ioc3-serial.h
 
 MIPS BOSTON DEVELOPMENT BOARD
 M:	Paul Burton <paulburton@kernel.org>
diff --git a/arch/mips/include/asm/sn/ioc4.h b/arch/mips/include/asm/sn/ioc4.h
new file mode 100644
index 000000000000..781fcfb81b5e
--- /dev/null
+++ b/arch/mips/include/asm/sn/ioc4.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * IOC4 -- SGI's I/O ASIC on Tezro/Origin 350-class boards.
+ *
+ * Copyright (C) 2003-2006 Silicon Graphics, Inc.
+ */
+#ifndef MIPS_SN_IOC4_H
+#define MIPS_SN_IOC4_H
+
+#include <linux/types.h>
+
+struct ioc4_serialregs {
+	u32	sscr;
+	u32	stpir;
+	u32	stcir;
+	u32	srpir;
+	u32	srcir;
+	u32	srtr;
+	u32	shadow;
+};
+
+struct ioc4_uartregs {
+	u8	i4u_lcr;
+	union {
+		u8	i4u_iir;	/* read only */
+		u8	i4u_fcr;	/* write only */
+	};
+	union {
+		u8	i4u_ier;	/* DLAB == 0 */
+		u8	i4u_dlm;	/* DLAB == 1 */
+	};
+	union {
+		u8	i4u_rbr;	/* read only, DLAB == 0 */
+		u8	i4u_thr;	/* write only, DLAB == 0 */
+		u8	i4u_dll;	/* DLAB == 1 */
+	};
+	u8	i4u_scr;
+	u8	i4u_msr;
+	u8	i4u_lsr;
+	u8	i4u_mcr;
+};
+
+struct ioc4_serioregs {
+	u32	km_csr;
+	u32	k_rd;
+	u32	m_rd;
+	u32	k_wd;
+	u32	m_wd;
+};
+
+/* ATA/ATAPI block: one taskfile register per 32-bit word. */
+struct ioc4_ata_regs {
+	u32	cmd[8];		/* 0x000, data through status/command */
+	u32	ctrl;		/* 0x020, altstatus/devctrl */
+	u32	pad[(0x040 - 0x024) / 4]; /* 0x024 */
+	u32	dma[9];		/* 0x040, DMA engine */
+};
+
+/* Register layout of IOC4 in PCI BAR0. */
+struct ioc4 {
+	u32	pci_err_addr_l;	/* 0x00000 */
+	u32	pci_err_addr_h;	/* 0x00004 */
+	u32	sio_ir;		/* 0x00008 */
+	u32	other_ir;	/* 0x0000c */
+	u32	sio_ies;	/* 0x00010 */
+	u32	other_ies;	/* 0x00014 */
+	u32	sio_iec;	/* 0x00018 */
+	u32	other_iec;	/* 0x0001c */
+	u32	sio_cr;		/* 0x00020 */
+	u32	pad0;		/* 0x00024 */
+	u32	int_out;	/* 0x00028 */
+	u32	pad1;		/* 0x0002c */
+	u32	gpcr_s;		/* 0x00030 */
+	u32	gpcr_c;		/* 0x00034 */
+	u32	gpdr;		/* 0x00038 */
+	u32	pad2;		/* 0x0003c */
+	u32	gppr[8];	/* 0x00040 */
+
+	u32	pad3[(0x100 - 0x60) / 4];	/* 0x00060 */
+
+	struct ioc4_ata_regs	ata;	/* 0x00100 */
+
+	u32	pad3b[(0x200 - 0x164) / 4];	/* 0x00164 */
+
+	struct ioc4_serioregs	serio;	/* 0x00200, IOC4_KBC_BASE */
+
+	u32	pad4[(0x300 - 0x214) / 4];
+
+	u32	sbbr01_l;	/* 0x00300 */
+	u32	sbbr01_h;	/* 0x00304 */
+	u32	sbbr23_l;	/* 0x00308 */
+	u32	sbbr23_h;	/* 0x0030c */
+
+	struct ioc4_serialregs	port[4];	/* 0x00310 */
+	struct ioc4_uartregs	uart[4];	/* 0x00380 */
+};
+
+/* Bytebus device 0, where the TOD chip sits. */
+#define IOC4_BYTEBUS_DEV0	0x80000L
+
+/* sio_ir carries serial events only, one 8-bit group per port. */
+#define IOC4_SIO_IR_TX_MT	0x01	/* TX ring buffer empty */
+#define IOC4_SIO_IR_RX_FULL	0x02	/* RX ring buffer full */
+#define IOC4_SIO_IR_RX_HIGH	0x04	/* RX high-water exceeded */
+#define IOC4_SIO_IR_RX_TIMER	0x08	/* RX timer has triggered */
+#define IOC4_SIO_IR_DELTA_DCD	0x10	/* DELTA_DCD seen */
+#define IOC4_SIO_IR_DELTA_CTS	0x20	/* DELTA_CTS seen */
+#define IOC4_SIO_IR_INT		0x40	/* UART pass-through interrupt */
+#define IOC4_SIO_IR_TX_EXPLICIT	0x80	/* TX, MCW, or delay complete */
+
+#define IOC4_SIO_IR_PORT_SHIFT(port)	((port) * 8)
+#define IOC4_SIO_IR_PORT_INT(port) \
+	(IOC4_SIO_IR_INT << IOC4_SIO_IR_PORT_SHIFT(port))
+
+/* Bit index of IOC4_SIO_IR_INT; DEFINE_RES_IRQ() needs a constant. */
+#define IOC4_SIO_IR_INT_BIT		6
+#define IOC4_SIO_IR_PORT_INT_BIT(port) \
+	(IOC4_SIO_IR_PORT_SHIFT(port) + IOC4_SIO_IR_INT_BIT)
+
+#define IOC4_OTHER_IR_ATA_INT		0x00000001	/* ATA passthru */
+#define IOC4_OTHER_IR_ATA_MEMERR	0x00000002	/* ATA PCI error */
+#define IOC4_OTHER_IR_S0_MEMERR		0x00000004	/* port 0 PCI error */
+#define IOC4_OTHER_IR_S1_MEMERR		0x00000008	/* port 1 PCI error */
+#define IOC4_OTHER_IR_S2_MEMERR		0x00000010	/* port 2 PCI error */
+#define IOC4_OTHER_IR_S3_MEMERR		0x00000020	/* port 3 PCI error */
+/* The IX-brick wires this bit to the PS/2 ports. */
+#define IOC4_OTHER_IR_KBD_INT		0x00000040
+#define IOC4_OTHER_IR_RT_INT		0x00800000	/* INT_OUT latch */
+#define IOC4_OTHER_IR_GEN_INT		0xff000000	/* generic pins */
+
+#define IOC4_OTHER_IR_KBD_INT_BIT	6	/* bit index */
+
+#define IOC4_SSCR_DMA_EN	0x10000000	/* enable ring buffer DMA */
+
+/* GPIO pins 4-7 select RS232 or RS422 mode for the four UARTs. */
+#define IOC4_GPCR_UART_MODESEL(port)		(0x10 << (port))
+#define IOC4_GPPR_UART_MODESEL_PIN(port)	(4 + (port))
+
+/* The serial core runs off the PCI bus clock, 66MHz in the IX-brick. */
+#define IOC4_UARTCLK	66666667
+
+#endif /* MIPS_SN_IOC4_H */
diff --git a/drivers/mfd/ioc3.c b/drivers/mfd/ioc3.c
index 5f8ac364b610..57956c00263f 100644
--- a/drivers/mfd/ioc3.c
+++ b/drivers/mfd/ioc3.c
@@ -19,11 +19,13 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/sgi-ioc3-serial.h>
 #include <linux/platform_data/sgi-w1.h>
 #include <linux/rtc/ds1685.h>
 
 #include <asm/pci/bridge.h>
 #include <asm/sn/ioc3.h>
+#include <asm/sn/ioc4.h>
 
 #define IOC3_IRQ_SERIAL_A	6
 #define IOC3_IRQ_SERIAL_B	15
@@ -37,9 +39,33 @@
 /* 1.2 us latency timer (40 cycles at 33 MHz) */
 #define IOC3_LATENCY	40
 
+struct ioc3_priv_data;
+
+/*
+ * One interrupt bank: an ir/ies/iec register triplet covering 32 hwirqs.
+ * IOC3 has a single bank. IOC4 keeps only the four serial ports in
+ * sio_ir and moves ATA, memory-error, keyboard, RT and generic-pin
+ * events into a second bank, other_ir.
+ */
+struct ioc3_irq_bank {
+	u16 ir, ies, iec;	/* BAR0 offsets */
+	u32 lvl_mask;		/* hwirqs needing level-triggered handling */
+};
+
+struct ioc3_variant {
+	const char *name;
+	struct irq_chip *chip;
+	const struct ioc3_irq_bank *banks;
+	unsigned int nr_banks;
+	unsigned int nr_irqs;
+	u16 pci_command;	/* extra PCI_COMMAND bits to set at probe */
+	int (*setup)(struct ioc3_priv_data *ipd);
+};
+
 struct ioc3_priv_data {
 	struct irq_domain *domain;
-	struct ioc3 __iomem *regs;
+	void __iomem *base;
+	const struct ioc3_variant *var;
 	struct pci_dev *pdev;
 	int domain_irq;
 };
@@ -48,24 +74,27 @@ static void ioc3_irq_ack(struct irq_data *d)
 {
 	struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
+	const struct ioc3_irq_bank *bank = &ipd->var->banks[hwirq / 32];
 
-	writel(BIT(hwirq), &ipd->regs->sio_ir);
+	writel(BIT(hwirq % 32), ipd->base + bank->ir);
 }
 
 static void ioc3_irq_mask(struct irq_data *d)
 {
 	struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
+	const struct ioc3_irq_bank *bank = &ipd->var->banks[hwirq / 32];
 
-	writel(BIT(hwirq), &ipd->regs->sio_iec);
+	writel(BIT(hwirq % 32), ipd->base + bank->iec);
 }
 
 static void ioc3_irq_unmask(struct irq_data *d)
 {
 	struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
+	const struct ioc3_irq_bank *bank = &ipd->var->banks[hwirq / 32];
 
-	writel(BIT(hwirq), &ipd->regs->sio_ies);
+	writel(BIT(hwirq % 32), ipd->base + bank->ies);
 }
 
 static struct irq_chip ioc3_irq_chip = {
@@ -75,16 +104,25 @@ static struct irq_chip ioc3_irq_chip = {
 	.irq_unmask	= ioc3_irq_unmask,
 };
 
+static struct irq_chip ioc4_irq_chip = {
+	.name		= "IOC4",
+	.irq_ack	= ioc3_irq_ack,
+	.irq_mask	= ioc3_irq_mask,
+	.irq_unmask	= ioc3_irq_unmask,
+};
+
 static int ioc3_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hwirq)
 {
-	/* Set level IRQs for every interrupt contained in IOC3_LVL_MASK */
-	if (BIT(hwirq) & IOC3_LVL_MASK)
-		irq_set_chip_and_handler(irq, &ioc3_irq_chip, handle_level_irq);
+	struct ioc3_priv_data *ipd = d->host_data;
+	const struct ioc3_irq_bank *bank = &ipd->var->banks[hwirq / 32];
+
+	if (BIT(hwirq % 32) & bank->lvl_mask)
+		irq_set_chip_and_handler(irq, ipd->var->chip, handle_level_irq);
 	else
-		irq_set_chip_and_handler(irq, &ioc3_irq_chip, handle_edge_irq);
+		irq_set_chip_and_handler(irq, ipd->var->chip, handle_edge_irq);
 
-	irq_set_chip_data(irq, d->host_data);
+	irq_set_chip_data(irq, ipd);
 	return 0;
 }
 
@@ -103,17 +141,21 @@ static void ioc3_irq_handler(struct irq_desc *desc)
 {
 	struct irq_domain *domain = irq_desc_get_handler_data(desc);
 	struct ioc3_priv_data *ipd = domain->host_data;
-	struct ioc3 __iomem *regs = ipd->regs;
-	u32 pending, mask;
+	unsigned int i;
 
-	pending = readl(&regs->sio_ir);
-	mask = readl(&regs->sio_ies);
-	pending &= mask; /* Mask off not enabled interrupts */
+	for (i = 0; i < ipd->var->nr_banks; i++) {
+		const struct ioc3_irq_bank *bank = &ipd->var->banks[i];
+		u32 pending = readl(ipd->base + bank->ir) &
+			      readl(ipd->base + bank->ies);
 
-	if (pending)
-		generic_handle_domain_irq(domain, __ffs(pending));
-	else
-		spurious_interrupt();
+		if (pending) {
+			generic_handle_domain_irq(domain,
+						  i * 32 + __ffs(pending));
+			return;
+		}
+	}
+
+	spurious_interrupt();
 }
 
 /*
@@ -134,11 +176,12 @@ static int ioc3_irq_domain_setup(struct ioc3_priv_data *ipd, int irq)
 	struct irq_domain *domain;
 	struct fwnode_handle *fn;
 
-	fn = irq_domain_alloc_named_fwnode("IOC3");
+	fn = irq_domain_alloc_named_fwnode(ipd->var->name);
 	if (!fn)
 		goto err;
 
-	domain = irq_domain_create_linear(fn, 24, &ioc3_irq_domain_ops, ipd);
+	domain = irq_domain_create_linear(fn, ipd->var->nr_irqs,
+					  &ioc3_irq_domain_ops, ipd);
 	if (!domain) {
 		irq_domain_free_fwnode(fn);
 		goto err;
@@ -182,21 +225,19 @@ static struct mfd_cell ioc3_serial_cells[] = {
 
 static int ioc3_serial_setup(struct ioc3_priv_data *ipd)
 {
+	struct ioc3 __iomem *regs = ipd->base;
 	int ret;
 
 	/* Set gpio pins for RS232/RS422 mode selection */
-	writel(GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL,
-		&ipd->regs->gpcr_s);
+	writel(GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL, &regs->gpcr_s);
 	/* Select RS232 mode for uart a */
-	writel(0, &ipd->regs->gppr[6]);
+	writel(0, &regs->gppr[6]);
 	/* Select RS232 mode for uart b */
-	writel(0, &ipd->regs->gppr[7]);
+	writel(0, &regs->gppr[7]);
 
 	/* Switch both ports to 16650 mode */
-	writel(readl(&ipd->regs->port_a.sscr) & ~SSCR_DMA_EN,
-	       &ipd->regs->port_a.sscr);
-	writel(readl(&ipd->regs->port_b.sscr) & ~SSCR_DMA_EN,
-	       &ipd->regs->port_b.sscr);
+	writel(readl(&regs->port_a.sscr) & ~SSCR_DMA_EN, &regs->port_a.sscr);
+	writel(readl(&regs->port_b.sscr) & ~SSCR_DMA_EN, &regs->port_b.sscr);
 	udelay(1000); /* Wait until mode switch is done */
 
 	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
@@ -270,10 +311,11 @@ static struct mfd_cell ioc3_eth_cells[] = {
 
 static int ioc3_eth_setup(struct ioc3_priv_data *ipd)
 {
+	struct ioc3 __iomem *regs = ipd->base;
 	int ret;
 
 	/* Enable One-Wire bus */
-	writel(GPCR_MLAN_EN, &ipd->regs->gpcr_s);
+	writel(GPCR_MLAN_EN, &regs->gpcr_s);
 
 	/* Generate unique identifier */
 	snprintf(ioc3_w1_platform_data.dev_id,
@@ -539,14 +581,12 @@ static struct {
 
 static int ioc3_setup(struct ioc3_priv_data *ipd)
 {
+	struct ioc3 __iomem *regs = ipd->base;
 	u32 sid;
 	int i;
 
-	/* Clear IRQs */
-	writel(~0, &ipd->regs->sio_iec);
-	writel(~0, &ipd->regs->sio_ir);
-	writel(0, &ipd->regs->eth.eier);
-	writel(~0, &ipd->regs->eth.eisr);
+	writel(0, &regs->eth.eier);
+	writel(~0, &regs->eth.eisr);
 
 	/* Read subsystem vendor id and subsystem id */
 	pci_read_config_dword(ipd->pdev, PCI_SUBSYSTEM_VENDOR_ID, &sid);
@@ -565,10 +605,16 @@ static int ioc3_setup(struct ioc3_priv_data *ipd)
 static int ioc3_mfd_probe(struct pci_dev *pdev,
 			  const struct pci_device_id *pci_id)
 {
+	const struct ioc3_variant *var = (void *)pci_id->driver_data;
 	struct ioc3_priv_data *ipd;
-	struct ioc3 __iomem *regs;
+	void __iomem *base;
+	unsigned int i;
+	u16 cmd;
 	int ret;
 
+	if (!var)
+		return -ENODEV;
+
 	ret = pci_enable_device(pdev);
 	if (ret)
 		return ret;
@@ -576,6 +622,12 @@ static int ioc3_mfd_probe(struct pci_dev *pdev,
 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, IOC3_LATENCY);
 	pci_set_master(pdev);
 
+	if (var->pci_command) {
+		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+		pci_write_config_word(pdev, PCI_COMMAND,
+				      cmd | var->pci_command);
+	}
+
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 	if (ret) {
 		pr_err("%s: No usable DMA configuration, aborting.\n",
@@ -591,24 +643,31 @@ static int ioc3_mfd_probe(struct pci_dev *pdev,
 		goto out_disable_device;
 	}
 	ipd->pdev = pdev;
+	ipd->var = var;
 
 	/*
 	 * Map all IOC3 registers.  These are shared between subdevices
 	 * so the main IOC3 module manages them.
 	 */
-	regs = pci_ioremap_bar(pdev, 0);
-	if (!regs) {
+	base = pci_ioremap_bar(pdev, 0);
+	if (!base) {
 		dev_warn(&pdev->dev, "ioc3: Unable to remap PCI BAR for %s.\n",
 			 pci_name(pdev));
 		ret = -ENOMEM;
 		goto out_disable_device;
 	}
-	ipd->regs = regs;
+	ipd->base = base;
 
 	/* Track PCI-device specific data */
 	pci_set_drvdata(pdev, ipd);
 
-	ret = ioc3_setup(ipd);
+	/* Clear IRQs */
+	for (i = 0; i < var->nr_banks; i++) {
+		writel(~0, base + var->banks[i].iec);
+		writel(~0, base + var->banks[i].ir);
+	}
+
+	ret = var->setup(ipd);
 	if (ret) {
 		/* Remove all already added MFD devices */
 		mfd_remove_devices(&ipd->pdev->dev);
@@ -619,7 +678,7 @@ static int ioc3_mfd_probe(struct pci_dev *pdev,
 			irq_domain_free_fwnode(fn);
 			free_irq(ipd->domain_irq, (void *)ipd);
 		}
-		pci_iounmap(pdev, regs);
+		pci_iounmap(pdev, base);
 		goto out_disable_device;
 	}
 
@@ -633,12 +692,15 @@ static int ioc3_mfd_probe(struct pci_dev *pdev,
 static void ioc3_mfd_remove(struct pci_dev *pdev)
 {
 	struct ioc3_priv_data *ipd;
+	unsigned int i;
 
 	ipd = pci_get_drvdata(pdev);
 
 	/* Clear and disable all IRQs */
-	writel(~0, &ipd->regs->sio_iec);
-	writel(~0, &ipd->regs->sio_ir);
+	for (i = 0; i < ipd->var->nr_banks; i++) {
+		writel(~0, ipd->base + ipd->var->banks[i].iec);
+		writel(~0, ipd->base + ipd->var->banks[i].ir);
+	}
 
 	/* Release resources */
 	mfd_remove_devices(&ipd->pdev->dev);
@@ -649,12 +711,183 @@ static void ioc3_mfd_remove(struct pci_dev *pdev)
 		irq_domain_free_fwnode(fn);
 		free_irq(ipd->domain_irq, (void *)ipd);
 	}
-	pci_iounmap(pdev, ipd->regs);
+	pci_iounmap(pdev, ipd->base);
 	pci_disable_device(pdev);
 }
 
+static const struct ioc3_irq_bank ioc3_irq_banks[] = {
+	{
+		.ir = offsetof(struct ioc3, sio_ir),
+		.ies = offsetof(struct ioc3, sio_ies),
+		.iec = offsetof(struct ioc3, sio_iec),
+		.lvl_mask = IOC3_LVL_MASK,
+	},
+};
+
+static const struct ioc3_variant ioc3_variant = {
+	.name = "IOC3",
+	.chip = &ioc3_irq_chip,
+	.banks = ioc3_irq_banks,
+	.nr_banks = ARRAY_SIZE(ioc3_irq_banks),
+	.nr_irqs = 24,
+	.setup = ioc3_setup,
+};
+
+#define IOC4_NUM_PORTS		4
+#define IOC4_SERIAL_MIN_REV	62
+
+/* hwirqs 0-31 are sio_ir's, 32-63 other_ir's. */
+#define IOC4_IRQ_OTHER_BASE	32
+#define IOC4_NUM_IRQS		64
+
+/* In sio_ir only the four UART pass-through bits are level triggered. */
+#define IOC4_LVL_MASK \
+	(IOC4_SIO_IR_PORT_INT(0) | IOC4_SIO_IR_PORT_INT(1) | \
+	 IOC4_SIO_IR_PORT_INT(2) | IOC4_SIO_IR_PORT_INT(3))
+
+#define IOC4_UART_RES(port) {						\
+	DEFINE_RES_MEM(offsetof(struct ioc4, uart[port]),		\
+		       sizeof_field(struct ioc4, uart[port])),		\
+	DEFINE_RES_IRQ(IOC4_SIO_IR_PORT_INT_BIT(port)),			\
+}
+
+static const struct resource ioc4_uart_resources[][2] = {
+	IOC4_UART_RES(0),
+	IOC4_UART_RES(1),
+	IOC4_UART_RES(2),
+	IOC4_UART_RES(3),
+};
+
+static const struct resource ioc4_kbd_resources[] = {
+	DEFINE_RES_MEM(offsetof(struct ioc4, serio),
+		       sizeof_field(struct ioc4, serio)),
+	DEFINE_RES_IRQ(IOC4_IRQ_OTHER_BASE + IOC4_OTHER_IR_KBD_INT_BIT)
+};
+
+static const struct resource ioc4_rtc_resources[] = {
+	DEFINE_RES_MEM(IOC4_BYTEBUS_DEV0, M48T35_REG_SIZE)
+};
+
+static const struct ioc3_serial8250_platform_data ioc4_serial_pdata = {
+	.uartclk = IOC4_UARTCLK,
+};
+
+#define IOC4_SERIAL_CELL(port) {					\
+	.name = "ioc3-serial8250",					\
+	.resources = ioc4_uart_resources[port],				\
+	.num_resources = ARRAY_SIZE(ioc4_uart_resources[port]),		\
+	.platform_data = &ioc4_serial_pdata,				\
+	.pdata_size = sizeof(ioc4_serial_pdata),			\
+}
+
+static const struct mfd_cell ioc4_serial_cells[] = {
+	IOC4_SERIAL_CELL(0),
+	IOC4_SERIAL_CELL(1),
+	IOC4_SERIAL_CELL(2),
+	IOC4_SERIAL_CELL(3),
+};
+
+static const struct mfd_cell ioc4_cells[] = {
+	{
+		.name = "ioc3-kbd",
+		.resources = ioc4_kbd_resources,
+		.num_resources = ARRAY_SIZE(ioc4_kbd_resources),
+	},
+	{
+		.name = "rtc-m48t35-ip35",
+		.resources = ioc4_rtc_resources,
+		.num_resources = ARRAY_SIZE(ioc4_rtc_resources),
+	},
+};
+
+static int ioc4_serial_setup(struct ioc3_priv_data *ipd)
+{
+	struct ioc4 __iomem *regs = ipd->base;
+	int ret, i;
+
+	if (ipd->pdev->revision < IOC4_SERIAL_MIN_REV) {
+		dev_warn(&ipd->pdev->dev,
+			 "serial ports need IOC4 firmware revision %u or later\n",
+			 IOC4_SERIAL_MIN_REV);
+		return 0;
+	}
+
+	/* Set gpio pins for RS232/RS422 mode selection */
+	writel(IOC4_GPCR_UART_MODESEL(0) | IOC4_GPCR_UART_MODESEL(1) |
+	       IOC4_GPCR_UART_MODESEL(2) | IOC4_GPCR_UART_MODESEL(3),
+	       &regs->gpcr_s);
+
+	for (i = 0; i < IOC4_NUM_PORTS; i++) {
+		/* Select RS232 mode, and switch the port to 16650 mode */
+		writel(0, &regs->gppr[IOC4_GPPR_UART_MODESEL_PIN(i)]);
+		writel(readl(&regs->port[i].sscr) & ~IOC4_SSCR_DMA_EN,
+		       &regs->port[i].sscr);
+	}
+	udelay(1000); /* Wait until mode switch is done */
+
+	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
+			      ioc4_serial_cells, ARRAY_SIZE(ioc4_serial_cells),
+			      &ipd->pdev->resource[0], 0, ipd->domain);
+	if (ret)
+		dev_err(&ipd->pdev->dev, "Failed to add 16550 subdevs\n");
+
+	return ret;
+}
+
+static int ioc4_setup(struct ioc3_priv_data *ipd)
+{
+	int ret;
+
+	dev_info(&ipd->pdev->dev, "IOC4 firmware revision %u\n",
+		 ipd->pdev->revision);
+
+	ret = ioc3_irq_domain_setup(ipd, ipd->pdev->irq);
+	if (ret)
+		return ret;
+
+	ret = ioc4_serial_setup(ipd);
+	if (ret)
+		return ret;
+
+	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
+			      ioc4_cells, ARRAY_SIZE(ioc4_cells),
+			      &ipd->pdev->resource[0], 0, ipd->domain);
+	if (ret)
+		dev_err(&ipd->pdev->dev, "Failed to add IOC4 subdevs\n");
+
+	return ret;
+}
+
+static const struct ioc3_irq_bank ioc4_irq_banks[] = {
+	{
+		.ir = offsetof(struct ioc4, sio_ir),
+		.ies = offsetof(struct ioc4, sio_ies),
+		.iec = offsetof(struct ioc4, sio_iec),
+		.lvl_mask = IOC4_LVL_MASK,
+	},
+	{
+		.ir = offsetof(struct ioc4, other_ir),
+		.ies = offsetof(struct ioc4, other_ies),
+		.iec = offsetof(struct ioc4, other_iec),
+	},
+};
+
+static const struct ioc3_variant ioc4_variant = {
+	.name = "IOC4",
+	.chip = &ioc4_irq_chip,
+	.banks = ioc4_irq_banks,
+	.nr_banks = ARRAY_SIZE(ioc4_irq_banks),
+	.nr_irqs = IOC4_NUM_IRQS,
+	/* Parity and SERR# reporting, as the SN2 IOC4 core enabled them. */
+	.pci_command = PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
+	.setup = ioc4_setup,
+};
+
 static struct pci_device_id ioc3_mfd_id_table[] = {
-	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, (kernel_ulong_t)&ioc3_variant },
+	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, (kernel_ulong_t)&ioc4_variant },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, ioc3_mfd_id_table);
@@ -669,5 +902,5 @@ static struct pci_driver ioc3_mfd_driver = {
 module_pci_driver(ioc3_mfd_driver);
 
 MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
-MODULE_DESCRIPTION("SGI IOC3 MFD driver");
+MODULE_DESCRIPTION("SGI IOC3/IOC4 MFD driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/tty/serial/8250/8250_ioc3.c b/drivers/tty/serial/8250/8250_ioc3.c
index 28e28076782b..5d3c0190f19e 100644
--- a/drivers/tty/serial/8250/8250_ioc3.c
+++ b/drivers/tty/serial/8250/8250_ioc3.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <linux/platform_data/sgi-ioc3-serial.h>
 #include <linux/platform_device.h>
 
 #include "8250.h"
@@ -33,6 +34,7 @@ static void ioc3_serial_out(struct uart_port *p, unsigned int offset, u32 value)
 
 static int serial8250_ioc3_probe(struct platform_device *pdev)
 {
+	const struct ioc3_serial8250_platform_data *pdata;
 	struct ioc3_8250_data *data;
 	struct uart_8250_port up;
 	struct resource *r;
@@ -56,9 +58,10 @@ static int serial8250_ioc3_probe(struct platform_device *pdev)
 		irq = 0; /* no interrupt -> use polling */
 
 	/* Register serial ports with 8250.c */
+	pdata = dev_get_platdata(&pdev->dev);
 	memset(&up, 0, sizeof(struct uart_8250_port));
 	up.port.iotype = UPIO_MEM;
-	up.port.uartclk = IOC3_UARTCLK;
+	up.port.uartclk = pdata ? pdata->uartclk : IOC3_UARTCLK;
 	up.port.type = PORT_16550A;
 	up.port.irq = irq;
 	up.port.flags = (UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ);
diff --git a/include/linux/platform_data/sgi-ioc3-serial.h b/include/linux/platform_data/sgi-ioc3-serial.h
new file mode 100644
index 000000000000..ae4690f33125
--- /dev/null
+++ b/include/linux/platform_data/sgi-ioc3-serial.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * SGI IOC3/IOC4 8250-compatible UART cells
+ */
+
+#ifndef PLATFORM_DATA_SGI_IOC3_SERIAL_H
+#define PLATFORM_DATA_SGI_IOC3_SERIAL_H
+
+struct ioc3_serial8250_platform_data {
+	unsigned int uartclk;
+};
+
+#endif /* PLATFORM_DATA_SGI_IOC3_SERIAL_H */
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines
  2026-10-13 13:16 [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Imre Kaloz
  2026-10-13 13:16 ` [PATCH v2 31/53] mfd: ioc3: Add support for IOC4 Imre Kaloz
@ 2026-10-13 13:35 ` Niklas Cassel
  2026-10-13 14:25   ` Imre Kaloz
  1 sibling, 1 reply; 4+ messages in thread
From: Niklas Cassel @ 2026-10-13 13:35 UTC (permalink / raw)
  To: Imre Kaloz
  Cc: Thomas Bogendoerfer, linux-mips, linux-kernel, Lee Jones,
	Greg Kroah-Hartman, Jiri Slaby, mfd, linux-serial,
	Alexandre Belloni, linux-rtc, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Damien Le Moal,
	linux-ide, Pavel Machek, linux-leds, Bjorn Helgaas, linux-pci,
	Christoph Hellwig

Hello Imre,

This series is rather large.

I would recommend you to submit a minimal patch series
to get the basic support for your new board, such that
it can boot with a ramdisk and serial console.

Then in the next cycle, send separate series for ata,
net, leds, mfc, rtc, etc.


Kind regards,
Niklas

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines
  2026-10-13 13:35 ` [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Niklas Cassel
@ 2026-10-13 14:25   ` Imre Kaloz
  0 siblings, 0 replies; 4+ messages in thread
From: Imre Kaloz @ 2026-10-13 14:25 UTC (permalink / raw)
  To: Niklas Cassel
  Cc: Thomas Bogendoerfer, linux-mips, linux-kernel, Lee Jones,
	Greg Kroah-Hartman, Jiri Slaby, mfd, linux-serial,
	Alexandre Belloni, linux-rtc, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Damien Le Moal,
	linux-ide, Pavel Machek, linux-leds, Bjorn Helgaas, linux-pci,
	Christoph Hellwig

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

Hello Niklas,

On Tue, 13 Oct 2026, Niklas Cassel wrote:

> Hello Imre,
>
> This series is rather large.
>
> I would recommend you to submit a minimal patch series
> to get the basic support for your new board, such that
> it can boot with a ramdisk and serial console.
>
> Then in the next cycle, send separate series for ata,
> net, leds, mfc, rtc, etc.

Hi Niklas,

Thanks for having a look. I checked what the minimum is: 31 of the 53 
patches (1, 6-24, 26-29, 31-36 and 39) boot a Tezro to a ramdisk with a 
serial console. Two mfd/ioc3 patches have to be part of that, as they 
provide the console UARTs (31 for IOC4 on the Tezro, 36 for the IOC3 on 
the Fuel). The rest separates cleanly into follow-ups: the remaining 
Bridge fixes (2-5), ioc3-eth (25, 38), rtc (30), the IO8 serial IRQs (37), 
machine identification and the Odyssey widget (40-44), ata (45-47, 49), 
the defconfig refresh (48) and the LEDs (50-53).

I’ll wait for Thomas to say whether he prefers it split that way for v3.


Thanks,
Imre

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-13 14:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 13:16 [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Imre Kaloz
2026-10-13 13:16 ` [PATCH v2 31/53] mfd: ioc3: Add support for IOC4 Imre Kaloz
2026-10-13 13:35 ` [PATCH v2 00/53] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Niklas Cassel
2026-10-13 14:25   ` Imre Kaloz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox