mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Imre Kaloz <kaloz@kernel.org>
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 30/38] MIPS: PCI: xtalk-bridge: take the board part number from the L1
Date: Thu,  1 Oct 2026 18:12:05 +0200	[thread overview]
Message-ID: <e8aa94c609966bfea8dd95d6636db5110cc75aab.1790857966.git.kaloz@kernel.org> (raw)
In-Reply-To: <cover.1790857966.git.kaloz@kernel.org>

An XBridge answers nothing on the b_nic 1-wire pin, so
bridge_get_partnum() finds no PROM and the probe defers forever. Stop
waiting on XBridge and PIC widgets; on Bedrock hubs read the assembly
number from the L1 instead.

Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
 arch/mips/include/asm/sn/l1.h    |  7 +++
 arch/mips/pci/pci-xtalk-bridge.c | 37 +++++++++++++-
 arch/mips/sgi-ip27/ip27-l1.c     | 83 ++++++++++++++++++++++++++++++++
 3 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/sn/l1.h b/arch/mips/include/asm/sn/l1.h
index e61935e2fac8..1a3b7fa0e213 100644
--- a/arch/mips/include/asm/sn/l1.h
+++ b/arch/mips/include/asm/sn/l1.h
@@ -9,6 +9,13 @@
 
 #include <linux/types.h>
 
+/*
+ * Which L1 EEPROM component id carries which board is undocumented and
+ * differs from machine to machine, so a caller walks the whole range.
+ */
+#define L1_BOARD_COMPONENT_MAX	8
+
 int l1_exec_command(const char *cmd);
+int l1_read_board_partnum(unsigned int component, char *buf, size_t len);
 
 #endif /* __ASM_SN_L1_H */
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index 35ae7c423973..c97533653ef6 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -18,7 +18,9 @@
 #include <asm/pci/bridge.h>
 #include <asm/paccess.h>
 #include <asm/sn/irq_alloc.h>
+#include <asm/sn/addrs.h>
 #include <asm/sn/ioc3.h>
+#include <asm/sn/l1.h>
 
 #define CRC16_INIT	0
 #define CRC16_VALID	0xb001
@@ -583,6 +585,29 @@ static const struct {
 	BRIDGE_BOARD_SETUP("030-1707-", bridge_setup_ip34_fuel_sysboard),
 };
 
+/*
+ * The L1 answers one board information area per EEPROM component id, and
+ * which id carries which board is undocumented. Ask for each in turn and take
+ * the first answer the table above knows.
+ */
+static int bridge_l1_partnum(char *partnum, size_t len)
+{
+	unsigned int component;
+	int i;
+
+	for (component = 0; component < L1_BOARD_COMPONENT_MAX; component++) {
+		if (l1_read_board_partnum(component, partnum, len))
+			continue;
+
+		for (i = 0; i < ARRAY_SIZE(bridge_ioc3_devid); i++)
+			if (!strncmp(partnum, bridge_ioc3_devid[i].match,
+				     strlen(bridge_ioc3_devid[i].match)))
+				return 0;
+	}
+
+	return -ENODEV;
+}
+
 static void bridge_setup_board(struct bridge_controller *bc, char *partnum)
 {
 	int i;
@@ -657,8 +682,16 @@ static int bridge_probe(struct platform_device *pdev)
 	int err;
 
 	/* get part number from one wire prom */
-	if (bridge_get_partnum(virt_to_phys((void *)bd->bridge_addr), partnum))
-		return -EPROBE_DEFER; /* not available yet */
+	if (bridge_get_partnum(virt_to_phys((void *)bd->bridge_addr),
+			       partnum)) {
+		/* Only a classic Bridge waits for its 1-wire PROM. */
+		if (!bd->is_xbridge && !bd->is_pic)
+			return -EPROBE_DEFER; /* not available yet */
+
+		if (!IS_ENABLED(CONFIG_SGI_IP27) || !system_is_ip35 ||
+		    bridge_l1_partnum(partnum, sizeof(partnum)))
+			partnum[0] = '\0';
+	}
 
 	parent = irq_get_default_domain();
 	if (!parent)
diff --git a/arch/mips/sgi-ip27/ip27-l1.c b/arch/mips/sgi-ip27/ip27-l1.c
index 25f9be350c0b..173a506595da 100644
--- a/arch/mips/sgi-ip27/ip27-l1.c
+++ b/arch/mips/sgi-ip27/ip27-l1.c
@@ -650,6 +650,89 @@ static int l1_get_brick_ethernet_address(nasid_t nasid, u8 *enaddr)
 	return is_valid_ether_addr(enaddr) ? 0 : -EINVAL;
 }
 
