diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 760c040..e344fea 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -78,12 +78,6 @@ 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
  * has changed or not. So it is possible to reread an 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 f5f43a6..1f8955a 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <serial.h>
 #include <stdio_dev.h>
 #include <post.h>
@@ -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
@@ -46,6 +52,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 caf2cc4..c3e800a 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -39,6 +39,7 @@
  * a new assogiation in the ".callbacks" environment variable.
  */
 #define ENV_CALLBACK_LIST_STATIC ENV_CALLBACK_VAR ":callbacks," \
+	"baudrate:baudrate," \
 	"bootfile:bootfile," \
 	CONFIG_ENV_CALLBACK_LIST_STATIC
 
