Date: Mon, 27 Nov 2006 23:53:06 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 110599 for review Message-ID: <200611272353.kARNr6Ng004579@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=110599 Change 110599 by imp@imp_lighthouse on 2006/11/27 23:52:43 First round of changes necessary for iicbus to become a hinted bus. Also cleanup a few unused things. Affected files ... .. //depot/projects/arm/src/sys/dev/iicbus/iicbus.c#9 edit .. //depot/projects/arm/src/sys/dev/iicbus/iicbus.h#5 edit Differences ... ==== //depot/projects/arm/src/sys/dev/iicbus/iicbus.c#9 (text+ko) ==== @@ -34,52 +34,18 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/module.h> #include <sys/bus.h> - #include <dev/iicbus/iiconf.h> #include <dev/iicbus/iicbus.h> #include "iicbus_if.h" -#define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev)) - -devclass_t iicbus_devclass; - /* See comments below for why auto-scanning is a bad idea. */ #define SCAN_IICBUS 0 -/* - * Device methods - */ -static int iicbus_probe(device_t); -static int iicbus_attach(device_t); -static int iicbus_detach(device_t); -static int iicbus_add_child(device_t dev, int order, const char *name, int unit); - -static device_method_t iicbus_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, iicbus_probe), - DEVMETHOD(device_attach, iicbus_attach), - DEVMETHOD(device_detach, iicbus_detach), - - /* bus interface */ - DEVMETHOD(bus_add_child, iicbus_add_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_print_child, bus_generic_print_child), - - DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), - - { 0, 0 } -}; - -driver_t iicbus_driver = { - "iicbus", - iicbus_methods, - sizeof(struct iicbus_softc), -}; - static int iicbus_probe(device_t dev) { @@ -121,7 +87,9 @@ #if SCAN_IICBUS unsigned char addr; #endif + struct iicbus_softc *sc = IICBUS_SOFTC(dev); + sc->dev = dev; iicbus_reset(dev, IIC_FASTEST, 0, NULL); /* device probing is meaningless since the bus is supposed to be @@ -140,12 +108,13 @@ } printf("\n"); #endif - device_add_child(dev, "ic", -1); - device_add_child(dev, "iicsmb", -1); - device_add_child(dev, "ds1672", -1); - device_add_child(dev, "ad7418", -1); + /* Always attach the iicsmb children */ + BUS_ADD_CHILD(dev, 0, "iicsmb", -1); /* attach any known device */ - device_add_child(dev, "iic", -1); + BUS_ADD_CHILD(dev, 0, "iic", -1); + /* Attach the wired devices via hints */ + bus_enumerate_hinted_children(dev); + /* Now probe and attach them */ bus_generic_attach(dev); return (0); } @@ -160,12 +129,89 @@ } static int +iicbus_print_child(device_t dev, device_t child) +{ + struct iicbus_ivar *devi = IICBUS_IVAR(child); + int retval = 0; + + retval += bus_print_child_header(dev, child); + if (devi->addr != 0) + retval += printf(" at addr %#x", devi->addr); + retval += bus_print_child_footer(dev, child); + + return (retval); +} + +static void +iicbus_probe_nomatch(device_t bus, device_t child) +{ + struct iicbus_ivar *devi = IICBUS_IVAR(child); + + device_printf(bus, "<unknown card>"); + printf(" at addr %#x\n", devi->addr); + return; +} + +static int +iicbus_child_location_str(device_t bus, device_t child, char *buf, + size_t buflen) +{ + struct iicbus_ivar *devi = IICBUS_IVAR(child); + + snprintf(buf, buflen, "addr=%#x", devi->addr); + return (0); +} + +static int +iicbus_child_pnpinfo_str(device_t bus, device_t child, char *buf, + size_t buflen) +{ + *buf = '\0'; + return (0); +} + +static int +iicbus_read_ivar(device_t bus, device_t child, int which, u_char *result) +{ + struct iicbus_ivar *devi = IICBUS_IVAR(child); + + switch (which) { + default: + return (EINVAL); + case IICBUS_IVAR_ADDR: + *(uint32_t *)result = devi->addr; + break; + } + return (0); +} + +static device_t iicbus_add_child(device_t dev, int order, const char *name, int unit) { + device_t child; + struct iicbus_ivar *devi; + + child = device_add_child_ordered(dev, order, name, unit); + if (child == NULL) + return (child); + devi = malloc(sizeof(struct iicbus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); + if (devi == NULL) { + device_delete_child(dev, child); + return (0); + } + device_set_ivars(child, devi); + return (child); +} - device_add_child_ordered(dev, order, name, unit); - bus_generic_attach(dev); - return (0); +static void +iicbus_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + struct iicbus_ivar *devi; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + devi = IICBUS_IVAR(child); + resource_int_value(dname, dunit, "addr", &devi->addr); } int @@ -189,6 +235,36 @@ return (IIC_ENOTSUPP); } +static device_method_t iicbus_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, iicbus_probe), + DEVMETHOD(device_attach, iicbus_attach), + DEVMETHOD(device_detach, iicbus_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, iicbus_add_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + DEVMETHOD(bus_print_child, iicbus_print_child), + DEVMETHOD(bus_probe_nomatch, iicbus_probe_nomatch), + DEVMETHOD(bus_read_ivar, iicbus_read_ivar), + DEVMETHOD(bus_child_pnpinfo_str, iicbus_child_pnpinfo_str), + DEVMETHOD(bus_child_location_str, iicbus_child_location_str), + DEVMETHOD(bus_hinted_child, iicbus_hinted_child), + + /* iicbus interface */ + DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), + + { 0, 0 } +}; + +driver_t iicbus_driver = { + "iicbus", + iicbus_methods, + sizeof(struct iicbus_softc), +}; + +devclass_t iicbus_devclass; + DRIVER_MODULE(iicbus, envctrl, iicbus_driver, iicbus_devclass, 0, 0); DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0); MODULE_VERSION(iicbus, IICBUS_MODVER); ==== //depot/projects/arm/src/sys/dev/iicbus/iicbus.h#5 (text+ko) ==== @@ -29,13 +29,36 @@ #ifndef __IICBUS_H #define __IICBUS_H -struct iicbus_softc { +#define IICBUS_IVAR(d) (struct iicbus_ivar *) device_get_ivars(d) +#define IICBUS_SOFTC(d) (struct iicbus_softc *) device_get_softc(d) +struct iicbus_softc +{ + device_t dev; /* Myself */ device_t owner; /* iicbus owner device structure */ u_char started; /* address of the 'started' slave * 0 if no start condition succeeded */ }; +struct iicbus_ivar +{ + uint32_t addr; +}; + +enum { + IICBUS_IVAR_ADDR /* Address or base address */ +}; + +#define IICBUS_ACCESSOR(A, B, T) \ +__inline static int \ +iicbus_get_ ## A(device_t dev, T *t) \ +{ \ + return BUS_READ_IVAR(device_get_parent(dev), dev, \ + IICBUS_IVAR_ ## B, (uintptr_t *) t); \ +} + +IICBUS_ACCESSOR(addr, ADDR, uint32_t) + extern int iicbus_generic_intr(device_t dev, int event, char *buf); extern driver_t iicbus_driver;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611272353.kARNr6Ng004579>