Module Name:    src
Committed By:   thorpej
Date:           Sat Sep 11 01:03:18 UTC 2021

Modified Files:
        src/sys/arch/sandpoint/sandpoint [thorpej-i2c-spi-conf2]: autoconf.c
        src/sys/arch/sparc64/sparc64 [thorpej-i2c-spi-conf2]: ofw_patch.c
        src/sys/dev/i2c [thorpej-i2c-spi-conf2]: i2c.c i2cvar.h

Log Message:
Re-factor the code in sandpoint and sparc64 that enumerates a static
table of i2c device entries into something sharable.


To generate a diff of this commit:
cvs rdiff -u -r1.29.16.3 -r1.29.16.4 \
    src/sys/arch/sandpoint/sandpoint/autoconf.c
cvs rdiff -u -r1.7.14.2 -r1.7.14.3 src/sys/arch/sparc64/sparc64/ofw_patch.c
cvs rdiff -u -r1.80.2.5 -r1.80.2.6 src/sys/dev/i2c/i2c.c
cvs rdiff -u -r1.24.12.2 -r1.24.12.3 src/sys/dev/i2c/i2cvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sandpoint/sandpoint/autoconf.c
diff -u src/sys/arch/sandpoint/sandpoint/autoconf.c:1.29.16.3 src/sys/arch/sandpoint/sandpoint/autoconf.c:1.29.16.4
--- src/sys/arch/sandpoint/sandpoint/autoconf.c:1.29.16.3	Fri Sep 10 15:45:28 2021
+++ src/sys/arch/sandpoint/sandpoint/autoconf.c	Sat Sep 11 01:03:18 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.29.16.3 2021/09/10 15:45:28 thorpej Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.29.16.4 2021/09/11 01:03:18 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.29.16.3 2021/09/10 15:45:28 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.29.16.4 2021/09/11 01:03:18 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -58,54 +58,82 @@ static struct btinfo_net *bi_net;
 static struct btinfo_prodfamily *bi_pfam;
 static struct btinfo_model *bi_model;
 
