Skip site navigation (1)Skip section navigation (2)
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>