? arch/sparc64/sparc64/autoconf.c.u45
? arch/sparc64/sparc64/cpu.c.sysctl
Index: dev/i2c/pcf8574.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/pcf8574.c,v
retrieving revision 1.2
diff -u -r1.2 pcf8574.c
--- dev/i2c/pcf8574.c	31 Oct 2020 14:39:31 -0000	1.2
+++ dev/i2c/pcf8574.c	14 Nov 2020 09:44:42 -0000
@@ -1,3 +1,5 @@
+/* $NetBSD$ */
+
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -106,10 +108,22 @@
 pcf8574_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+        struct pcf8574_softc sc;        /* For chip ident */
+
 	int match_result;
 
-	if (iic_use_direct_match(ia, cf, compat_data, &match_result))
-		return match_result;
+	if (!iic_use_direct_match(ia, cf, compat_data, &match_result))
+		return 0;
+
+	/* OFW might show an optional component as present, so try a read */
+	if (match_result) {
+        	sc.sc_tag = ia->ia_tag;
+        	sc.sc_addr = ia->ia_addr;
+		if (pcf8574_read(&sc, &sc.sc_state))
+			return 0;
+		else
+			return 1;
+	}
 
 	/* We don't support indirect matches */
 	return 0;
Index: arch/sparc64/sparc64/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/autoconf.c,v
retrieving revision 1.227
diff -u -r1.227 autoconf.c
--- arch/sparc64/sparc64/autoconf.c	29 Oct 2020 06:47:38 -0000	1.227
+++ arch/sparc64/sparc64/autoconf.c	14 Nov 2020 09:44:43 -0000
@@ -1090,10 +1090,11 @@
 			}
 		} 
 		if (device_is_a(dev, "pcf8574io")) {
-			if (!strcmp(machine_model, "SUNW,Ultra-250")) {
+			if (!strcmp(machine_model, "SUNW,Ultra-250"))
 				add_gpio_props_e250(dev, aux);
-			}
-		} 
+			if (!strcmp(machine_model, "SUNW,Ultra-4"))
+				add_gpio_props_e450(dev, aux);
+		}
 	} else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) {
 		struct scsipibus_attach_args *sa = aux;
 		struct scsipi_periph *periph = sa->sa_periph;
Index: arch/sparc64/sparc64/ofw_patch.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/ofw_patch.c,v
retrieving revision 1.6
diff -u -r1.6 ofw_patch.c
--- arch/sparc64/sparc64/ofw_patch.c	29 Oct 2020 06:47:38 -0000	1.6
+++ arch/sparc64/sparc64/ofw_patch.c	14 Nov 2020 09:44:43 -0000
@@ -134,6 +134,8 @@
 	prop_array_t pins;
 
 	switch (ia->ia_addr) {
+		case 0x38:	/* interrupt status */
+			break;
 		case 0x39:	/* PSU status */
 			pins = prop_array_create();
 			add_gpio_pin(pins, "INDICATOR psu0_present", 0, 0, -1);
@@ -160,7 +162,7 @@
 			prop_dictionary_set(dict, "pins", pins);
 			prop_object_release(pins);
 			break;
-		case 0x3e:	/* front panel LEDs */
+		case 0x3e:	/* front panel LEDs (E250/E450) */
 			pins = prop_array_create();
 			add_gpio_pin(pins, "LED disk_fault", 0, 0, -1);
 			add_gpio_pin(pins, "LED psu_fault", 1, 0, -1);
@@ -189,6 +191,96 @@
 }
 
 void
+add_gpio_props_e450(device_t dev, void *aux)
+{
+	struct i2c_attach_args *ia = aux;
+	prop_dictionary_t dict = device_properties(dev);
+	prop_array_t pins;
+	char name[20];
+	int i;
+
+	switch (ia->ia_addr) {
+		case 0x20:	/* disk shelf 0 */
+			pins = prop_array_create();
+			for (i = 0; i < 4; i++) {
+				snprintf(name, sizeof(name),
+					"LED disk%d_fault", i);
+				add_gpio_pin(pins, name, i, 0, -1);
+			}
+			break;
+		case 0x21:	/* disk shelf 1 */
+			pins = prop_array_create();
+			for (i = 0; i < 8; i++) {
+				snprintf(name, sizeof(name),
+					"LED disk%d_fault", i + 4);
+				add_gpio_pin(pins, name, i, 0, -1);
+			}
+			break;
+		case 0x22:	/* disk shelf 2 */
+			pins = prop_array_create();
+			for (i = 0; i < 8; i++) {
+				snprintf(name, sizeof(name),
+					"LED disk%d_fault", i + 12);
+				add_gpio_pin(pins, name, i, 0, -1);
+			}
+			break;
+		case 0x38:	/* interrupt status */
+			break;
+		case 0x39:	/* PSU 2 status */
+			pins = prop_array_create();
+			add_gpio_pin(pins, "INDICATOR psu2_present", 0, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu2_550W", 1, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu2_650W", 2, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu2_DC_fault", 3, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu2_overload", 4, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu2_load_flt", 5, 0, -1);
+			break;
+		case 0x3a:	/* PSU 1 status */
+			pins = prop_array_create();
+			add_gpio_pin(pins, "INDICATOR psu1_present", 0, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu1_550W", 1, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu1_650W", 2, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu1_DC_fault", 3, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu1_overload", 4, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu1_load_flt", 5, 0, -1);
+			break;
+		case 0x3b:	/* PSU 0 status */
+			pins = prop_array_create();
+			add_gpio_pin(pins, "INDICATOR psu0_present", 0, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu0_550W", 1, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu0_650W", 2, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu0_DC_fault", 3, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu0_overload", 4, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu0_load_flt", 5, 0, -1);
+			break;
+		case 0x3c:	/* fan failure status */
+			pins = prop_array_create();
+			add_gpio_pin(pins, "INDICATOR psu2_fanfail", 0, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu1_fanfail", 1, 0, -1);
+			add_gpio_pin(pins, "INDICATOR psu0_fanfail", 2, 0, -1);
+			add_gpio_pin(pins, "INDICATOR cpu0_fanfail", 3, 0, -1);
+			add_gpio_pin(pins, "INDICATOR cpu1_fanfail", 4, 0, -1);
+			add_gpio_pin(pins, "INDICATOR cpu2_fanfail", 5, 0, -1);
+			add_gpio_pin(pins, "INDICATOR afb_fanfail", 6, 0, -1);
+			break;
+		case 0x3e:	/* front panel LEDs (E250/E450) */
+			pins = prop_array_create();
+			add_gpio_pin(pins, "LED disk_fault", 0, 0, -1);
+			add_gpio_pin(pins, "LED psu_fault", 1, 0, -1);
+			add_gpio_pin(pins, "LED overtemp", 2, 0, -1);
+			add_gpio_pin(pins, "LED fault", 3, 0, -1);
+			add_gpio_pin(pins, "LED activity", 4, 0, -1);
+			/* Pin 5 is power LED, but not controllable */
+			add_gpio_pin(pins, "INDICATOR key_normal", 6, 0, -1);
+			add_gpio_pin(pins, "INDICATOR key_diag", 7, 0, -1);
+			/* If not "normal" or "diag", key is "lock" */
+			prop_dictionary_set(dict, "pins", pins);
+			prop_object_release(pins);
+			break;
+	}
+}
+
+void
 add_drivebay_props(device_t dev, int ofnode, void *aux)
 {
 	struct scsipibus_attach_args *sa = aux;
@@ -275,10 +367,23 @@
 add_i2c_props_e450(device_t busdev, uint64_t node)
 {
 	prop_array_t cfg;
+	int i;
 
 	DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model));
 	cfg = create_i2c_dict(busdev);
 
+	/* Disk LED GPIO's */
+	for (i = 0x20; i <= 0x22; i++)
+		add_i2c_device(cfg, "gpio", "i2c-pcf8574", i, node);
+
+	/* TDA8444 fan speed controller */
+	add_i2c_device(cfg, "gpio", "fan-control", 0x27, node);
+
+	/* Other GPIO's */
+	for (i = 0x38; i <= 0x3c; i++)
+		add_i2c_device(cfg, "gpio", "i2c-pcf8574", i, node);
+	add_i2c_device(cfg, "gpio", "i2c-pcf8574", 0x3e, node);
+
 	/* Power supply 1 temperature. */
 	add_i2c_device(cfg, "PSU-1", "ecadc", 0x48, node);
 
@@ -294,6 +399,9 @@
 	/* CPU temperatures. */
 	add_i2c_device(cfg, "CPU", "ecadc", 0x4f, node);
 
+	/* Watchdog. */
+	add_i2c_device(cfg, "CPU", "watchdog", 0x50, node);
+
 	prop_object_release(cfg);
 }
 
@@ -306,18 +414,18 @@
 	DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model));
 	cfg = create_i2c_dict(busdev);
 
-	/* PSU temperature / CPU fan */
-	add_i2c_device(cfg, "PSU", "ecadc", 0x4a, node);
-
-	/* CPU & system board temperature */
-	add_i2c_device(cfg, "CPU", "ecadc", 0x4f, node);
-
 	/* GPIO's */
 	for (i = 0x38; i <= 0x39; i++)
 		add_i2c_device(cfg, "gpio", "i2c-pcf8574", i, node);
 	for (i = 0x3d; i <= 0x3f; i++)
 		add_i2c_device(cfg, "gpio", "i2c-pcf8574", i, node);
 
+	/* PSU temperature / CPU fan */
+	add_i2c_device(cfg, "PSU", "ecadc", 0x4a, node);
+
+	/* CPU & system board temperature */
+	add_i2c_device(cfg, "CPU", "ecadc", 0x4f, node);
+
 	/* NVRAM */
 	add_i2c_device(cfg, "nvram", "i2c-at24c02", 0x52, node);
 
Index: arch/sparc64/sparc64/ofw_patch.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/ofw_patch.h,v
retrieving revision 1.4
diff -u -r1.4 ofw_patch.h
--- arch/sparc64/sparc64/ofw_patch.h	29 Oct 2020 06:47:38 -0000	1.4
+++ arch/sparc64/sparc64/ofw_patch.h	14 Nov 2020 09:44:43 -0000
@@ -43,6 +43,7 @@
 
 void add_gpio_props_v210(device_t, void *);
 void add_gpio_props_e250(device_t, void *);
+void add_gpio_props_e450(device_t, void *);
 void add_drivebay_props(device_t, int, void *);
 void add_spdmem_props_sparcle(device_t);
 void add_env_sensors_v210(device_t);