From 32057717e06a4e703fdf3774671cea14554de76b Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:27 -0600 Subject: env: Add a baudrate env handler Remove the hard-coded baudrate handler and use a callback instead Signed-off-by: Joe Hershberger --- common/cmd_nvedit.c | 47 --------------------------------- drivers/serial/serial.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/env_callback.h | 1 + 3 files changed, 71 insertions(+), 47 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 874baef865..df136cfa35 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -77,12 +77,6 @@ ulong load_addr = CONFIG_SYS_LOAD_ADDR; /* Default Load Address */ ulong save_addr; /* Default Save Address */ ulong save_size; /* Default Save Size (in bytes) */ -/* - * Table with supported baudrates (defined in config_xyz.h) - */ -static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; -#define N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0])) - /* * This variable is incremented on each do_env_set(), so it can * be used via get_env_id() as an indication, if the environment @@ -275,47 +269,6 @@ int env_change_ok(const ENTRY *item, const char *newval, enum env_op op, } } #endif - /* - * When we change baudrate, or we are doing an env default -a - * (which will erase all variables prior to calling this), - * we want the baudrate to actually change - for real. - */ - if (op != env_op_create || /* variable exists */ - (flag & H_NOCLEAR) == 0) { /* or env is clear */ - /* - * Switch to new baudrate if new baudrate is supported - */ - if (strcmp(name, "baudrate") == 0) { - int baudrate = simple_strtoul(newval, NULL, 10); - int i; - for (i = 0; i < N_BAUDRATES; ++i) { - if (baudrate == baudrate_table[i]) - break; - } - if (i == N_BAUDRATES) { - if ((flag & H_FORCE) == 0) - printf("## Baudrate %d bps not " - "supported\n", baudrate); - return 1; - } - if (gd->baudrate == baudrate) { - /* If unchanged, we just say it's OK */ - return 0; - } - printf("## Switch baudrate to %d bps and" - "press ENTER ...\n", baudrate); - udelay(50000); - gd->baudrate = baudrate; -#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) - gd->bd->bi_baudrate = baudrate; -#endif - - serial_setbrg(); - udelay(50000); - while (getc() != '\r') - ; - } - } /* * Some variables should be updated when the corresponding diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index f5f43a6ddc..1f8955a0fd 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -32,6 +33,11 @@ DECLARE_GLOBAL_DATA_PTR; static struct serial_device *serial_devices; static struct serial_device *serial_current; +/* + * Table with supported baudrates (defined in config_xyz.h) + */ +static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; +#define N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0])) /** * serial_null() - Void registration routine of a serial driver @@ -45,6 +51,70 @@ static void serial_null(void) { } +/** + * on_baudrate() - Update the actual baudrate when the env var changes + * + * This will check for a valid baudrate and only apply it if valid. + */ +static int on_baudrate(const char *name, const char *value, enum env_op op, + int flags) +{ + int i; + int baudrate; + + switch (op) { + case env_op_create: + case env_op_overwrite: + /* + * Switch to new baudrate if new baudrate is supported + */ + baudrate = simple_strtoul(value, NULL, 10); + + /* Not actually changing */ + if (gd->baudrate == baudrate) + return 0; + + for (i = 0; i < N_BAUDRATES; ++i) { + if (baudrate == baudrate_table[i]) + break; + } + if (i == N_BAUDRATES) { + if ((flags & H_FORCE) == 0) + printf("## Baudrate %d bps not supported\n", + baudrate); + return 1; + } + if ((flags & H_INTERACTIVE) != 0) { + printf("## Switch baudrate to %d" + " bps and press ENTER ...\n", baudrate); + udelay(50000); + } + + gd->baudrate = baudrate; +#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) + gd->bd->bi_baudrate = baudrate; +#endif + + serial_setbrg(); + + udelay(50000); + + if ((flags & H_INTERACTIVE) != 0) + while (1) { + if (getc() == '\r') + break; + } + + return 0; + case env_op_delete: + printf("## Baudrate may not be deleted\n"); + return 1; + default: + return 0; + } +} +U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); + /** * serial_initfunc() - Forward declare of driver registration routine * @name: Name of the real driver registration routine. diff --git a/include/env_callback.h b/include/env_callback.h index bce01362ce..2f5048fa49 100644 --- a/include/env_callback.h +++ b/include/env_callback.h @@ -39,6 +39,7 @@ * a new association in the ".callbacks" environment variable. */ #define ENV_CALLBACK_LIST_STATIC ENV_CALLBACK_VAR ":callbacks," \ + "baudrate:baudrate," \ "bootfile:bootfile," \ CONFIG_ENV_CALLBACK_LIST_STATIC -- cgit v1.2.3