summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/lib/armlinux.c2
-rw-r--r--arch/arm/lib/board.c84
-rw-r--r--board/scb9328/Makefile1
-rw-r--r--board/scb9328/scb9328.c28
-rw-r--r--board/scb9328/u-boot.lds69
-rw-r--r--board/scb9328/u-boot.lds.S63
-rw-r--r--common/cmd_mem.c5
-rw-r--r--common/mtdpart.c14
-rw-r--r--cpu/arm920t/cpu.c5
-rw-r--r--cpu/arm920t/imx/interrupts.c5
-rw-r--r--drivers/cfi_flash.c5
-rw-r--r--drivers/net/dm9000.c28
-rw-r--r--include/asm-arm/u-boot-arm.h1
-rw-r--r--include/asm-generic/u-boot.lds.h11
-rw-r--r--include/configs/scb9328.h3
-rw-r--r--include/driver.h13
-rw-r--r--include/init.h16
-rw-r--r--include/net.h7
-rw-r--r--lib_generic/misc.c39
-rw-r--r--net/eth.c62
-rw-r--r--net/net.c2
21 files changed, 276 insertions, 187 deletions
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index 5657541d3a..df5a61bdd1 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -248,7 +248,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
cleanup_before_linux ();
- theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
+ theKernel (0, CONFIG_ARCH_NUMBER, CONFIG_BOOT_PARAMS);
}
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 52241a8a1c..acb6910405 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -39,6 +39,7 @@
*/
#include <common.h>
+#include <init.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
@@ -70,11 +71,10 @@ static ulong mem_malloc_start = 0;
static ulong mem_malloc_end = 0;
static ulong mem_malloc_brk = 0;
-static
-void mem_malloc_init (ulong dest_addr)
+static void mem_malloc_init (void)
{
- mem_malloc_start = dest_addr;
- mem_malloc_end = dest_addr + CFG_MALLOC_LEN;
+ mem_malloc_start = _armboot_start - CFG_MALLOC_LEN;
+ mem_malloc_end = _armboot_start;
mem_malloc_brk = mem_malloc_start;
memset ((void *) mem_malloc_start, 0,
@@ -102,17 +102,6 @@ void *sbrk (ptrdiff_t increment)
* but let's get it working (again) first...
*/
-static int init_baudrate (void)
-{
- char tmp[64]; /* long enough for environment variables */
- int i = getenv_r ("baudrate", tmp, sizeof (tmp));
- gd->bd->bi_baudrate = gd->baudrate = (i > 0)
- ? (int) simple_strtoul (tmp, NULL, 10)
- : CONFIG_BAUDRATE;
-
- return (0);
-}
-
static int display_banner (void)
{
printf ("\n\n%s\n\n", version_string);
@@ -172,41 +161,19 @@ static int display_dram_config (void)
*/
typedef int (init_fnc_t) (void);
-extern int mem_init(void);
-extern int partition_init(void);
-
-int print_cpuinfo (void); /* test-only */
-
init_fnc_t *init_sequence[] = {
- cpu_init, /* basic cpu dependent setup */
- board_init, /* basic board dependent setup */
- interrupt_init, /* set up exceptions */
- env_init, /* initialize environment */
- init_baudrate, /* initialze baudrate settings */
- serial_init, /* serial communications setup */
- console_init_f, /* stage 1 init of console */
-#ifdef CONFIG_DRIVER_CFI
- flash_init,
-#endif
- partition_init,
-#ifdef CONFIG_CMD_MEMORY
- mem_init,
-#endif
display_banner, /* say that we are here */
-#if defined(CONFIG_DISPLAY_CPUINFO)
- print_cpuinfo, /* display cpu info (and speed) */
-#endif
-#if defined(CONFIG_DISPLAY_BOARDINFO)
- checkboard, /* display board info */
-#endif
- dram_init, /* configure available RAM banks */
display_dram_config,
NULL,
};
+extern initcall_t __u_boot_initcalls_start[], __u_boot_initcalls_end[];
+
void start_armboot (void)
{
- init_fnc_t **init_fnc_ptr;
+ initcall_t *initcall;
+ int result;
+
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif
@@ -223,39 +190,28 @@ void start_armboot (void)
monitor_flash_len = _bss_start - _armboot_start;
/* armboot_start is defined in the board-specific linker script */
- mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
+ mem_malloc_init();
- for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-// serial_putc(i++ + 'a');
- if ((*init_fnc_ptr)() != 0) {
- hang ();
- }
- }
+ env_init(); /* initialize environment */
+ serial_init(); /* serial communications setup */
+ console_init_f(); /* stage 1 init of console */
-#if (CONFIG_COMMANDS & CFG_CMD_NAND)
- puts ("NAND: ");
- nand_init(); /* go init the NAND */
-#endif
+ for (initcall = __u_boot_initcalls_start; initcall < __u_boot_initcalls_end; initcall++) {
+ result = (*initcall)();
+ if (result)
+ hang();
+ }
+
+ display_banner();
/* initialize environment */
env_relocate ();
jumptable_init ();
-#if defined(CONFIG_MISC_INIT_R)
- /* miscellaneous platform dependent initialisations */
- misc_init_r ();
-#endif
-
/* enable exceptions */
enable_interrupts ();
-#ifdef BOARD_LATE_INIT
- board_late_init ();
-#endif
-#ifdef CONFIG_NET
- eth_initialize(gd->bd);
-#endif
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
diff --git a/board/scb9328/Makefile b/board/scb9328/Makefile
index 3ea2ae775b..72dc0f5cd0 100644
--- a/board/scb9328/Makefile
+++ b/board/scb9328/Makefile
@@ -2,3 +2,4 @@
obj-y += lowlevel_init.o
obj-y += scb9328.o
+extra-y += u-boot.lds
diff --git a/board/scb9328/scb9328.c b/board/scb9328/scb9328.c
index 7becbb32d9..001342091e 100644
--- a/board/scb9328/scb9328.c
+++ b/board/scb9328/scb9328.c
@@ -21,6 +21,7 @@
#include <common.h>
#include <net.h>
#include <cfi_flash.h>
+#include <init.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -45,19 +46,24 @@ static struct device_d sdram_dev = {
.size = 16 * 1024 * 1024,
};
-int board_init (void)
-{
- gd->bd->bi_arch_number = MACH_TYPE_SCB9328;
- gd->bd->bi_boot_params = 0x08000100;
+static struct device_d dm9000_dev = {
+ .name = "dm9000",
+ .id = "eth0",
- return 0;
-}
+ .type = DEVICE_TYPE_ETHER,
+};
-int dram_init (void)
-{
+static int scb9328_devices_init(void) {
register_device(&cfi_dev);
register_device(&sdram_dev);
+ register_device(&dm9000_dev);
+ return 0;
+}
+
+device_initcall(scb9328_devices_init);
+static int late_init (void)
+{
#if ( CONFIG_NR_DRAM_BANKS > 0 )
gd->bd->bi_dram[0].start = SCB9328_SDRAM_1;
gd->bd->bi_dram[0].size = SCB9328_SDRAM_1_SIZE;
@@ -75,10 +81,8 @@ int dram_init (void)
gd->bd->bi_dram[3].size = SCB9328_SDRAM_4_SIZE;
#endif
-#ifdef CONFIG_DRIVER_NET_DM9000
- eth_set_current(&dm9000_eth);
-#endif
-
return 0;
}
+late_initcall(late_init);
+
diff --git a/board/scb9328/u-boot.lds b/board/scb9328/u-boot.lds
index 1d1669cdea..7af965d110 100644
--- a/board/scb9328/u-boot.lds
+++ b/board/scb9328/u-boot.lds
@@ -1,57 +1,38 @@
-/*
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
- . = 0x00000000;
+ . = 0x00000000;
- . = ALIGN(4);
- .text :
- {
- cpu/arm920t/start.o (.text)
- *(.text)
- }
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm920t/start.o (.text)
+ *(.text)
+ }
- . = ALIGN(4);
- .rodata : { *(.rodata) }
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
- . = ALIGN(4);
- .data : { *(.data) }
+ . = ALIGN(4);
+ .data : { *(.data) }
- . = ALIGN(4);
- .got : { *(.got) }
+ . = ALIGN(4);
+ .got : { *(.got) }
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
- . = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss) }
- _end = .;
+ __u_boot_initcalls_start = .;
+ .u_boot_initcalls : { *(.initcall.0) *(.initcall.1) *(.initcall.2) *(.initcall.3) *(.initcall.4) *(.initcall.5) *(.initcall.6) *(.initcall.7) }
+ __u_boot_initcalls_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
}
diff --git a/board/scb9328/u-boot.lds.S b/board/scb9328/u-boot.lds.S
new file mode 100644
index 0000000000..c450497e75
--- /dev/null
+++ b/board/scb9328/u-boot.lds.S
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <asm-generic/u-boot.lds.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm920t/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ __u_boot_initcalls_start = .;
+ .u_boot_initcalls : { INITCALLS }
+ __u_boot_initcalls_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+}
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 978c21c256..ab58f28ef0 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -29,6 +29,7 @@
#include <common.h>
#include <command.h>
+#include <init.h>
#include <driver.h>
#include <malloc.h>
@@ -770,7 +771,7 @@ struct driver_d ram_drv = {
.write = mem_write,
};
-int mem_init(void)
+static int mem_init(void)
{
rw_buf = malloc(RW_BUF_SIZE);
if(!rw_buf) {
@@ -784,6 +785,8 @@ int mem_init(void)
return 0;
}
+device_initcall(mem_init);
+
U_BOOT_CMD(
md, 3, 0, do_mem_md,
"md - memory display\n",
diff --git a/common/mtdpart.c b/common/mtdpart.c
index e967ae7975..2fc1c5e0f9 100644
--- a/common/mtdpart.c
+++ b/common/mtdpart.c
@@ -1,6 +1,7 @@
#include <common.h>
#include <command.h>
+#include <init.h>
#include <driver.h>
#include <malloc.h>
@@ -11,6 +12,8 @@ struct partition {
struct device_d *parent;
struct device_d device;
+
+ char name[16];
};
#if 0
@@ -60,7 +63,7 @@ int mtd_part_do_parse_one (struct partition *part, const char *str, char **endp)
return -1;
}
- memcpy(buf, str, end - str);
+ memcpy(part->name, str, end - str);
end++;
}
@@ -77,7 +80,6 @@ int mtd_part_do_parse_one (struct partition *part, const char *str, char **endp)
strcpy(part->device.name, "partition");
part->device.size = size;
-// printf("part: name=%10s size=0x%08x %s\n", part->device.name, size, ro ? "ro":"");
return 0;
}
@@ -187,7 +189,10 @@ U_BOOT_CMD(
int part_probe (struct device_d *dev)
{
-// printf("%s: devname: %s devid: %s drvname: %s\n",__FUNCTION__, dev->name, dev->id, dev->driver->name);
+ struct partition *part = dev->platform_data;
+
+ printf("registering partition %s on device %s (size=0x%08x, name=%s)\n",
+ dev->id, part->parent->id, dev->size, part->name);
return 0;
}
@@ -223,8 +228,9 @@ static struct driver_d part_driver = {
.erase = part_erase,
};
-int partition_init(void)
+static int partition_init(void)
{
return register_driver(&part_driver);
}
+device_initcall(partition_init);
diff --git a/cpu/arm920t/cpu.c b/cpu/arm920t/cpu.c
index f93bf57e2b..8bcf0fafaf 100644
--- a/cpu/arm920t/cpu.c
+++ b/cpu/arm920t/cpu.c
@@ -31,6 +31,7 @@
#include <common.h>
#include <command.h>
+#include <init.h>
#include <arm920t.h>
#ifdef CONFIG_USE_IRQ
@@ -89,7 +90,7 @@ static void cp_delay (void)
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
-int cpu_init (void)
+static int cpu_init (void)
{
/*
* setup up stacks if necessary
@@ -101,6 +102,8 @@ int cpu_init (void)
return 0;
}
+core_initcall(cpu_init);
+
int cleanup_before_linux (void)
{
/*
diff --git a/cpu/arm920t/imx/interrupts.c b/cpu/arm920t/imx/interrupts.c
index 30fbd3ff0f..16376b8ca0 100644
--- a/cpu/arm920t/imx/interrupts.c
+++ b/cpu/arm920t/imx/interrupts.c
@@ -30,6 +30,7 @@
*/
#include <common.h>
+#include <init.h>
#include <clock.h>
#include <arm920t.h>
#include <asm/arch/imx-regs.h>
@@ -45,7 +46,7 @@ static struct clocksource cs = {
.shift = 10,
};
-int interrupt_init (void)
+static int clocksource_init (void)
{
int i;
/* setup GP Timer 1 */
@@ -64,6 +65,8 @@ int interrupt_init (void)
return 0;
}
+core_initcall(clocksource_init);
+
/*
* Reset the cpu by setting up the watchdog timer and let him time out
*/
diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c
index 1e0db22840..8b30ae6615 100644
--- a/drivers/cfi_flash.c
+++ b/drivers/cfi_flash.c
@@ -39,6 +39,7 @@
#include <asm/byteorder.h>
#include <environment.h>
#include <clock.h>
+#include <init.h>
#include <cfi_flash.h>
/*
@@ -521,11 +522,13 @@ static struct driver_d cfi_driver = {
.info = cfi_info,
};
-int flash_init(void)
+static int cfi_init(void)
{
return register_driver(&cfi_driver);
}
+device_initcall(cfi_init);
+
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index d675327da1..98171222e9 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -44,9 +44,11 @@ TODO: Homerun NIC and longrun NIC are not functional, only internal at the
#include <common.h>
#include <command.h>
+#include <driver.h>
#include <clock.h>
#include <miiphy.h>
#include <net.h>
+#include <init.h>
#include <asm/io.h>
#include "dm9000.h"
@@ -133,7 +135,7 @@ static void phy_write(int reg, u16 value)
DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
}
-int dm9000_probe(void)
+int dm9000_check_id(void)
{
u32 id_val;
id_val = DM9000_ior(DM9000_VIDL);
@@ -158,13 +160,15 @@ static void dm9000_reset(void)
udelay(1000); /* delay 1ms */
}
-int dm9000_eth_init(struct eth_device *ndev, bd_t * bd)
+int dm9000_probe(struct device_d *dev)
{
+// struct eth_device *ndev = dev->type_data;
+
printf("dm9000_eth_init()\n");
/* RESET device */
dm9000_reset();
- dm9000_probe();
+ dm9000_check_id();
/* Program operating register */
DM9000_iow(DM9000_NCR, 0x0); /* only intern phy supported by now */
@@ -180,7 +184,7 @@ int dm9000_eth_init(struct eth_device *ndev, bd_t * bd)
}
-int dm9000_eth_open(struct eth_device *ndev, bd_t * bd)
+int dm9000_eth_open(struct eth_device *ndev)
{
int lnk, i = 0, ctl;
@@ -426,7 +430,6 @@ printf("dm9000_set_mac_address\n");
}
struct eth_device dm9000_eth = {
- .init = dm9000_eth_init,
.open = dm9000_eth_open,
.send = dm9000_eth_send,
.recv = dm9000_eth_rx,
@@ -435,3 +438,18 @@ struct eth_device dm9000_eth = {
.set_mac_address = dm9000_set_mac_address,
};
+static struct driver_d dm9000_driver = {
+ .name = "dm9000",
+ .probe = dm9000_probe,
+ .type = DEVICE_TYPE_ETHER,
+ .type_data = &dm9000_eth,
+};
+
+static int dm9000_init(void)
+{
+ register_driver(&dm9000_driver);
+ return 0;
+}
+
+device_initcall(dm9000_init);
+
diff --git a/include/asm-arm/u-boot-arm.h b/include/asm-arm/u-boot-arm.h
index efff5e9902..e21d164aa5 100644
--- a/include/asm-arm/u-boot-arm.h
+++ b/include/asm-arm/u-boot-arm.h
@@ -37,7 +37,6 @@ extern ulong IRQ_STACK_START; /* top of IRQ stack */
extern ulong FIQ_STACK_START; /* top of FIQ stack */
/* cpu/.../cpu.c */
-int cpu_init(void);
int cleanup_before_linux(void);
/* board/.../... */
diff --git a/include/asm-generic/u-boot.lds.h b/include/asm-generic/u-boot.lds.h
new file mode 100644
index 0000000000..a0ecf727ab
--- /dev/null
+++ b/include/asm-generic/u-boot.lds.h
@@ -0,0 +1,11 @@
+
+#define INITCALLS \
+ *(.initcall.0) \
+ *(.initcall.1) \
+ *(.initcall.2) \
+ *(.initcall.3) \
+ *(.initcall.4) \
+ *(.initcall.5) \
+ *(.initcall.6) \
+ *(.initcall.7)
+
diff --git a/include/configs/scb9328.h b/include/configs/scb9328.h
index 629d863a06..632939ec54 100644
--- a/include/configs/scb9328.h
+++ b/include/configs/scb9328.h
@@ -87,6 +87,9 @@
#define PRECHARGE_CMD 0x910a8200
#define AUTOREFRESH_CMD 0xa10a8200
+#define CONFIG_ARCH_NUMBER MACH_TYPE_SCB9328
+#define CONFIG_BOOT_PARAMS 0x08000100
+
/*
* SDRAM Memory Map
*/
diff --git a/include/driver.h b/include/driver.h
index 23e84a04c3..848f844ec2 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -8,6 +8,11 @@
struct memarea_info;
+#define DEVICE_TYPE_UNKNOWN 0
+#define DEVICE_TYPE_ETHER 1
+#define DEVICE_TYPE_STDIO 2
+#define MAX_DEVICE_TYPE 2
+
struct device_d {
char name[MAX_DRIVER_NAME];
char id[MAX_DRIVER_NAME];
@@ -26,6 +31,8 @@ struct device_d {
struct driver_d *driver;
struct device_d *next;
+
+ unsigned long type;
};
struct driver_d {
@@ -40,6 +47,9 @@ struct driver_d {
void (*info) (struct device_d *);
void (*shortinfo) (struct device_d *);
+
+ unsigned long type;
+ void *type_data;
};
#define RW_SIZE(x) (x)
@@ -59,5 +69,8 @@ ssize_t erase(struct device_d *dev, size_t count, unsigned long offset);
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
+int register_device_type_handler(int(*handle)(struct device_d *), ulong device_type);
+//void unregister_device_type_handler(struct device_d *);
+
#endif /* DRIVER_H */
diff --git a/include/init.h b/include/init.h
new file mode 100644
index 0000000000..06d1174e6f
--- /dev/null
+++ b/include/init.h
@@ -0,0 +1,16 @@
+#ifndef _INIT_H
+#define _INIT_H
+
+typedef int (*initcall_t)(void);
+
+#define __define_initcall(level,fn,id) \
+ static initcall_t __initcall_##fn##id __attribute__((__used__)) \
+ __attribute__((__section__(".initcall." level))) = fn
+
+
+#define core_initcall(fn) __define_initcall("0",fn,0)
+#define device_initcall(fn) __define_initcall("5",fn,5)
+#define late_initcall(fn) __define_initcall("6",fn,6)
+
+#endif /* _INIT_H */
+
diff --git a/include/net.h b/include/net.h
index 99b3d7d982..6c78e1d628 100644
--- a/include/net.h
+++ b/include/net.h
@@ -98,8 +98,8 @@ struct eth_device {
int iobase;
int state;
- int (*init) (struct eth_device*, bd_t*);
- int (*open) (struct eth_device*, bd_t*);
+ int (*init) (struct eth_device*);
+ int (*open) (struct eth_device*);
int (*send) (struct eth_device*, volatile void* pachet, int length);
int (*recv) (struct eth_device*);
void (*halt) (struct eth_device*);
@@ -110,7 +110,6 @@ struct eth_device {
void *priv;
};
-extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */
extern int eth_register(struct eth_device* dev);/* Register network device */
extern void eth_try_another(int first_restart); /* Change the device */
extern struct eth_device *eth_get_dev(void); /* get the current device MAC */
@@ -118,7 +117,7 @@ extern struct eth_device *eth_get_dev_by_name(char *devname); /* get device */
extern int eth_get_dev_index (void); /* get the device index */
extern void eth_set_enetaddr(int num, char* a); /* Set new MAC address */
-extern int eth_init(bd_t *bis); /* Initialize the device */
+extern int eth_init(void); /* Initialize the device */
extern int eth_send(volatile void *packet, int length); /* Send a packet */
extern int eth_rx(void); /* Check for received packets */
extern void eth_halt(void); /* stop SCC */
diff --git a/lib_generic/misc.c b/lib_generic/misc.c
index 28c4c482c2..10b96aad31 100644
--- a/lib_generic/misc.c
+++ b/lib_generic/misc.c
@@ -26,6 +26,17 @@ int cmd_get_data_size(char* arg, int default_size)
return default_size;
}
+static ulong device_handler[MAX_DEVICE_TYPE];
+
+int register_device_type_handler(int(*handler)(struct device_d *), ulong device_type)
+{
+ device_handler[device_type] = (ulong)handler;
+
+ /* FIXME: cycle through devices */
+
+ return 0;
+}
+
static struct device_d *first_device = NULL;
static struct driver_d *first_driver = NULL;
@@ -83,8 +94,21 @@ U_BOOT_CMD(
static int match(struct driver_d *drv, struct device_d *dev)
{
+ int(*handler)(struct device_d *);
+
if (strcmp(dev->name, drv->name))
return -1;
+ if (dev->type != drv->type)
+ return -1;
+ if(drv->probe(dev))
+ return -1;
+
+ dev->driver = drv;
+
+ handler = device_handler[dev->type];
+
+ if(handler)
+ (*handler)(dev);
return 0;
}
@@ -110,10 +134,8 @@ int register_device(struct device_d *new_device)
drv = first_driver;
while(drv) {
- if (!match(drv, new_device) && !drv->probe(new_device)) {
- new_device->driver = drv;
+ if (!match(drv, new_device))
break;
- }
drv = drv->next;
}
@@ -186,8 +208,7 @@ int register_driver(struct driver_d *new_driver)
dev = first_device;
while (dev) {
- if (!match(new_driver, dev) && !new_driver->probe(dev))
- dev->driver = new_driver;
+ match(new_driver, dev);
dev = dev->next;
}
@@ -357,12 +378,16 @@ out:
ssize_t read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
{
- return dev->driver->read(dev, buf, count, offset, flags);
+ if (dev->driver->read)
+ return dev->driver->read(dev, buf, count, offset, flags);
+ return -1;
}
ssize_t write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
{
- return dev->driver->write(dev, buf, count, offset, flags);
+ if (dev->driver->write)
+ return dev->driver->write(dev, buf, count, offset, flags);
+ return -1;
}
ssize_t erase(struct device_d *dev, size_t count, unsigned long offset)
diff --git a/net/eth.c b/net/eth.c
index dc9442b56c..ba3b9320eb 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -23,6 +23,8 @@
#include <common.h>
#include <command.h>
+#include <driver.h>
+#include <init.h>
#include <net.h>
#include <miiphy.h>
@@ -38,13 +40,13 @@ struct eth_device * eth_get_current(void)
return eth_current;
}
-int eth_init(bd_t *bis)
+int eth_init(void)
{
if (!eth_current)
return 0;
- eth_current->open(eth_current, bis);
+ eth_current->open(eth_current);
return 1;
}
@@ -75,39 +77,26 @@ int eth_rx(void)
return eth_current->recv(eth_current);
}
-extern int at91rm9200_miiphy_initialize(bd_t *bis);
-extern int emac4xx_miiphy_initialize(bd_t *bis);
-extern int mcf52x2_miiphy_initialize(bd_t *bis);
-extern int ns7520_miiphy_initialize(bd_t *bis);
-
-int eth_initialize(bd_t *bis)
+static int eth_handle(struct device_d *dev)
{
unsigned char ethaddr_tmp[20];
unsigned char *ethaddr;
+ struct eth_device *ndev = dev->driver->type_data;
char *e = NULL;
int i;
- if (!eth_current) {
- printf("%s: no eth device set\n", __FUNCTION__);
- return -1;
- }
-
- if (eth_current->init(eth_current, bis)) {
- printf("failed to initialize network device\n");
- return -1;
- }
-
- if (!eth_current->get_mac_address) {
+ printf("%s: %s\n",__FUNCTION__, dev->id);
+ if (!ndev->get_mac_address) {
printf("no get_mac_address found for current eth device\n");
return -1;
}
- ethaddr = eth_current->enetaddr;
+ ethaddr = ndev->enetaddr;
/* Try to get a MAC address from the eeprom set 'ethaddr' to it.
* If this fails we rely on 'ethaddr' being set by the user.
*/
- if (eth_current->get_mac_address(eth_current, ethaddr) == 0) {
+ if (ndev->get_mac_address(ndev, ethaddr) == 0) {
sprintf (ethaddr_tmp, "%02X:%02X:%02X:%02X:%02X:%02X",
ethaddr[0], ethaddr[1], ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]);
printf("got MAC address from EEPROM: %s\n",ethaddr_tmp);
@@ -121,30 +110,23 @@ int eth_initialize(bd_t *bis)
printf("got MAC address from Environment: %s\n",ethaddr);
for(i = 0; i < 6; i++) {
- eth_current->enetaddr[i] = ethaddr ? simple_strtoul (ethaddr, &e, 16) : 0;
+ ndev->enetaddr[i] = ethaddr ? simple_strtoul (ethaddr, &e, 16) : 0;
if (ethaddr) {
ethaddr = (*e) ? e + 1 : e;
}
- eth_current->set_mac_address(eth_current, eth_current->enetaddr);
+ ndev->set_mac_address(eth_current, ndev->enetaddr);
}
}
-#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
- miiphy_init();
-#endif
-
-#if defined(CONFIG_DRIVER_NET_AT91_ETHER)
- at91rm9200_miiphy_initialize(bis);
-#endif
-#if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) \
- && !defined(CONFIG_AP1000) && !defined(CONFIG_405)
- emac4xx_miiphy_initialize(bis);
-#endif
-#if defined(CONFIG_MCF52x2)
- mcf52x2_miiphy_initialize(bis);
-#endif
-#if defined(CONFIG_NETARM)
- ns7520_miiphy_initialize(bis);
-#endif
+ eth_current = ndev;
return 0;
}
+
+int eth_initialize(void)
+{
+ register_device_type_handler(&eth_handle, DEVICE_TYPE_ETHER);
+
+ return 0;
+}
+
+core_initcall(eth_initialize);
diff --git a/net/net.c b/net/net.c
index 5355172cde..18e65fe77f 100644
--- a/net/net.c
+++ b/net/net.c
@@ -287,7 +287,7 @@ NetLoop(proto_t protocol)
NetArpWaitTxPacketSize = 0;
}
- if (eth_init(bd) < 0)
+ if (eth_init() < 0)
return -1;
restart: