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 *);