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