Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jul 2012 20:17:15 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r238376 - head/sys/arm/at91
Message-ID:  <201207112017.q6BKHFZK063176@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Wed Jul 11 20:17:14 2012
New Revision: 238376
URL: http://svn.freebsd.org/changeset/base/238376

Log:
  Make the SoC stuff a little more modular, and start to move away from
  having the CPU device that's a child of atmelarm that does stuff.
  
  o Create a linker_set for the support fucntions for the SoCs.
  o Rename soc_data to soc_info.
  o Move the delay and reset function pointers to new soc_data struct
  o Create elements for all known SoCs
  o Add lookup of the SoC we found, and print a warning if it isn't one
    we know about.

Added:
  head/sys/arm/at91/at91soc.c   (contents, props changed)
  head/sys/arm/at91/at91soc.h   (contents, props changed)
Modified:
  head/sys/arm/at91/at91_machdep.c
  head/sys/arm/at91/at91_mci.c
  head/sys/arm/at91/at91_st.c
  head/sys/arm/at91/at91_streg.h
  head/sys/arm/at91/at91rm9200.c
  head/sys/arm/at91/at91sam9260.c
  head/sys/arm/at91/at91sam9g20.c
  head/sys/arm/at91/at91sam9x25.c
  head/sys/arm/at91/at91var.h
  head/sys/arm/at91/files.at91

Modified: head/sys/arm/at91/at91_machdep.c
==============================================================================
--- head/sys/arm/at91/at91_machdep.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91_machdep.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
 
 #include <arm/at91/at91board.h>
 #include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
 #include <arm/at91/at91_usartreg.h>
 #include <arm/at91/at91rm92reg.h>
 #include <arm/at91/at91sam9g20reg.h>
@@ -278,7 +279,7 @@ static const char *soc_subtype_name[] = 
 	[AT91_ST_SAM9X35] = "at91sam9x35",
 };
 