+/*
+ * The L1 stores SGI assembly numbers with underscores where the printed
+ * form has dashes: "030_1707_003" for "030-1707-003".
+ */
+static int l1_get_board_partnum(nasid_t nasid, unsigned int component,
+				char *buf, size_t len)
+{
+	size_t iapos, ialen, fieldlen, i;
+	u8 *ia;
+	int rc;
+
+	rc = l1_read_board_ia(nasid, L1_TYPE_L1, component, &ia, &ialen);
+	if (rc)
+		return rc;
+
+	if (ia[1] < 2 || ia[1] * 8UL > ialen)
+		return -EINVAL;
+
+	/* skip the fixed part, then mfg, product, serial */
+	iapos = 6;
+	iapos = ia_skip(ia, iapos, ialen);
+	iapos = ia_skip(ia, iapos, ialen);
+	iapos = ia_skip(ia, iapos, ialen);
+
+	if (iapos >= ialen || (ia[iapos] >> IA_TYPE_SHIFT) != IA_TYPE_ASCII)
+		return -EINVAL;
+
+	fieldlen = ia[iapos] & IA_LENGTH_MASK;
+	if (fieldlen == 0 || iapos + 1 + fieldlen > ialen || fieldlen >= len)
+		return -EINVAL;
+
+	iapos++;
+	for (i = 0; i < fieldlen; i++)
+		buf[i] = ia[iapos + i] == '_' ? '-' : ia[iapos + i];
+	buf[fieldlen] = '\0';
+
+	return 0;
+}
+
+/*
+ * Part numbers cannot change at runtime, so failures are cached along
+ * with successes and each component is queried once.
+ */
+#define L1_PARTNUM_SIZE		24
+static char l1_partnum[L1_BOARD_COMPONENT_MAX][L1_PARTNUM_SIZE];
+static int l1_partnum_rc[L1_BOARD_COMPONENT_MAX];
+static bool l1_partnum_cached[L1_BOARD_COMPONENT_MAX];
+
+int l1_read_board_partnum(unsigned int component, char *buf, size_t len)
+{
+	unsigned long flags;
+
+	if (component >= L1_BOARD_COMPONENT_MAX)
+		return -EINVAL;
+
+	spin_lock_irqsave(&l1_lock, flags);
+
+	if (!l1_partnum_cached[component]) {
+		l1_partnum_rc[component] =
+			l1_get_board_partnum(get_nasid(), component,
+					     l1_partnum[component],
+					     sizeof(l1_partnum[component]));
+		l1_partnum_cached[component] = true;
+
+		if (l1_partnum_rc[component])
+			pr_debug("l1: component %u: no part number (%d)\n",
+				 component, l1_partnum_rc[component]);
+		else
+			pr_debug("l1: component %u: part number %s\n",
+				 component, l1_partnum[component]);
+	}
+
+	spin_unlock_irqrestore(&l1_lock, flags);
+
+	if (l1_partnum_rc[component])
+		return l1_partnum_rc[component];
+
+	if (strscpy(buf, l1_partnum[component], len) < 0)
+		return -E2BIG;
+
+	return 0;
+}
+
 static u8 ip27_l1_mac_addr[ETH_ALEN];
 static bool ip27_l1_mac_addr_valid;
 static bool ip27_l1_mac_addr_tried;
