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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to