Consolidate bootcount code into drivers/bootcount

This patch moves all bootcount implementations into a common
directory: drivers/bootcount. The generic bootcount driver
is now usable not only by powerpc platforms, but others as well.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Heiko Schocher <hs@denx.de>
Cc: Valentin Longchamp <valentin.longchamp@keymile.com>
Cc: Christian Riesch <christian.riesch@omicron.at>
Cc: Manfred Rudigier <manfred.rudigier@omicron.at>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
Tested-by: Valentin Longchamp <valentin.longchamp@keymile.com>
Tested-by: Christian Riesch <christian.riesch@omicron.at>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Mike Frysinger <vapier@gentoo.org>
diff --git a/drivers/bootcount/bootcount_ram.c b/drivers/bootcount/bootcount_ram.c
new file mode 100644
index 0000000..8655af7
--- /dev/null
+++ b/drivers/bootcount/bootcount_ram.c
@@ -0,0 +1,72 @@
+/*
+ * (C) Copyright 2010
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+const ulong patterns[]      = {	0x00000000,
+				0xFFFFFFFF,
+				0xFF00FF00,
+				0x0F0F0F0F,
+				0xF0F0F0F0};
+const ulong NBR_OF_PATTERNS = sizeof(patterns) / sizeof(*patterns);
+const ulong OFFS_PATTERN    = 3;
+const ulong REPEAT_PATTERN  = 1000;
+
+void bootcount_store(ulong a)
+{
+	ulong *save_addr;
+	ulong size = 0;
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
+		size += gd->bd->bi_dram[i].size;
+	save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
+	writel(a, save_addr);
+	writel(BOOTCOUNT_MAGIC, &save_addr[1]);
+
+	for (i = 0; i < REPEAT_PATTERN; i++)
+		writel(patterns[i % NBR_OF_PATTERNS],
+			&save_addr[i + OFFS_PATTERN]);
+
+}
+
+ulong bootcount_load(void)
+{
+	ulong *save_addr;
+	ulong size = 0;
+	ulong counter = 0;
+	int i, tmp;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
+		size += gd->bd->bi_dram[i].size;
+	save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
+
+	counter = readl(&save_addr[0]);
+
+	/* Is the counter reliable, check in the big pattern for bit errors */
+	for (i = 0; (i < REPEAT_PATTERN) && (counter != 0); i++) {
+		tmp = readl(&save_addr[i + OFFS_PATTERN]);
+		if (tmp != patterns[i % NBR_OF_PATTERNS])
+			counter = 0;
+	}
+	return counter;
+}