-struct at91_soc_info soc_data;
+struct at91_soc_info soc_info;
 
 /*
  * Read the SoC ID from the CIDR register and try to match it against the
@@ -291,92 +292,92 @@ at91_try_id(uint32_t dbgu_base)
 {
 	uint32_t socid;
 
-	soc_data.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+	soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
 	    DBGU_C1R);
-	socid = soc_data.cidr & ~AT91_CPU_VERSION_MASK;
+	socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK;
 
-	soc_data.type = AT91_T_NONE;
-	soc_data.subtype = AT91_ST_NONE;
-	soc_data.family = (soc_data.cidr & AT91_CPU_FAMILY_MASK) >> 20;
-	soc_data.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+	soc_info.type = AT91_T_NONE;
+	soc_info.subtype = AT91_ST_NONE;
+	soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20;
+	soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
 	    DBGU_C2R);
 
 	switch (socid) {
 	case AT91_CPU_CAP9:
-		soc_data.type = AT91_T_CAP9;
+		soc_info.type = AT91_T_CAP9;
 		break;
 	case AT91_CPU_RM9200:
-		soc_data.type = AT91_T_RM9200;
+		soc_info.type = AT91_T_RM9200;
 		break;
 	case AT91_CPU_SAM9XE128:
 	case AT91_CPU_SAM9XE256:
 	case AT91_CPU_SAM9XE512:
 	case AT91_CPU_SAM9260:
-		soc_data.type = AT91_T_SAM9260;
-		if (soc_data.family == AT91_FAMILY_SAM9XE)
-			soc_data.subtype = AT91_ST_SAM9XE;
+		soc_info.type = AT91_T_SAM9260;
+		if (soc_info.family == AT91_FAMILY_SAM9XE)
+			soc_info.subtype = AT91_ST_SAM9XE;
 		break;
 	case AT91_CPU_SAM9261:
-		soc_data.type = AT91_T_SAM9261;
+		soc_info.type = AT91_T_SAM9261;
 		break;
 	case AT91_CPU_SAM9263:
-		soc_data.type = AT91_T_SAM9263;
+		soc_info.type = AT91_T_SAM9263;
 		break;
 	case AT91_CPU_SAM9G10:
-		soc_data.type = AT91_T_SAM9G10;
+		soc_info.type = AT91_T_SAM9G10;
 		break;
 	case AT91_CPU_SAM9G20:
-		soc_data.type = AT91_T_SAM9G20;
+		soc_info.type = AT91_T_SAM9G20;
 		break;
 	case AT91_CPU_SAM9G45:
-		soc_data.type = AT91_T_SAM9G45;
+		soc_info.type = AT91_T_SAM9G45;
 		break;
 	case AT91_CPU_SAM9N12:
-		soc_data.type = AT91_T_SAM9N12;
+		soc_info.type = AT91_T_SAM9N12;
 		break;
 	case AT91_CPU_SAM9RL64:
-		soc_data.type = AT91_T_SAM9RL;
+		soc_info.type = AT91_T_SAM9RL;
 		break;
 	case AT91_CPU_SAM9X5:
-		soc_data.type = AT91_T_SAM9X5;
+		soc_info.type = AT91_T_SAM9X5;
 		break;
 	default:
 		return (0);
 	}
 
-	switch (soc_data.type) {
+	switch (soc_info.type) {
 	case AT91_T_SAM9G45:
-		switch (soc_data.exid) {
+		switch (soc_info.exid) {
 		case AT91_EXID_SAM9G45:
-			soc_data.subtype = AT91_ST_SAM9G45;
+			soc_info.subtype = AT91_ST_SAM9G45;
 			break;
 		case AT91_EXID_SAM9G46:
-			soc_data.subtype = AT91_ST_SAM9G46;
+			soc_info.subtype = AT91_ST_SAM9G46;
 			break;
 		case AT91_EXID_SAM9M10:
-			soc_data.subtype = AT91_ST_SAM9M10;
+			soc_info.subtype = AT91_ST_SAM9M10;
 			break;
 		case AT91_EXID_SAM9M11:
-			soc_data.subtype = AT91_ST_SAM9M11;
+			soc_info.subtype = AT91_ST_SAM9M11;
 			break;
 		}
 		break;
 	case AT91_T_SAM9X5:
-		switch (soc_data.exid) {
+		switch (soc_info.exid) {
 		case AT91_EXID_SAM9G15:
-			soc_data.subtype = AT91_ST_SAM9G15;
+			soc_info.subtype = AT91_ST_SAM9G15;
 			break;
 		case AT91_EXID_SAM9G25:
-			soc_data.subtype = AT91_ST_SAM9G25;
+			soc_info.subtype = AT91_ST_SAM9G25;
 			break;
 		case AT91_EXID_SAM9G35:
-			soc_data.subtype = AT91_ST_SAM9G35;
+			soc_info.subtype = AT91_ST_SAM9G35;
 			break;
 		case AT91_EXID_SAM9X25:
-			soc_data.subtype = AT91_ST_SAM9X25;
+			soc_info.subtype = AT91_ST_SAM9X25;
 			break;
 		case AT91_EXID_SAM9X35:
-			soc_data.subtype = AT91_ST_SAM9X35;
+			soc_info.subtype = AT91_ST_SAM9X35;
 			break;
 		}
 		break;
@@ -384,18 +385,24 @@ at91_try_id(uint32_t dbgu_base)
 		break;
 	}
 	/*
-	 * Disable interrupts
+	 * Disable interrupts in the DBGU unit...
 	 */
 	*(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff;
 
 	/*
 	 * Save the name for later...
 	 */
-	snprintf(soc_data.name, sizeof(soc_data.name), "%s%s%s",
-	    soc_type_name[soc_data.type],
-	    soc_data.subtype == AT91_ST_NONE ? "" : " subtype ",
-	    soc_data.subtype == AT91_ST_NONE ? "" :
-	    soc_subtype_name[soc_data.subtype]);
+	snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s",
+	    soc_type_name[soc_info.type],
+	    soc_info.subtype == AT91_ST_NONE ? "" : " subtype ",
+	    soc_info.subtype == AT91_ST_NONE ? "" :
+	    soc_subtype_name[soc_info.subtype]);
+
+        /*
+         * try to get the matching CPU support.
+         */
+        soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype);
+
 	return (1);
 }
 
@@ -548,6 +555,9 @@ initarm(struct arm_boot_params *abp)
 
 	cninit();
 
+	if (soc_info.soc_data == NULL)
+		printf("Warning: No soc support for %s found.\n", soc_info.name);
+
 	memsize = board_init();
 	physmem = memsize / PAGE_SIZE;
 