-- 
2.47.3


  parent reply	other threads:[~2026-10-01 16:14 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01 16:11 [PATCH 00/38] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Imre Kaloz
2026-10-01 16:11 ` [PATCH 01/38] MIPS: Xtalk: guard the widget identification table from assembly Imre Kaloz
2026-10-01 16:11 ` [PATCH 02/38] MIPS: SGI-IP27: dump the NMI save areas the CPU scan recorded Imre Kaloz
2026-10-01 16:11 ` [PATCH 03/38] MIPS: SGI-IP27: add REMOTE_HUB_PI_S()/REMOTE_HUB_PI_L() Imre Kaloz
2026-10-01 16:11 ` [PATCH 04/38] MIPS: SGI-IP27: detect Bedrock hubs at boot Imre Kaloz
2026-10-01 16:11 ` [PATCH 05/38] MIPS: SGI-IP27: widen Kconfig for the Bedrock-based machines Imre Kaloz
2026-10-01 16:11 ` [PATCH 06/38] MIPS: SGI-IP27: fold the dead SN1 arm out of klconfig.h Imre Kaloz
2026-10-01 16:11 ` [PATCH 07/38] MIPS: SGI-IP27: choose the node address layout at runtime Imre Kaloz
2026-10-01 16:11 ` [PATCH 08/38] MIPS: SGI-IP27: add the Bedrock hub register windows Imre Kaloz
2026-10-01 16:11 ` [PATCH 09/38] MIPS: SGI-IP27: decode a Bedrock hub's node id and system size Imre Kaloz
2026-10-01 16:11 ` [PATCH 10/38] MIPS: SGI-IP27: put a Bedrock hub's boot CPU in slot 0 Imre Kaloz
2026-10-01 16:11 ` [PATCH 11/38] MIPS: SGI-IP27: lay out node memory in 1GB banks on Bedrock hubs Imre Kaloz
2026-10-01 16:11 ` [PATCH 12/38] MIPS: SGI-IP27: reserve the bottom 64MB of node 0 " Imre Kaloz
2026-10-01 16:11 ` [PATCH 13/38] MIPS: SGI-IP27: route interrupt masks and slices through both PIs Imre Kaloz
2026-10-01 16:11 ` [PATCH 14/38] MIPS: SGI-IP27: address a CPU's own PI for NMI, IPI and RT counter Imre Kaloz
2026-10-01 16:11 ` [PATCH 15/38] MIPS: SGI-IP27: take a CPU's node from the CPU table in per_cpu_init() Imre Kaloz
2026-10-01 16:11 ` [PATCH 16/38] MIPS: SGI-IP27: resolve the mapped-kernel node shift at runtime Imre Kaloz
2026-10-01 16:11 ` [PATCH 17/38] MIPS: SGI-IP27: load the kernel at node offset 0x40000 Imre Kaloz
2026-10-01 16:11 ` [PATCH 18/38] MIPS: SGI-IP27: xbow_probe(): recognize KLTYPE_PBRICK_XBOW Imre Kaloz
2026-10-01 16:11 ` [PATCH 19/38] MIPS: ip27_defconfig: enable the IOC3 MFD, its cell drivers and tg3 Imre Kaloz
2026-10-01 16:11 ` [PATCH 20/38] net: ethernet: sgi: ioc3-eth: apply the DMA attributes only to 64-bit addresses Imre Kaloz
2026-10-01 16:11 ` [PATCH 21/38] MIPS: SGI-IP27: route XBridge and PIC DMA through the 32-bit window Imre Kaloz
2026-10-05  8:39   ` Christoph Hellwig
2026-10-05 13:15     ` Imre Kaloz
2026-10-01 16:11 ` [PATCH 22/38] MIPS: SGI-IP27: recognize the PXBow crossbar Imre Kaloz
2026-10-01 16:11 ` [PATCH 23/38] MIPS: PCI: xtalk-bridge: recognize the PIC widget's 64-bit-only registers Imre Kaloz
2026-10-01 16:11 ` [PATCH 24/38] MIPS: PCI: xtalk-bridge: match PIC's register-level differences Imre Kaloz
2026-10-01 16:12 ` [PATCH 25/38] rtc: m48t35: support the SGI IP35 timekeeper's 1968 year base Imre Kaloz
2026-10-01 16:12 ` [PATCH 26/38] mfd: ioc3: add support for IOC4 Imre Kaloz
2026-10-01 16:12 ` [PATCH 27/38] MIPS: SGI-IP27: dispatch the early console between IOC3 and IOC4 Imre Kaloz
2026-10-01 16:12 ` [PATCH 28/38] MIPS: SGI-IP27: add L1 system controller support Imre Kaloz
2026-10-01 16:12 ` [PATCH 29/38] MIPS: SGI-IP27: wire the L1 into reset and the Ethernet address Imre Kaloz
2026-10-01 16:12 ` Imre Kaloz [this message]
2026-10-01 16:12 ` [PATCH 31/38] mfd: ioc3: add IP34 system-board entry to ioc3_infos[] Imre Kaloz
2026-10-02 10:02   ` Lee Jones
2026-10-02 10:29     ` Imre Kaloz
2026-10-01 16:12 ` [PATCH 32/38] net: ethernet: sgi: ioc3-eth: fall back to the platform MAC address Imre Kaloz
2026-10-01 16:12 ` [PATCH 33/38] MIPS: SGI-IP27: don't register a w1 master on an XBridge or PIC Imre Kaloz
2026-10-01 16:12 ` [PATCH 34/38] MIPS: SGI-IP27: report a Bedrock machine as SGI IP35 Imre Kaloz
2026-10-01 16:12 ` [PATCH 35/38] MIPS: SGI-IP27: identify the machine by the L1 brick type Imre Kaloz
2026-10-01 16:12 ` [PATCH 36/38] MIPS: SGI-IP27: register the Odyssey graphics widget Imre Kaloz
2026-10-01 16:12 ` [PATCH 37/38] MIPS: SGI-IP27: take the console from the KLCONFIG header on IP35 Imre Kaloz
2026-10-01 16:12 ` [PATCH 38/38] MIPS: SGI-IP27: give each CPU its own topology package id Imre Kaloz
2026-10-02 15:46 ` [PATCH 00/38] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Thomas Bogendoerfer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e8aa94c609966bfea8dd95d6636db5110cc75aab.1790857966.git.kaloz@kernel.org \
    --to=kaloz@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=tsbogend@alpha.franken.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®