-struct sandpoint_i2cdev {
-	const char *	name;
-	const char *	compat;
-	uint32_t	model_mask;
-	i2c_addr_t	addr;
+struct sandpoint_i2c_data {
+	const struct i2c_deventry *entries;
+	unsigned int               nentries;
+	uint32_t                   model_mask;
 };
 
-static const struct sandpoint_i2cdev dlink_i2cdevs[] = {
+static const struct i2c_deventry dlink_i2cdevs[] = {
 	{ .name = "strtc", .compat = "st,m41t80", .addr = 0x68, },
-	{ .name = NULL }
+};
+static const struct sandpoint_i2c_data dlink_i2cdata[] = {
+	{ .entries = dlink_i2cdevs,
+	  .nentries = __arraycount(dlink_i2cdevs), },
+	{ .entries = NULL },
 };
 
-static const struct sandpoint_i2cdev iomega_i2cdevs[] = {
+static const struct i2c_deventry iomega_i2cdevs[] = {
 	{ .name = "dsrtc", .compat = "dallas,ds1307", .addr = 0x68, },
-	{ .name = NULL }
+};
+static const struct sandpoint_i2c_data iomega_i2cdata[] = {
+	{ .entries = iomega_i2cdevs,
+	  .nentries = __arraycount(iomega_i2cdevs), },
+	{ .entries = NULL },
 };
 
-static const struct sandpoint_i2cdev kurobox_i2cdevs[] = {
+static const struct i2c_deventry kurobox_i2cdevs[] = {
 	{ .name = "rs5c372rtc", .compat = "ricoh,rs5c372a", .addr = 0x32, },
-	{ .name = NULL }
+};
+static const struct sandpoint_i2c_data kurobox_i2cdata[] = {
+	{ .entries = kurobox_i2cdevs,
+	  .nentries = __arraycount(kurobox_i2cdevs), },
+	{ .entries = NULL },
 };
 
-static const struct sandpoint_i2cdev nhnas_i2cdevs[] = {
+static const struct i2c_deventry nhnas_i2cdevs[] = {
 	{ .name = "pcf8563rtc", .compat = "nxp,pcf8563", .addr = 0x51, },
-	{ .name = NULL }
+};
+static const struct sandpoint_i2c_data nhnas_i2cdata[] = {
+	{ .entries = nhnas_i2cdevs,
+	  .nentries = __arraycount(nhnas_i2cdevs), },
+	{ .entries = NULL },
 };
 
-static const struct sandpoint_i2cdev qnap_i2cdevs[] = {
+static const struct i2c_deventry qnap_i2cdevs[] = {
 	{ .name = "s390rtc", .compat = "sii,s35390a", .addr = 0x30, },
-	{ .name = NULL }
+};
+static const struct sandpoint_i2c_data qnap_i2cdata[] = {
+	{ .entries = qnap_i2cdevs,
+	  .nentries = __arraycount(qnap_i2cdevs), },
+	{ .entries = NULL },
 };
 
-static const struct sandpoint_i2cdev synology_i2cdevs[] = {
+static const struct i2c_deventry synology_thermal_i2cdevs[] = {
+	{ .name = "rs5c372rtc", .compat = "ricoh,rs5c372a", .addr = 0x32, },
+	{ .name = "lmtemp", .compat = "national,lm75", .addr = 0x48, },
+};
+static const struct i2c_deventry synology_i2cdevs[] = {
 	{ .name = "rs5c372rtc", .compat = "ricoh,rs5c372a", .addr = 0x32, },
-	{ .name = "lmtemp", .compat = "national,lm75", .addr = 0x48,
-	   .model_mask = BI_MODEL_THERMAL, },
-	{ .name = NULL }
+};
+static const struct sandpoint_i2c_data synology_i2cdata[] = {
+	{ .entries = synology_thermal_i2cdevs,
+	  .nentries = __arraycount(synology_thermal_i2cdevs),
+	  .model_mask  = BI_MODEL_THERMAL, },
+	{ .entries = synology_i2cdevs,
+	  .nentries = __arraycount(synology_i2cdevs), },
+	{ .entries = NULL },
 };
 
 static const struct device_compatible_entry sandpoint_i2c_compat[] = {
-	{ .compat = "dlink",		.data = &dlink_i2cdevs },
-	{ .compat = "iomega",		.data = &iomega_i2cdevs },
-	{ .compat = "kurobox",		.data = &kurobox_i2cdevs },
+	{ .compat = "dlink",		.data = dlink_i2cdata },
+	{ .compat = "iomega",		.data = iomega_i2cdata },
+	{ .compat = "kurobox",		.data = kurobox_i2cdata },
 	/* kurot4 has same i2c devices as kurobox */
-	{ .compat = "kurot4",		.data = &kurobox_i2cdevs },
-	{ .compat = "nhnas",		.data = &nhnas_i2cdevs },
-	{ .compat = "qnap",		.data = &qnap_i2cdevs },
-	{ .compat = "synology",		.data = &synology_i2cdevs },
+	{ .compat = "kurot4",		.data = kurobox_i2cdata },
+	{ .compat = "nhnas",		.data = nhnas_i2cdata },
+	{ .compat = "qnap",		.data = qnap_i2cdata },
+	{ .compat = "synology",		.data = synology_i2cdata },
 	DEVICE_COMPAT_EOL
 };
 
@@ -115,10 +143,8 @@ static const struct device_compatible_en
 static int
 sandpoint_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
 {
-	struct i2c_enumerate_devices_args *args = v;
 	const struct device_compatible_entry *dce;
-	const struct sandpoint_i2cdev *i2cdev;
-	bool cbrv;
+	const struct sandpoint_i2c_data *data;
 
 	KASSERT(bi_pfam != NULL);
 
@@ -128,33 +154,27 @@ sandpoint_i2c_enumerate_devices(device_t
 		/* no i2c devices for this model. */
 		return 0;
 	}
-	i2cdev = dce->data;
-	KASSERT(i2cdev != NULL);
+	data = dce->data;
+	KASSERT(data != NULL);
 
-	for (; i2cdev->name != NULL; i2cdev++) {
-		if (i2cdev->model_mask != 0) {
-			KASSERT(bi_model != NULL);
-			if ((i2cdev->model_mask & bi_model->flags) == 0) {
-				/* skip this device. */
-				continue;
-			}
+	/* Filter by model_mask if necessary. */
+	for (; data->entries != NULL; data++) {
+		if (data->model_mask == 0) {
+			/* We'll use this one! */
+			break;
 		}
-
-		args->ia->ia_addr = i2cdev->addr;
-		args->ia->ia_name = i2cdev->name;
-		args->ia->ia_clist = i2cdev->compat;
-		args->ia->ia_clist_size = strlen(i2cdev->compat) + 1;
-		/* no devhandle for child devices. */
-		devhandle_invalidate(&args->ia->ia_devhandle);
-
-		cbrv = args->callback(dev, args);
-
-		if (!cbrv) {
+		if ((data->model_mask & bi_model->flags) == data->model_mask) {
+			/* We'll use this one! */
 			break;
 		}
 	}
+	if (data->entries == NULL) {
+		/* no i2c devies for this model. */
+		return 0;
+	}
 
-	return 0;
+	return i2c_enumerate_deventries(dev, call_handle, v,
+	    data->entries, data->nentries);
 }
 
 static device_call_t

Index: src/sys/arch/sparc64/sparc64/ofw_patch.c
diff -u src/sys/arch/sparc64/sparc64/ofw_patch.c:1.7.14.2 src/sys/arch/sparc64/sparc64/ofw_patch.c:1.7.14.3
--- src/sys/arch/sparc64/sparc64/ofw_patch.c:1.7.14.2	Fri Sep 10 15:45:28 2021
+++ src/sys/arch/sparc64/sparc64/ofw_patch.c	Sat Sep 11 01:03:18 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ofw_patch.c,v 1.7.14.2 2021/09/10 15:45:28 thorpej Exp $ */
+/*	$NetBSD: ofw_patch.c,v 1.7.14.3 2021/09/11 01:03:18 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2020, 2021 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ofw_patch.c,v 1.7.14.2 2021/09/10 15:45:28 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ofw_patch.c,v 1.7.14.3 2021/09/11 01:03:18 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -90,12 +90,11 @@ add_gpio_pins(device_t dev, const struct
  * On some systems, there are lots of i2c devices missing from the
  * device tree.
  *
- * The way we deal with this is by defining a devhandle_impl subclass
- * of the i2c controller's devhandle, create a new OF-type devhandle
- * with the new devhandle_impl, and stuff that into the controller
- * device's handle, which will then pass that handle on down to the iic bus
- * instance.  This devhandle_impl will implement "i2c-enumerate-devices",
- * and pass everything else along to the super.
+ * The way we deal with this is by subclassing the controller's
+ * devhandle_impl and overriding the "i2c-enumerate-devices" device
+ * call.  Our implementation will enumerate using the super-class
+ * (OpenFirmware enumeration), and then enumerate the missing entries
+ * from our own static tables.
  *
  * This devhandle_impl will be wrapped inside of a container structure
  * that will point to the extra devices that need to be added as children
@@ -104,18 +103,11 @@ add_gpio_pins(device_t dev, const struct
  * additions.
  */
 
-struct i2c_addition {
-	const char *name;
-	const char *compat;
-	i2c_addr_t addr;
-};
-
 struct i2c_fixup_container {
 	struct devhandle_impl i2c_devhandle_impl;
 	devhandle_t i2c_super_handle;
-	const struct i2c_addition *i2c_additions;
+	const struct i2c_deventry *i2c_additions;
 	int i2c_nadditions;
-	int i2c_phandle;
 };
 
 static int
@@ -128,46 +120,20 @@ i2c_fixup_enumerate_devices(device_t dev
 			 struct i2c_fixup_container, i2c_devhandle_impl);
 	devhandle_t super_handle = fixup->i2c_super_handle;
 	device_call_t super_call;
-	int error;
+	int super_error, error;
 
 	/* First, enumerate using whatever is in the device tree. */
 	super_call = devhandle_lookup_device_call(super_handle,
 	    "i2c-enumerate-devices", &super_handle);
-	if (super_call != NULL) {
-		error = super_call(dev, super_handle, args);
-		if (error) {
-			return error;
-		}
-	}
+	super_error = super_call != NULL ? super_call(dev, super_handle, args)
+					 : 0;
 
 	/* Now enumerate our additions. */
-	const struct i2c_addition *i2c_adds = fixup->i2c_additions;
-	KASSERT(i2c_adds != NULL);
-	int i;
-	bool cbrv;
-
-	for (i = 0; i < fixup->i2c_nadditions; i++) {
-		args->ia->ia_addr = i2c_adds[i].addr;
-		args->ia->ia_name = i2c_adds[i].name;
-		args->ia->ia_clist = i2c_adds[i].compat;
-		args->ia->ia_clist_size = args->ia->ia_clist != NULL
-		    ? strlen(i2c_adds[i].compat) + 1
-		    : 0;
-		if (fixup->i2c_phandle != 0) {
-			args->ia->ia_devhandle =
-			    devhandle_from_of(fixup->i2c_phandle);
-		} else {
-			devhandle_invalidate(&args->ia->ia_devhandle);
-		}
-
-		cbrv = args->callback(dev, args);
-
-		if (! cbrv) {
-			break;
-		}
-	}
+	KASSERT(fixup->i2c_additions != NULL);
+	error = i2c_enumerate_deventries(dev, call_handle, args,
+	    fixup->i2c_additions, fixup->i2c_nadditions);
 
-	return 0;
+	return super_error != 0 ? super_error : error;
 }
 
 static device_call_t
@@ -183,8 +149,8 @@ i2c_fixup_lookup_device_call(devhandle_t
 }
 
 static void
-add_i2c_devices(device_t dev, const struct i2c_addition *i2c_adds, int nadds,
-    int phandle)
+add_i2c_devices(device_t dev, const struct i2c_deventry *i2c_adds,
+    unsigned int nadds)
 {
 	struct i2c_fixup_container *fixup;
 
@@ -192,7 +158,6 @@ add_i2c_devices(device_t dev, const stru
 
 	fixup->i2c_additions = i2c_adds;
 	fixup->i2c_nadditions = nadds;
-	fixup->i2c_phandle = phandle;
 
 	/* Stash away the super-class handle. */
 	devhandle_t devhandle = device_handle(dev);
@@ -306,7 +271,7 @@ static int v210_env_sensors_i2c_phandle 
 static void
 v210_env_sensors_fixup(device_t dev, void *aux)
 {
-	static const struct i2c_addition i2c_adds[] = {
+	static const struct i2c_deventry i2c_adds[] = {
 		{ .name = "hardware-monitor",
 		  .compat = "i2c-adm1026", .addr = 0x2e },
 
@@ -319,7 +284,7 @@ v210_env_sensors_fixup(device_t dev, voi
 	devhandle_t devhandle = device_handle(dev);
 	v210_env_sensors_i2c_phandle = devhandle_to_of(devhandle);
 
-	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds), 0);
+	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds));
 }
 
 static const struct device_compatible_entry dtnode_fixup_table_v210[] = {
@@ -441,7 +406,7 @@ static int e250_envctrltwo_phandle __rea
 static void
 e250_envctrltwo_fixup(device_t dev, void *aux)
 {
-	static const struct i2c_addition i2c_adds[] = {
+	static const struct i2c_deventry i2c_adds[] = {
 		/* PSU temperature / CPU fan */
 		{ .name = "PSU", .compat = "ecadc", .addr = 0x4a },
 
@@ -468,8 +433,7 @@ e250_envctrltwo_fixup(device_t dev, void
 	KASSERT(e250_envctrltwo_phandle == 0);
 	e250_envctrltwo_phandle = devhandle_to_of(devhandle);
 
-	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds),
-	    e250_envctrltwo_phandle);
+	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds));
 }
 
 static const struct device_compatible_entry dtnode_fixup_table_e250[] = {
@@ -652,7 +616,7 @@ static const struct system_fixup system_
 static void
 e450_envctrl_fixup(device_t dev, void *aux)
 {
-	static const struct i2c_addition i2c_adds[] = {
+	static const struct i2c_deventry i2c_adds[] = {
 		/* Power supply 1 temperature. */
 		{ .name = "PSU-1", .compat = "ecadc", .addr = 0x48 },
 
@@ -670,8 +634,7 @@ e450_envctrl_fixup(device_t dev, void *a
 	};
 	devhandle_t devhandle = device_handle(dev);
 	KASSERT(devhandle_type(devhandle) == DEVHANDLE_TYPE_OF);
-	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds),
-	    devhandle_to_of(devhandle));
+	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds));
 }
 
 static const struct device_compatible_entry dtnode_fixup_table_e450[] = {
@@ -692,13 +655,13 @@ static const struct system_fixup system_
 static void
 sparcle_smbus_fixup(device_t dev, void *aux)
 {
-	static const struct i2c_addition i2c_adds[] = {
+	static const struct i2c_deventry i2c_adds[] = {
 		{ .name = "dimm-spd",	.addr = 0x50 },
 		{ .name = "dimm-spd",	.addr = 0x51 },
 	};
 	devhandle_t devhandle = device_handle(dev);
 	KASSERT(devhandle_type(devhandle) == DEVHANDLE_TYPE_OF);
-	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds), 0);
+	add_i2c_devices(dev, i2c_adds, __arraycount(i2c_adds));
 };
 
 static const struct device_compatible_entry dtnode_fixup_table_sparcle[] = {

Index: src/sys/dev/i2c/i2c.c
diff -u src/sys/dev/i2c/i2c.c:1.80.2.5 src/sys/dev/i2c/i2c.c:1.80.2.6
--- src/sys/dev/i2c/i2c.c:1.80.2.5	Fri Sep 10 15:45:28 2021
+++ src/sys/dev/i2c/i2c.c	Sat Sep 11 01:03:18 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: i2c.c,v 1.80.2.5 2021/09/10 15:45:28 thorpej Exp $	*/
+/*	$NetBSD: i2c.c,v 1.80.2.6 2021/09/11 01:03:18 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.80.2.5 2021/09/10 15:45:28 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.80.2.6 2021/09/11 01:03:18 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -632,6 +632,41 @@ iic_enumerate_devices_callback(device_t 
 	return true;				/* keep enumerating */
 }
 
+/*
+ * i2c_enumerate_deventries:
+ *
+ *	Helper for enumerating known i2c devices that can be used
+ *	by a platform's i2c-emumerate-devices device call if needed.
+ */
+int
+i2c_enumerate_deventries(device_t dev, devhandle_t call_handle,
+    struct i2c_enumerate_devices_args *args,
+    const struct i2c_deventry *entries, unsigned int nentries)
+{
+	unsigned int i;
+	bool cbrv;
+
+	for (i = 0; i < nentries; i++) {
+		args->ia->ia_addr = entries[i].addr;
+		args->ia->ia_name = entries[i].name;
+		args->ia->ia_clist = entries[i].compat;
+		args->ia->ia_clist_size =
+		    entries[i].compat != NULL ? strlen(entries[i].compat) + 1
+					      : 0;
+
+		/* no devhandle for child devices. */
+		devhandle_invalidate(&args->ia->ia_devhandle);
+
+		cbrv = args->callback(dev, args);
+
+		if (!cbrv) {
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static int
 iic_match(device_t parent, cfdata_t cf, void *aux)
 {

Index: src/sys/dev/i2c/i2cvar.h
diff -u src/sys/dev/i2c/i2cvar.h:1.24.12.2 src/sys/dev/i2c/i2cvar.h:1.24.12.3
--- src/sys/dev/i2c/i2cvar.h:1.24.12.2	Fri Sep 10 15:45:28 2021
+++ src/sys/dev/i2c/i2cvar.h	Sat Sep 11 01:03:18 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: i2cvar.h,v 1.24.12.2 2021/09/10 15:45:28 thorpej Exp $	*/
+/*	$NetBSD: i2cvar.h,v 1.24.12.3 2021/09/11 01:03:18 thorpej Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -175,6 +175,19 @@ struct i2c_enumerate_devices_args {
 };
 
 /*
+ * Helpers for enumerating known i2c devices, that can be used from
+ * the i2c-enumerate-devices device call.
+ */
+struct i2c_deventry {
+	const char *name;
+	const char *compat;
+	i2c_addr_t addr;
+};
+int	i2c_enumerate_deventries(device_t, devhandle_t,
+	    struct i2c_enumerate_devices_args *,
+	    const struct i2c_deventry *, unsigned int);
+
+/*
  * API presented to i2c controllers.
  */
 int	iicbus_print(void *, const char *);

Reply via email to