diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 1f4dad3..4684e55 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	:= $(obj)libinput.o
 
 COBJS-$(CONFIG_I8042_KBD) += i8042.o
+COBJS-$(CONFIG_TEGRA2_KEYBOARD) += tegra-kbc.o
 ifdef CONFIG_PS2KBD
 COBJS-y += keyboard.o pc_keyb.o
 COBJS-$(CONFIG_PS2MULT) += ps2mult.o ps2ser.o
diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c
new file mode 100644
index 0000000..7a45440
--- /dev/null
+++ b/drivers/input/tegra-kbc.c
@@ -0,0 +1,626 @@
+/*
+ *  (C) Copyright 2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * 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
+ */
+#define DEBUG
+#include <common.h>
+#include <malloc.h>
+#include <stdio_dev.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/timer.h>
+#include <tegra-kbc.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DEVNAME "tegra-kbc"
+
+enum {
+	KBC_MAX_ROW		= 16,
+	KBC_MAX_COL		= 8,
+	KBC_KEY_COUNT		= KBC_MAX_ROW * KBC_MAX_COL,
+	KBC_MAX_GPIO		= 24,
+	KBC_MAX_KPENT		= 8,	/* size of keypress entry queue */
+};
+
+enum KEYS {
+	KEY_FIRST_MODIFIER = 220,
+	KEY_RIGHT_CTRL = KEY_FIRST_MODIFIER,
+	KEY_LEFT_CTRL,
+	KEY_FN,
+	KEY_SHIFT,
+};
+
+/* KBC row scan time and delay for beginning the row scan (in usecs) */
+#define KBC_ROW_SCAN_TIME	16
+#define KBC_ROW_SCAN_DLY	5
+
+/*  uses a 32KHz clock so a cycle = 1/32Khz */
+#define KBC_CYCLE_IN_USEC	DIV_ROUND_UP(1000, 32)
+
+#define KBC_FIFO_TH_CNT_SHIFT(cnt)	(cnt << 14)
+#define KBC_DEBOUNCE_CNT_SHIFT(cnt)	(cnt << 4)
+#define KBC_CONTROL_FIFO_CNT_INT_EN	(1 << 3)
+#define KBC_CONTROL_KBC_EN		(1 << 0)
+#define KBC_INT_FIFO_CNT_INT_STATUS	(1 << 2)
+#define KBC_KPENT_VALID	(1 << 7)
+
+#define KBC_RPT_DLY	20
+#define KBC_RPT_RATE	4
+
+/*
+ * Use a simple FIFO to convert some keys into escape sequences and to handle
+ * testc vs getc.  The FIFO length must be a power of two.  Currently, four
+ * characters is the smallest power of two that is large enough to contain all
+ * generated escape sequences.
+ */
+#define KBC_FIFO_LENGTH	(1 << 2)
+
+static struct keyb {
+	/*
+	 * Information about keycode mappings. The plain_keycode array must
+	 * exist but the others may be NULL in which case they are not
+	 * decoded.
+	 */
+	const u8 *plain_keycode;	/* key code for each row / column */
+	const u8 *shift_keycode;	/* ...when shift held down */
+	const u8 *fn_keycode;		/* ...when Fn held down */
+	const u8 *ctrl_keycode;		/* ...when ctrl held down */
+
+	struct kbc_tegra *kbc;		/* tegra keyboard controller */
+	int prev_fifo[KBC_MAX_KPENT];	/* keys left over from last scan */
+	int prev_cnt;			/* number of keys left over */
+	unsigned char prev_key;		/* previously decoded key */
+	unsigned int rpt_dly;		/* delay until next key repeat */
+	unsigned char repeat_key;	/* the key being held down */
+	unsigned char inited;		/* 1 if keyboard has been inited */
+	int fifo[KBC_FIFO_LENGTH];	/* key fifo, with decoded keys */
+	int fifo_read;			/* Key fifo read pointer */
+	int fifo_write;			/* Key fifo write pointer */
+	unsigned int repoll_time;	/* next time to poll keyboard (us) */
+
+	/*
+	 * After init we must wait a short time before polling the keyboard.
+	 * This gives the tegra keyboard controller time to react after reset
+	 * and lets us grab keys pressed during reset.
+	 */
+	unsigned int init_dly;		/* Delay before we can read keyboard */
+	unsigned long start_time;	/* Time that we inited (in us) */
+} config;
+
+
+static int tegra_kbc_keycode(struct keyb *config, int r, int c,
+			     int modifier)
+{
+	int entry = r * KBC_MAX_COL + c;
+
+	if (modifier == KEY_FN && config->fn_keycode)
+		return config->fn_keycode[entry];
+
+	/* Put ctrl keys ahead of shift */
+	else if ((modifier == KEY_LEFT_CTRL || modifier == KEY_RIGHT_CTRL)
+			&& config->ctrl_keycode)
+		return config->ctrl_keycode[entry];
+	else if (modifier == KEY_SHIFT && config->shift_keycode)
+		return config->shift_keycode[entry];
+	else
+		return config->plain_keycode[entry];
+}
+
+/* determines if current keypress configuration can cause key ghosting */
+static int is_ghost_key_config(int *rows_val, int *cols_val, int valid)
+{
+	int i, j, key_in_same_col = 0, key_in_same_row = 0;
+
+	/*
+	 * Matrix keyboard designs are prone to keyboard ghosting.
+	 * Ghosting occurs if there are 3 keys such that -
+	 * any 2 of the 3 keys share a row, and any 2 of them share a column.
+	 */
+	for (i = 0; i < valid; i++) {
+		/*
+		 * Find 2 keys such that one key is in the same row
+		 * and the other is in the same column as the i-th key.
+		 */
+		for (j = i + 1; j < valid; j++) {
+			if (cols_val[j] == cols_val[i])
+				key_in_same_col = 1;
+			if (rows_val[j] == rows_val[i])
+				key_in_same_row = 1;
+		}
+	}
+
+	if (key_in_same_col && key_in_same_row)
+		return 1;
+	else
+		return 0;
+}
+
+/* reads the keyboard fifo for current keypresses. */
+static int tegra_kbc_find_keys(struct keyb *config, int *fifo)
+{
+	int rows_val[KBC_MAX_KPENT], cols_val[KBC_MAX_KPENT];
+	u32 kp_ent_val[(KBC_MAX_KPENT + 3) / 4];
+	u32 *kp_ents = kp_ent_val;
+	u32 kp_ent = 0;
+	int i, j, k, valid = 0;
+	int modifier = 0;
+
+	for (i = 0; i < ARRAY_SIZE(kp_ent_val); i++)
+		kp_ent_val[i] = readl(&config->kbc->kp_ent[i]);
+
+	valid = 0;
+	for (i = 0; i < KBC_MAX_KPENT; i++) {
+		if (!(i&3))
+			kp_ent = *kp_ents++;
+
+		if (kp_ent & KBC_KPENT_VALID) {
+			cols_val[valid] = kp_ent & 0x7;
+			rows_val[valid++] = (kp_ent >> 3) & 0xf;
+		}
+		kp_ent >>= 8;
+	}
+	for (i = 0; i < valid; i++) {
+		k = tegra_kbc_keycode(config, rows_val[i], cols_val[i], 0);
+		if (KEY_IS_MODIFIER(k)) {
+			modifier = k;
+			break;
+		}
+	}
+
+	/* For a ghost key config, ignore the keypresses for this iteration. */
+	if ((valid >= 3) && is_ghost_key_config(rows_val, cols_val, valid))
+		return KBC_MAX_KPENT + 1;
+
+	j = 0;
+	for (i = 0; i < valid; i++) {
+		k = tegra_kbc_keycode(config, rows_val[i], cols_val[i],
+				      modifier);
+		/* Key modifiers (Fn and Shift) will not be part of the fifo */
+		if (k && (k != -1))
+			fifo[j++] = k;
+	}
+
+	return j;
+}
+
+static void process_keys(struct keyb *config, int fifo[], int cnt)
+{
+	int prev_key_in_fifo = 0;
+	char key = config->prev_key;
+	int i, j;
+
+	/*
+	 * If multiple keys are pressed such that it results in * 2 or more
+	 * unmodified keys, we will determine the newest key and report
+	 * that to the upper layer.
+	 */
+	for (i = 0; i < cnt; i++) {
+		for (j = 0; j < config->prev_cnt; j++) {
+			if (fifo[i] == config->prev_fifo[j])
+				break;
+		}
+		/* Found a new key. */
+		if (j == config->prev_cnt) {
+			key = fifo[i];
+			break;
+		}
+		if (config->prev_key == fifo[i])
+			prev_key_in_fifo = 1;
+	}
+	/*
+	 * Keys were released and FIFO does not contain * the previous
+	 * reported key. So report a null key.
+	 */
+	if (i == cnt && !prev_key_in_fifo)
+		key = 0;
+
+	for (i = 0; i < cnt; i++)
+		config->prev_fifo[i] = fifo[i];
+	config->prev_cnt = cnt;
+	config->prev_key = key;
+}
+
+/* processes all the keypresses in fifo and returns a single key */
+static int tegra_kbc_get_single_char(struct keyb *config, u32 fifo_cnt)
+{
+	int fifo[KBC_MAX_KPENT] = {0};
+	int cnt;
+
+	if (fifo_cnt) {
+		do {
+			cnt = tegra_kbc_find_keys(config, fifo);
+			/* If this is a ghost key combo, report no change */
+			if (cnt <= KBC_MAX_KPENT)
+				process_keys(config, fifo, cnt);
+		} while (!config->prev_key && --fifo_cnt);
+	} else {
+		config->prev_cnt = 0;
+		config->prev_key = 0;
+	}
+
+	udelay((fifo_cnt == 1) ? config->repoll_time : 1000);
+
+	return config->prev_key;
+}
+
+/* manages keyboard hardware registers on keypresses and returns a key.*/
+static unsigned char tegra_kbc_get_char(struct keyb *config)
+{
+	struct kbc_tegra *kbc = config->kbc;
+	u32 val, ctl;
+	char key = 0;
+
+	/*
+	 * Until all keys are released, defer further processing to
+	 * the polling loop.
+	 */
+	ctl = readl(&kbc->control);
+	ctl &= ~KBC_CONTROL_FIFO_CNT_INT_EN;
+	writel(ctl, &kbc->control);
+
+	/*
+	 * Quickly bail out & reenable interrupts if the interrupt source
+	 * wasn't fifo count threshold
+	 */
+	val = readl(&kbc->interrupt);
+	writel(val, &kbc->interrupt);
+
+	if (val & KBC_INT_FIFO_CNT_INT_STATUS)
+		key = tegra_kbc_get_single_char(config, (val >> 4) & 0xf);
+
+	ctl |= KBC_CONTROL_FIFO_CNT_INT_EN;
+	writel(ctl, &kbc->control);
+
+	return key;
+}
+
+/* handles key repeat delay and key repeat rate.*/
+static int kbd_fetch_char(struct keyb *config, int test)
+{
+	unsigned char key;
+
+	do {
+		key = tegra_kbc_get_char(config);
+		if (!key) {
+			config->repeat_key = 0;
+			if (test)
+				break;
+			else
+				continue;
+		}
+
+		/* This logic takes care of the repeat rate */
+		if ((key != config->repeat_key) || !(config->rpt_dly--))
+			break;
+	} while (1);
+
+	if (key == config->repeat_key) {
+		config->rpt_dly = KBC_RPT_RATE;
+	} else {
+		config->rpt_dly = KBC_RPT_DLY;
+		config->repeat_key = key;
+	}
+
+	return key;
+}
+
+/*
+ * Return true if there are no characters in the FIFO.
+ */
+static int kbd_fifo_empty(struct keyb *config)
+{
+	return config->fifo_read == config->fifo_write;
+}
+
+/*
+ * Return number of characters of free space in the FIFO.
+ */
+static int kbd_fifo_free_space(struct keyb *config)
+{
+	return KBC_FIFO_LENGTH - (config->fifo_write - config->fifo_read);
+}
+
+/*
+ * Insert a character into the FIFO.  Calling this function when the FIFO is
+ * full will overwrite the oldest character in the FIFO.
+ */
+static void kbd_fifo_insert(struct keyb *config, int key)
+{
+	int index = config->fifo_write & (KBC_FIFO_LENGTH - 1);
+
+	assert(kbd_fifo_free_space(config) > 0);
+
+	config->fifo[index] = key;
+
+	config->fifo_write++;
+}
+
+/*
+ * Remove a character from the FIFO, it is an error to call this function when
+ * the FIFO is empty.
+ */
+static int kbd_fifo_remove(struct keyb *config)
+{
+	int index = config->fifo_read & (KBC_FIFO_LENGTH - 1);
+	int key   = config->fifo[index];
+
+	assert(!kbd_fifo_empty(config));
+
+	config->fifo_read++;
+
+	return key;
+}
+
+/*
+ * Given a keycode, convert it to the sequence of characters that U-Boot expects
+ * to recieve from its input devices and insert the characters into the FIFO.
+ * If the keycode is 0, ignore it.  Currently this function will only ever add
+ * at most three characters to the FIFO, so it is always safe to call when the
+ * FIFO is empty.
+ */
+static void kbd_fifo_refill(struct keyb *config, int key)
+{
+	switch (key) {
+	/*
+	 * We need to deal with a zero keycode value here because the
+	 * testc call can call us with zero if no key is pressed.
+	 */
+	case 0x00:
+		break;
+
+	/*
+	 * Generate escape sequences for arrow keys.  Additional escape
+	 * sequences can be added to the switch statements, but it may
+	 * be better in the future t0 use the top bit of the keycode to
+	 * indicate a key that generates an escape sequence.  Then the
+	 * outer switch could turn into an "if (key & 0x80)".
+	 */
+	case 0x1C:
+	case 0x1D:
+	case 0x1E:
+	case 0x1F:
+		kbd_fifo_insert(config, 0x1B); /* Escape */
+		kbd_fifo_insert(config, '[');
+
+		switch (key) {
+		case 0x1C:
+			kbd_fifo_insert(config, 'D');
+			break;
+		case 0x1D:
+			kbd_fifo_insert(config, 'C');
+			break;
+		case 0x1E:
+			kbd_fifo_insert(config, 'A');
+			break;
+		case 0x1F:
+			kbd_fifo_insert(config, 'B');
+			break;
+		}
+		break;
+
+	/*
+	 * All other keycodes can be treated as characters as is and
+	 * are inserted into the FIFO directly.
+	 */
+	default:
+		kbd_fifo_insert(config, key);
+		break;
+	}
+}
+
+static void kbd_wait_for_fifo_init(struct keyb *config)
+{
+	/*
+	 * In order to detect keys pressed on boot, wait for the hardware to
+	 * complete scanning the keys. This includes time to transition from
+	 * Wkup mode to Continous polling mode and the repoll time. We can
+	 * deduct the time thats already elapsed.
+	 */
+	if (!config->inited) {
+		unsigned long elapsed_time;
+		long delay;
+
+		elapsed_time = timer_get_us() - config->start_time;
+		delay = config->init_dly + config->repoll_time - elapsed_time;
+		if (delay > 0)
+			udelay(delay);
+
+		config->inited = 1;
+	}
+}
+
+static int kbd_testc(void)
+{
+	kbd_wait_for_fifo_init(&config);
+
+	if (kbd_fifo_empty(&config))
+		kbd_fifo_refill(&config, kbd_fetch_char(&config, 1));
+
+	return !kbd_fifo_empty(&config);
+}
+
+static int kbd_getc(void)
+{
+	if (kbd_fifo_empty(&config))
+		kbd_fifo_refill(&config, kbd_fetch_char(&config, 0));
+
+	return kbd_fifo_remove(&config);
+}
+
+/* configures keyboard GPIO registers to use the rows and columns */
+static void config_kbc(struct kbc_tegra *kbc)
+{
+	int i;
+
+	for (i = 0; i < KBC_MAX_GPIO; i++) {
+		u32 row_cfg, col_cfg;
+		u32 r_shift = 5 * (i % 6);
+		u32 c_shift = 4 * (i % 8);
+		u32 r_mask = 0x1f << r_shift;
+		u32 c_mask = 0xf << c_shift;
+		u32 r_offs = i / 6;
+		u32 c_offs = i / 8;
+
+		row_cfg = readl(&kbc->row_cfg[r_offs]);
+		col_cfg = readl(&kbc->col_cfg[c_offs]);
+
+		row_cfg &= ~r_mask;
+		col_cfg &= ~c_mask;
+
+		if (i < KBC_MAX_ROW)
+			row_cfg |= ((i << 1) | 1) << r_shift;
+		else
+			col_cfg |= (((i - KBC_MAX_ROW) << 1) | 1) << c_shift;
+
+		writel(row_cfg, &kbc->row_cfg[r_offs]);
+		writel(col_cfg, &kbc->col_cfg[c_offs]);
+	}
+}
+
+static int tegra_kbc_open(void)
+{
+	unsigned int scan_time_rows, debounce_cnt, rpt_cnt;
+	struct kbc_tegra *kbc = config.kbc;
+	u32 val = 0;
+
+	config_kbc(kbc);
+
+	/*
+	 * The time delay between two consecutive reads of the FIFO is
+	 * the sum of the repeat time and the time taken for scanning
+	 * the rows. There is an additional delay before the row scanning
+	 * starts. The repoll delay is computed in microseconds.
+	 */
+	rpt_cnt = 5 * DIV_ROUND_UP(1000, KBC_CYCLE_IN_USEC);
+	debounce_cnt = 2;
+	scan_time_rows = (KBC_ROW_SCAN_TIME + debounce_cnt) * KBC_MAX_ROW;
+	config.repoll_time = KBC_ROW_SCAN_DLY + scan_time_rows + rpt_cnt;
+	config.repoll_time = config.repoll_time * KBC_CYCLE_IN_USEC;
+
+	writel(rpt_cnt, &kbc->rpt_dly);
+
+	val = KBC_DEBOUNCE_CNT_SHIFT(debounce_cnt);
+	val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */
+	val |= KBC_CONTROL_FIFO_CNT_INT_EN;  /* interrupt on FIFO threshold */
+	val |= KBC_CONTROL_KBC_EN;     /* enable */
+
+	writel(val, &kbc->control);
+
+	config.init_dly = readl(&kbc->init_dly) * KBC_CYCLE_IN_USEC;
+	config.start_time = timer_get_us();
+
+	return 0;
+}
+
+void config_kbc_pinmux(void)
+{
+	enum pmux_pingrp pingrp[] = {PINGRP_KBCA, PINGRP_KBCB, PINGRP_KBCC,
+				     PINGRP_KBCD, PINGRP_KBCE, PINGRP_KBCF};
+	int i;
+
+	for (i = 0; i < (sizeof(pingrp)/sizeof(pingrp[0])); i++) {
+		pinmux_tristate_disable(pingrp[i]);
+		pinmux_set_func(pingrp[i], PMUX_FUNC_KBC);
+		pinmux_set_pullupdown(pingrp[i], PMUX_PULL_UP);
+	}
+}
+
+static int fdt_decode_kbc(const void *blob, int node, struct keyb *config)
+{
+	config->kbc = (struct kbc_tegra *)fdtdec_get_addr(blob, node, "reg");
+	config->plain_keycode = fdtdec_locate_byte_array(blob, node,
+				"keycode-plain", KBC_KEY_COUNT);
+	config->shift_keycode = fdtdec_locate_byte_array(blob, node,
+				"keycode-shift", KBC_KEY_COUNT);
+	config->fn_keycode = fdtdec_locate_byte_array(blob, node,
+				"keycode-fn", KBC_KEY_COUNT);
+	config->ctrl_keycode = fdtdec_locate_byte_array(blob, node,
+				"keycode-ctrl", KBC_KEY_COUNT);
+	if (!config->plain_keycode) {
+		debug("%s: cannot find keycode-plain map\n", __func__);
+		return -1;
+	}
+	return 0;
+}
+
+int drv_keyboard_init(void)
+{
+	int error;
+	struct stdio_dev kbddev;
+	char *stdinname;
+
+#ifdef CONFIG_OF_CONTROL
+	int	node;
+
+	node = fdtdec_next_compatible(gd->fdt_blob, 0,
+					  COMPAT_NVIDIA_TEGRA20_KBC);
+	if (node < 0) {
+		debug("%s: cannot locate keyboard node\n", __func__);
+		return node;
+	}
+	if (fdt_decode_kbc(gd->fdt_blob, node, &config))
+		return -1;
+#else
+#error "Tegra keyboard driver requires FDT definitions"
+#endif
+	config.rpt_dly = KBC_RPT_DLY;
+
+	config_kbc_pinmux();
+
+	/*
+	 * All of the Tegra board use the same clock configuration for now.
+	 * This can be moved to the board specific configuration if that
+	 * changes.
+	 */
+	clock_enable(PERIPH_ID_KBC);
+
+	stdinname = getenv("stdin");
+	memset(&kbddev, 0, sizeof(kbddev));
+	strcpy(kbddev.name, DEVNAME);
+	kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+	kbddev.putc = NULL;
+	kbddev.puts = NULL;
+	kbddev.getc = kbd_getc;
+	kbddev.tstc = kbd_testc;
+	kbddev.start = tegra_kbc_open;
+
+	error = stdio_register(&kbddev);
+	if (!error) {
+		/* check if this is the standard input device */
+		if (strcmp(stdinname, DEVNAME) == 0) {
+			/* reassign the console */
+			if (OVERWRITE_CONSOLE)
+				return 1;
+
+			error = console_assign(stdin, DEVNAME);
+			if (!error)
+				return 0;
+			else
+				return error;
+		}
+		return 1;
+	}
+
+	return error;
+}
diff --git a/include/fdtdec.h b/include/fdtdec.h
index f72d219..9a61611 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -58,6 +58,7 @@ struct fdt_memory {
 enum fdt_compat_id {
 	COMPAT_UNKNOWN,
 	COMPAT_NVIDIA_TEGRA20_USB,	/* Tegra2 USB port */
+	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra2 Keyboard */
 
 	COMPAT_COUNT,
 };
diff --git a/include/tegra-kbc.h b/include/tegra-kbc.h
new file mode 100644
index 0000000..7803f10
--- /dev/null
+++ b/include/tegra-kbc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __include_tegra_kbc_h__
+#define __include_tegra_kbc_h__
+
+#include <common.h>
+
+#define KEY_IS_MODIFIER(key) ((key) >= KEY_FIRST_MODIFIER)
+
+struct kbc_tegra {
+	u32 control;
+	u32 interrupt;
+	u32 row_cfg[4];
+	u32 col_cfg[3];
+	u32 timeout_cnt;
+	u32 init_dly;
+	u32 rpt_dly;
+	u32 kp_ent[2];
+	u32 row_mask[16];
+};
+
+#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console(void);
+#define OVERWRITE_CONSOLE overwrite_console()
+#else
+#define OVERWRITE_CONSOLE 0
+#endif /* CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE */
+
+#endif /* __include_tegra_kbc_h__ */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 90db53c..6db814a 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -38,6 +38,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(UNKNOWN, "<none>"),
 	COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
+	COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
 };
 
 /**