@@ -637,16 +647,16 @@ void
 DELAY(int n)
 {
 
-	if (soc_data.delay)
-		soc_data.delay(n);
+	if (soc_info.soc_data)
+		soc_info.soc_data->soc_delay(n);
 }
 
 void
 cpu_reset(void)
 {
 
-	if (soc_data.reset)
-		soc_data.reset();
+	if (soc_info.soc_data)
+		soc_info.soc_data->soc_reset();
 	while (1)
 		continue;
 }

Modified: head/sys/arm/at91/at91_mci.c
==============================================================================
--- head/sys/arm/at91/at91_mci.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91_mci.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -313,7 +313,7 @@ static int
 at91_mci_is_mci1rev2xx(void)
 {
 
-	switch (soc_data.type) {
+	switch (soc_info.type) {
 	case AT91_T_SAM9260:
 	case AT91_T_SAM9263:
 	case AT91_T_CAP9:

Modified: head/sys/arm/at91/at91_st.c
==============================================================================
--- head/sys/arm/at91/at91_st.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91_st.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 #include <arm/at91/at91var.h>
 #include <arm/at91/at91_streg.h>
+#include <arm/at91/at91rm92reg.h>
 
 static struct at91_st_softc {
 	struct resource *	sc_irq_res;
@@ -57,6 +58,12 @@ static inline uint32_t
 RD4(bus_size_t off)
 {
 
+	if (timer_softc == NULL) {
+		uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
+
+		return *p;
+	}
+
 	return (bus_read_4(timer_softc->sc_mem_res, off));
 }
 
@@ -64,7 +71,13 @@ static inline void
 WR4(bus_size_t off, uint32_t val)
 {
 
-	bus_write_4(timer_softc->sc_mem_res, off, val);
+	if (timer_softc == NULL) {
+		uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
+
+		*p = val;
+	}
+	else
+		bus_write_4(timer_softc->sc_mem_res, off, val);
 }
 
 static void at91_st_watchdog(void *, u_int, int *);
@@ -105,7 +118,7 @@ clock_intr(void *arg)
 	return (FILTER_STRAY);
 }
 
-static void
+void
 at91_st_delay(int n)
 {
 	uint32_t start, end, cur;
@@ -125,7 +138,7 @@ at91_st_delay(int n)
 	}
 }
 
-static void
+void
 at91_st_cpu_reset(void)
 {
 	/*
@@ -209,9 +222,6 @@ at91_st_attach(device_t dev)
 	if (err)
 		return err;
 
-        soc_data.delay = at91_st_delay;
-        soc_data.reset = at91_st_cpu_reset;      // XXX kinda late to be setting this...
-
 	timer_softc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
 	  at91_st_watchdog, dev, 0);
 

Modified: head/sys/arm/at91/at91_streg.h
==============================================================================
--- head/sys/arm/at91/at91_streg.h	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91_streg.h	Wed Jul 11 20:17:14 2012	(r238376)
@@ -55,4 +55,7 @@
 /* ST_CRTR */
 #define ST_CRTR_MASK	0xfffff /* 20-bit counter */
 
+void at91_st_delay(int n);
+void at91_st_cpu_reset(void);
+
 #endif /* ARM_AT91_AT91STREG_H */

Modified: head/sys/arm/at91/at91rm9200.c
==============================================================================
--- head/sys/arm/at91/at91rm9200.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91rm9200.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -42,7 +42,10 @@ __FBSDID("$FreeBSD$");
 #include <arm/at91/at91rm92reg.h>
 #include <arm/at91/at91_aicreg.h>
 #include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_streg.h>
 #include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91soc.h>
+
 
 struct at91rm92_softc {
 	device_t dev;
@@ -171,7 +174,7 @@ static int
 at91_probe(device_t dev)
 {
 
-	device_set_desc(dev, soc_data.name);
+	device_set_desc(dev, soc_info.name);
 	return (0);
 }
 
@@ -277,3 +280,10 @@ static driver_t at91rm92_driver = {
 static devclass_t at91rm92_devclass;
 
 DRIVER_MODULE(at91rm920, atmelarm, at91rm92_driver, at91rm92_devclass, 0, 0);
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_st_delay,
+	.soc_reset = at91_st_cpu_reset
+};
+
+AT91_SOC(AT91_T_RM9200, &soc_data);

Modified: head/sys/arm/at91/at91sam9260.c
==============================================================================
--- head/sys/arm/at91/at91sam9260.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91sam9260.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$");
 
 #include <arm/at91/at91var.h>
 #include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
 #include <arm/at91/at91_aicreg.h>
 #include <arm/at91/at91sam9260reg.h>
+#include <arm/at91/at91_pitreg.h>
 #include <arm/at91/at91_pmcreg.h>
 #include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
 
 struct at91sam9_softc {
 	device_t dev;
@@ -162,7 +165,7 @@ static void
 at91_identify(driver_t *drv, device_t parent)
 {
 
-	if (soc_data.type == AT91_T_SAM9260) {
+	if (soc_info.type == AT91_T_SAM9260) {
 		at91_add_child(parent, 0, "at91sam9260", 0, 0, 0, -1, 0, 0);
 		at91_cpu_add_builtin_children(parent);
 	}
@@ -172,7 +175,7 @@ static int
 at91_probe(device_t dev)
 {
 
-	device_set_desc(dev, soc_data.name);
+	device_set_desc(dev, soc_info.name);
 	return (0);
 }
 
@@ -293,3 +296,10 @@ static devclass_t at91sam9260_devclass;
 
 DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass,
     NULL, NULL);
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset
+};
+
+AT91_SOC(AT91_T_SAM9260, &soc_data);

Modified: head/sys/arm/at91/at91sam9g20.c
==============================================================================
--- head/sys/arm/at91/at91sam9g20.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91sam9g20.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$");
 
 #include <arm/at91/at91var.h>
 #include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
 #include <arm/at91/at91_aicreg.h>
 #include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_pitreg.h>
 #include <arm/at91/at91_pmcreg.h>
 #include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
 
 struct at91sam9_softc {
 	device_t dev;
@@ -179,7 +182,7 @@ static int
 at91_probe(device_t dev)
 {
 
-	device_set_desc(dev, soc_data.name);
+	device_set_desc(dev, soc_info.name);
 	return (0);
 }
 
@@ -295,3 +298,10 @@ static driver_t at91sam9_driver = {
 static devclass_t at91sam9_devclass;
 
 DRIVER_MODULE(at91sam, atmelarm, at91sam9_driver, at91sam9_devclass, 0, 0);
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset
+};
+
+AT91_SOC(AT91_T_SAM9G20, &soc_data);

Modified: head/sys/arm/at91/at91sam9x25.c
==============================================================================
--- head/sys/arm/at91/at91sam9x25.c	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91sam9x25.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$");
 
 #include <arm/at91/at91var.h>
 #include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
 #include <arm/at91/at91_aicreg.h>
 #include <arm/at91/at91sam9x25reg.h>
+#include <arm/at91/at91_pitreg.h>
 #include <arm/at91/at91_pmcreg.h>
 #include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
 
 struct at91sam9x25_softc {
 	device_t dev;
@@ -171,7 +174,7 @@ static void
 at91_identify(driver_t *drv, device_t parent)
 {
 
-	if (soc_data.type == AT91_T_SAM9X5 && soc_data.subtype == AT91_ST_SAM9X25) {
+	if (soc_info.type == AT91_T_SAM9X5 && soc_info.subtype == AT91_ST_SAM9X25) {
 		at91_add_child(parent, 0, "at91sam9x25", 0, 0, 0, -1, 0, 0);
 		at91_cpu_add_builtin_children(parent);
 	}
@@ -284,3 +287,10 @@ static driver_t at91sam9x25_driver = {
 static devclass_t at91sam9x25_devclass;
 
 DRIVER_MODULE(at91sam9x25, atmelarm, at91sam9x25_driver, at91sam9x25_devclass, 0, 0);
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset
+};
+
+AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data);

Added: head/sys/arm/at91/at91soc.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/at91/at91soc.c	Wed Jul 11 20:17:14 2012	(r238376)
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2012 Warner Losh.  All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
+
+SET_DECLARE(at91_socs, const struct at91_soc);
+
+struct at91_soc_data *
+at91_match_soc(enum at91_soc_type type, enum at91_soc_subtype subtype)
+{
+	const struct at91_soc **socp;
+
+	SET_FOREACH(socp, at91_socs) {
+		if ((*socp)->soc_type != type)
+			continue;
+		if ((*socp)->soc_subtype != AT91_ST_ANY &&
+		    (*socp)->soc_subtype != subtype)
+			continue;
+		return (*socp)->soc_data;
+	}
+	return NULL;
+}

Added: head/sys/arm/at91/at91soc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/at91/at91soc.h	Wed Jul 11 20:17:14 2012	(r238376)
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2012 Warner Losh.  All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
+ */
+
+/* $FreeBSD$ */
+
+#ifndef _ARM_AT91_AT91SOC_H_
+#define _ARM_AT91_AT91SOC_H_
+
+#include <sys/linker_set.h>
+
+struct at91_soc {
+	enum at91_soc_type	soc_type;	/* Family of mail type of SoC */
+	enum at91_soc_subtype 	soc_subtype;	/* More specific soc, if any */
+	struct at91_soc_data	*soc_data;
+};
+ 
+// Make varadic
+#define AT91_SOC(type, data)			\
+	static struct at91_soc this_soc = {	\
+		.soc_type = type,		\
+		.soc_subtype = AT91_ST_ANY,	\
+		.soc_data = data,		\
+	};					\
+	DATA_SET(at91_socs, this_soc);
+
+#define AT91_SOC_SUB(type, subtype, data)	\
+	static struct at91_soc this_soc = {	\
+		.soc_type = type,		\
+		.soc_subtype = subtype,		\
+		.soc_data = data,		\
+	};					\
+	DATA_SET(at91_socs, this_soc);
+
+struct at91_soc_data *at91_match_soc(enum at91_soc_type, enum at91_soc_subtype);
+
+#endif /* _ARM_AT91_AT91SOC_H_ */

Modified: head/sys/arm/at91/at91var.h
==============================================================================
--- head/sys/arm/at91/at91var.h	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/at91var.h	Wed Jul 11 20:17:14 2012	(r238376)
@@ -74,6 +74,7 @@ enum at91_soc_type {
 };
 
 enum at91_soc_subtype {
+	AT91_ST_ANY = -1,	/* Match any type */
 	AT91_ST_NONE = 0,
 	/* AT91RM9200 */
 	AT91_ST_RM9200_BGA,
@@ -104,6 +105,11 @@ enum at91_soc_family {
 typedef void (*DELAY_t)(int);
 typedef void (*cpu_reset_t)(void);
 
+struct at91_soc_data {
+	DELAY_t		soc_delay;
+	cpu_reset_t	soc_reset;
+};
+
 struct at91_soc_info {
 	enum at91_soc_type type;
 	enum at91_soc_subtype subtype;
@@ -111,11 +117,10 @@ struct at91_soc_info {
 	uint32_t cidr;
 	uint32_t exid;
 	char name[AT91_SOC_NAME_MAX];
-	DELAY_t delay;
-	cpu_reset_t reset;
+	struct at91_soc_data *soc_data;
 };
 
-extern struct at91_soc_info soc_data;
+extern struct at91_soc_info soc_info;
 
 static inline int at91_is_rm92(void);
 static inline int at91_is_sam9(void);
@@ -126,28 +131,28 @@ static inline int
 at91_is_rm92(void)
 {
 
-	return (soc_data.type == AT91_T_RM9200);
+	return (soc_info.type == AT91_T_RM9200);
 }
 
 static inline int
 at91_is_sam9(void)
 {
 
-	return (soc_data.family == AT91_FAMILY_SAM9);
+	return (soc_info.family == AT91_FAMILY_SAM9);
 }
 
 static inline int
 at91_is_sam9xe(void)
 {
 
-	return (soc_data.family == AT91_FAMILY_SAM9XE);
+	return (soc_info.family == AT91_FAMILY_SAM9XE);
 }
 
 static inline int
 at91_cpu_is(u_int cpu)
 {
 
-	return (soc_data.type == cpu);
+	return (soc_info.type == cpu);
 }
 
 void at91_add_child(device_t dev, int prio, const char *name, int unit,

Modified: head/sys/arm/at91/files.at91
==============================================================================
--- head/sys/arm/at91/files.at91	Wed Jul 11 19:54:21 2012	(r238375)
+++ head/sys/arm/at91/files.at91	Wed Jul 11 20:17:14 2012	(r238376)
@@ -27,6 +27,7 @@ arm/at91/uart_dev_at91usart.c	optional	u
 #
 # All the "systems on a chip" we support
 #
+arm/at91/at91soc.c		standard
 arm/at91/at91rm9200.c		optional	at91rm9200
 arm/at91/at91sam9260.c		optional	at91sam9260
 arm/at91/at91sam9g20.c		optional	at91sam9g20



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207112017.q6BKHFZK063176>