PERFORCE change 142741 for review

Andrew Turner andrew at FreeBSD.org
Mon Jun 2 08:19:07 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=142741

Change 142741 by andrew at andrew_bender on 2008/06/02 08:18:59

	Add uart as a child of the s3c2410 cpu bus
	Improve the bus code to allow IRQ's to be specified with bus_set_resource

Affected files ...

.. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c2410.c#9 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/s3c2xx0/s3c2410.c#9 (text+ko) ====

@@ -36,6 +36,7 @@
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/reboot.h>
+#include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 
@@ -54,25 +55,29 @@
 u_int irqmasks[IPL_LEVELS];
 
 /* prototypes */
+static device_t s3c2410_add_child(device_t, int, const char *, int);
+
 static int	s3c2410_probe(device_t);
 static int	s3c2410_attach(device_t);
 static void	s3c2410_identify(driver_t *, device_t);
-
+static int	s3c2410_setup_intr(device_t, device_t, struct resource *, int,
+        driver_filter_t *, driver_intr_t *, void *, void **);
 static struct resource *s3c2410_alloc_resource(device_t, device_t, int, int *,
         u_long, u_long, u_long, u_int);
-
 static int s3c2410_activate_resource(device_t, device_t, int, int,
         struct resource *);
-static int s3c2410_setup_intr(device_t, device_t, struct resource *, int,
-        driver_filter_t *, driver_intr_t *, void *, void **);
+static struct resource_list *s3c2410_get_resource_list(device_t, device_t);
 
 static device_method_t s3c2410_methods[] = {
 	DEVMETHOD(device_probe, s3c2410_probe),
 	DEVMETHOD(device_attach, s3c2410_attach),
 	DEVMETHOD(device_identify, s3c2410_identify),
+	DEVMETHOD(bus_setup_intr, s3c2410_setup_intr),
 	DEVMETHOD(bus_alloc_resource, s3c2410_alloc_resource),
 	DEVMETHOD(bus_activate_resource, s3c2410_activate_resource),
-	DEVMETHOD(bus_setup_intr, s3c2410_setup_intr),
+	DEVMETHOD(bus_get_resource_list,s3c2410_get_resource_list),
+	DEVMETHOD(bus_set_resource,	bus_generic_rl_set_resource),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
 	{0, 0},
 };
 
@@ -87,35 +92,76 @@
 
 struct s3c2xx0_softc *s3c2xx0_softc = NULL;
 
+static device_t
+s3c2410_add_child(device_t bus, int prio, const char *name, int unit)
+{
+	device_t child;
+	struct s3c2xx0_ivar *ivar;
+
+	child = device_add_child_ordered(bus, prio, name, unit);
+	if (child == NULL)
+		return (NULL);
+
+	ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (ivar == NULL) {
+		device_delete_child(bus, child);
+		printf("Can't add alloc ivar\n");
+		return (NULL);
+	}
+	device_set_ivars(child, ivar);
+	resource_list_init(&ivar->resources);
+
+	return (child);
+}
+
 static int
 s3c2410_setup_intr(device_t dev, device_t child,
         struct resource *ires,  int flags, driver_filter_t *filt,
 	driver_intr_t *intr, void *arg, void **cookiep)
 {
 	int saved_cpsr;
+	int error;
 
-	if (flags & INTR_TYPE_TTY) 
-		rman_set_start(ires, 15);
-	else if (flags & INTR_TYPE_CLK) {
+	if (flags & INTR_TYPE_CLK) {
 		if (rman_get_start(ires) == 0)
 			rman_set_start(ires, 26);
 		else
 			rman_set_start(ires, 27);
 	}
 	saved_cpsr = SetCPSR(I32_bit, I32_bit);                 
+	SetCPSR(I32_bit, saved_cpsr & I32_bit);
 
-	SetCPSR(I32_bit, saved_cpsr & I32_bit);
-	BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt, 
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
 	    intr, arg, cookiep);
-	return (0);
+	return (error);
 }
 
 static struct resource *
 s3c2410_alloc_resource(device_t bus, device_t child, int type, int *rid,
         u_long start, u_long end, u_long count, u_int flags)
 {
+	struct resource_list_entry *rle;
+	struct s3c2xx0_ivar *ivar = device_get_ivars(child);
+	struct resource_list *rl = &ivar->resources;
 	struct resource *res = NULL;
 
+	if (device_get_parent(child) != bus)
+		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
+		    type, rid, start, end, count, flags));
+
+	rle = resource_list_find(rl, type, *rid);
+	if (rle != NULL) {
+		/* There is a resource list. Use it */
+		if (rle->res)
+			panic("Resource rid %d type %d already in use", *rid,
+			    type);
+		if (start == 0UL && end == ~0UL) {
+			start = rle->start;
+			count = ulmax(count, rle->count);
+			end = ulmax(rle->end, start + count - 1);
+		}
+	}
+
 	switch (type) {
 	case SYS_RES_IRQ:
 		res = rman_reserve_resource(
@@ -124,12 +170,31 @@
 		break;
 	}
 
-	if (res != NULL)
+	if (res != NULL) {
 		rman_set_rid(res, *rid);
+		if (rle != NULL)
+			rle->res = res;
+	}
 
 	return (res);
 }
 
+static int
+s3c2410_activate_resource(device_t bus, device_t child, int type, int rid,
+        struct resource *r)
+{
+	return (0);
+}
+
+static struct resource_list *
+s3c2410_get_resource_list(device_t dev, device_t child)
+{
+	struct s3c2xx0_ivar *ivar;
+
+	ivar = device_get_ivars(child);
+	return (&(ivar->resources));
+}
+
 void
 s3c2410_identify(driver_t *driver, device_t parent)
 {
@@ -137,13 +202,6 @@
 	BUS_ADD_CHILD(parent, 0, "s3c2410", 0);
 }
 
-static int
-s3c2410_activate_resource(device_t bus, device_t child, int type, int rid,
-        struct resource *r)
-{
-	return (0);
-}
-
 int
 s3c2410_probe(device_t dev)
 {
@@ -155,6 +213,7 @@
 {
 	struct s3c24x0_softc *sc = device_get_softc(dev);
 	bus_space_tag_t iot;
+	device_t child;
 
 	s3c2xx0_softc = &(sc->sc_sx);
 	sc->sc_sx.sc_iot = iot = &s3c2xx0_bs_tag;
@@ -207,6 +266,9 @@
 		panic("s3c2410_attach: failed to set up IRQ rman");
 	device_add_child(dev, "timer", 0);
 	device_add_child(dev, "nand", 0);
+
+	child = s3c2410_add_child(dev, 0, "uart", 0);
+
 	bus_generic_probe(dev);
 	bus_generic_attach(dev);
 


More information about the p4-projects mailing list