Index: dev/fdt/fdt_spi.c =================================================================== RCS file: /cvsroot/src/sys/dev/fdt/fdt_spi.c,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -p -r1.3 -r1.3.2.1 --- dev/fdt/fdt_spi.c 7 Aug 2021 16:19:10 -0000 1.3 +++ dev/fdt/fdt_spi.c 9 Aug 2021 00:30:09 -0000 1.3.2.1 @@ -1,4 +1,4 @@ -/* $NetBSD: fdt_spi.c,v 1.3 2021/08/07 16:19:10 thorpej Exp $ */ +/* $NetBSD: fdt_spi.c,v 1.3.2.1 2021/08/09 00:30:09 thorpej Exp $ */ /* * Copyright (c) 2019 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: fdt_spi.c,v 1.3 2021/08/07 16:19:10 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fdt_spi.c,v 1.3.2.1 2021/08/09 00:30:09 thorpej Exp $"); #include #include @@ -42,9 +42,9 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_spi.c,v #include struct fdtbus_spi_controller { - device_t spi_dev; + struct spi_controller *spi_ctlr; int spi_phandle; - const struct fdtbus_spi_controller_func *spi_funcs; + LIST_ENTRY(fdtbus_spi_controller) spi_next; }; @@ -52,21 +52,20 @@ static LIST_HEAD(, fdtbus_spi_controller LIST_HEAD_INITIALIZER(fdtbus_spi_controllers); int -fdtbus_register_spi_controller(device_t dev, int phandle, - const struct fdtbus_spi_controller_func *funcs) +fdtbus_register_spi_controller(struct spi_controller *ctlr, int phandle) { struct fdtbus_spi_controller *spi; spi = kmem_alloc(sizeof(*spi), KM_SLEEP); - spi->spi_dev = dev; + spi->spi_ctlr = ctlr; spi->spi_phandle = phandle; - spi->spi_funcs = funcs; LIST_INSERT_HEAD(&fdtbus_spi_controllers, spi, spi_next); return 0; } +#if 0 static struct spi_controller * fdtbus_get_spi_controller(int phandle) { @@ -74,42 +73,9 @@ fdtbus_get_spi_controller(int phandle) LIST_FOREACH(spi, &fdtbus_spi_controllers, spi_next) { if (spi->spi_phandle == phandle) { - return spi->spi_funcs->get_controller(spi->spi_dev); + return spi->spi_ctlr; } } return NULL; } - -device_t -fdtbus_attach_spibus(device_t dev, int phandle, cfprint_t print) -{ - struct spi_controller *spi; - struct spibus_attach_args sba; - prop_dictionary_t devs; - device_t ret; - u_int address_cells; - - devs = prop_dictionary_create(); - if (of_getprop_uint32(phandle, "#address-cells", &address_cells)) - address_cells = 1; - of_enter_spi_devs(devs, phandle, address_cells * 4); - - spi = fdtbus_get_spi_controller(phandle); - KASSERT(spi != NULL); - memset(&sba, 0, sizeof(sba)); - sba.sba_controller = spi; - - sba.sba_child_devices = prop_dictionary_get(devs, "spi-child-devices"); - if (sba.sba_child_devices) - prop_object_retain(sba.sba_child_devices); - prop_object_release(devs); - - ret = config_found(dev, &sba, print, - CFARGS(.iattr = "spibus")); - if (sba.sba_child_devices) - prop_object_release(sba.sba_child_devices); - - return ret; -} - - +#endif Index: dev/fdt/fdtvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/fdt/fdtvar.h,v retrieving revision 1.70 retrieving revision 1.70.12.1 diff -u -p -r1.70 -r1.70.12.1 --- dev/fdt/fdtvar.h 24 Apr 2021 23:36:53 -0000 1.70 +++ dev/fdt/fdtvar.h 9 Aug 2021 00:30:09 -0000 1.70.12.1 @@ -1,4 +1,4 @@ -/* $NetBSD: fdtvar.h,v 1.70 2021/04/24 23:36:53 thorpej Exp $ */ +/* $NetBSD: fdtvar.h,v 1.70.12.1 2021/08/09 00:30:09 thorpej Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -79,10 +80,6 @@ struct fdtbus_interrupt_controller_func void (*unmask)(device_t, void *); }; -struct fdtbus_spi_controller_func { - struct spi_controller * (*get_controller)(device_t); -}; - struct fdtbus_gpio_controller; struct fdtbus_gpio_pin { @@ -274,8 +271,7 @@ struct fdt_dma_range { int fdtbus_register_interrupt_controller(device_t, int, const struct fdtbus_interrupt_controller_func *); int fdtbus_register_i2c_controller(i2c_tag_t, int); -int fdtbus_register_spi_controller(device_t, int, - const struct fdtbus_spi_controller_func *); +int fdtbus_register_spi_controller(struct spi_controller *, int); int fdtbus_register_gpio_controller(device_t, int, const struct fdtbus_gpio_controller_func *); int fdtbus_register_pinctrl_config(device_t, int, @@ -403,9 +399,6 @@ int fdtbus_todr_attach(device_t, int, t void fdtbus_power_reset(void); void fdtbus_power_poweroff(void); -device_t fdtbus_attach_i2cbus(device_t, int, i2c_tag_t, cfprint_t); -device_t fdtbus_attach_spibus(device_t, int, cfprint_t); - bool fdtbus_init(const void *); const void * fdtbus_get_data(void); int fdtbus_phandle2offset(int); Index: dev/ofw/ofw_spi_subr.c =================================================================== RCS file: /cvsroot/src/sys/dev/ofw/ofw_spi_subr.c,v retrieving revision 1.1 retrieving revision 1.1.16.1 diff -u -p -r1.1 -r1.1.16.1 --- dev/ofw/ofw_spi_subr.c 4 Feb 2021 20:19:09 -0000 1.1 +++ dev/ofw/ofw_spi_subr.c 9 Aug 2021 00:30:09 -0000 1.1.16.1 @@ -1,100 +1,96 @@ -/* $NetBSD: ofw_spi_subr.c,v 1.1 2021/02/04 20:19:09 thorpej Exp $ */ +/* $NetBSD: ofw_spi_subr.c,v 1.1.16.1 2021/08/09 00:30:09 thorpej Exp $ */ /* - * Copyright 1998 - * Digital Equipment Corporation. All rights reserved. + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. * - * This software is furnished under license and may be used and - * copied only in accordance with the following terms and conditions. - * Subject to these conditions, you may download, copy, install, - * use, modify and distribute this software in source and/or binary - * form. No title or ownership is transferred hereby. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 1) Any source code used, modified or distributed must reproduce - * and retain this copyright notice and list of conditions as - * they appear in the source file. - * - * 2) No right is granted to use any trade name, trademark, or logo of - * Digital Equipment Corporation. Neither the "Digital Equipment - * Corporation" name nor any trademark or logo of Digital Equipment - * Corporation may be used to endorse or promote products derived - * from this software without the prior written permission of - * Digital Equipment Corporation. - * - * 3) This software is provided "AS-IS" and any express or implied - * warranties, including but not limited to, any implied warranties - * of merchantability, fitness for a particular purpose, or - * non-infringement are disclaimed. In no event shall DIGITAL be - * liable for any damages whatsoever, and in particular, DIGITAL - * shall not be liable for special, indirect, consequential, or - * incidental damages or damages for lost profits, loss of - * revenue or loss of use, whether such damages arise in contract, - * negligence, tort, under statute, in equity, at law or otherwise, - * even if advised of the possibility of such damage. + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include -__KERNEL_RCSID(0, "$NetBSD: ofw_spi_subr.c,v 1.1 2021/02/04 20:19:09 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofw_spi_subr.c,v 1.1.16.1 2021/08/09 00:30:09 thorpej Exp $"); #include #include #include #include #include +#include -void -of_enter_spi_devs(prop_dictionary_t props, int ofnode, size_t cell_size) +static int +of_spi_enumerate_devices(device_t dev, devhandle_t call_handle, void *v) { - int node, len; - char name[32]; - uint64_t reg64; - uint32_t reg32; - uint32_t slave; - u_int32_t maxfreq; - prop_array_t array = NULL; - prop_dictionary_t dev; - int mode; + struct spi_enumerate_devices_args *args = v; + int spi_node, node; + char name[32], compat_buf[32]; + uint32_t chip_select; + char *clist; + int clist_size; + bool cbrv; + + spi_node = devhandle_to_of(call_handle); - for (node = OF_child(ofnode); node; node = OF_peer(node)) { - if (OF_getprop(node, "name", name, sizeof(name)) <= 0) + for (node = OF_child(spi_node); node != 0; node = OF_peer(node)) { + if (OF_getprop(node, "name", name, sizeof(name)) <= 0) { continue; - len = OF_getproplen(node, "reg"); - slave = 0; - if (cell_size == 8 && len >= sizeof(reg64)) { - if (OF_getprop(node, "reg", ®64, sizeof(reg64)) - < sizeof(reg64)) - continue; - slave = be64toh(reg64); - } else if (cell_size == 4 && len >= sizeof(reg32)) { - if (OF_getprop(node, "reg", ®32, sizeof(reg32)) - < sizeof(reg32)) - continue; - slave = be32toh(reg32); - } else { + } + + if (of_getprop_uint32(node, "reg", &chip_select) != 0) { continue; } - if (of_getprop_uint32(node, "spi-max-frequency", &maxfreq)) { - maxfreq = 0; + + /* Device Tree bindings specify a max chip select of 256. */ + if (chip_select > 256) { + continue; } - mode = ((int)of_hasprop(node, "cpol") << 1) | (int)of_hasprop(node, "cpha"); - if (array == NULL) - array = prop_array_create(); + clist_size = OF_getproplen(node, "compatible"); + if (clist_size <= 0) { + continue; + } - dev = prop_dictionary_create(); - prop_dictionary_set_string(dev, "name", name); - prop_dictionary_set_uint32(dev, "slave", slave); - prop_dictionary_set_uint32(dev, "mode", mode); - if (maxfreq > 0) - prop_dictionary_set_uint32(dev, "spi-max-frequency", maxfreq); - prop_dictionary_set_uint64(dev, "cookie", node); - of_to_dataprop(dev, node, "compatible", "compatible"); - prop_array_add(array, dev); - prop_object_release(dev); - } + clist = kmem_tmpbuf_alloc(clist_size, + compat_buf, sizeof(compat_buf), KM_SLEEP); + if (OF_getprop(node, "compatible", clist, clist_size) < + clist_size) { + kmem_tmpbuf_free(clist, clist_size, compat_buf); + continue; + } + + args->chip_select = (int)chip_select; + args->sa->sa_name = name; + args->sa->sa_clist = clist; + args->sa->sa_clist_size = clist_size; + args->sa->sa_devhandle = devhandle_from_of(node); - if (array != NULL) { - prop_dictionary_set(props, "spi-child-devices", array); - prop_object_release(array); + cbrv = args->callback(dev, args); + + kmem_tmpbuf_free(clist, clist_size, compat_buf); + + if (!cbrv) { + break; + } } + + return 0; } +OF_DEVICE_CALL_REGISTER("spi-enumerate-devices", of_spi_enumerate_devices);