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