From d5ef856b4628a4531c1627dec100eeff15e8b31e Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 17 Jan 2012 19:20:11 +0000
Subject: [PATCH 2/7] Main bcm2708 linux port

Signed-off-by: popcornmix <popcornmix@gmail.com>
---
 arch/arm/Kconfig                                   |   14 +
 arch/arm/Makefile                                  |    1 +
 arch/arm/boot/compressed/Makefile                  |    8 +-
 arch/arm/boot/compressed/divdi3.c                  |  338 +++++
 arch/arm/boot/compressed/longlong.h                |  151 ++
 arch/arm/configs/bcmrpi_cutdown_defconfig          | 1558 ++++++++++++++++++++
 arch/arm/kernel/armksyms.c                         |    4 +
 arch/arm/lib/Makefile                              |    3 +-
 arch/arm/lib/divdi3.c                              |  338 +++++
 arch/arm/lib/lib1funcs.S                           |   27 +
 arch/arm/lib/longlong.h                            |  151 ++
 arch/arm/mach-bcm2708/Kconfig                      |   25 +
 arch/arm/mach-bcm2708/Makefile                     |    8 +
 arch/arm/mach-bcm2708/Makefile.boot                |    3 +
 arch/arm/mach-bcm2708/armctrl.c                    |  399 +++++
 arch/arm/mach-bcm2708/armctrl.h                    |   27 +
 arch/arm/mach-bcm2708/bcm2708.c                    |  658 +++++++++
 arch/arm/mach-bcm2708/bcm2708.h                    |   51 +
 arch/arm/mach-bcm2708/bcm2708_gpio.c               |  323 ++++
 arch/arm/mach-bcm2708/clock.c                      |   61 +
 arch/arm/mach-bcm2708/clock.h                      |   24 +
 arch/arm/mach-bcm2708/dma.c                        |  397 +++++
 arch/arm/mach-bcm2708/include/mach/arm_control.h   |  419 ++++++
 arch/arm/mach-bcm2708/include/mach/arm_power.h     |   60 +
 arch/arm/mach-bcm2708/include/mach/clkdev.h        |    7 +
 arch/arm/mach-bcm2708/include/mach/debug-macro.S   |   24 +
 arch/arm/mach-bcm2708/include/mach/dma.h           |   84 ++
 arch/arm/mach-bcm2708/include/mach/entry-macro.S   |   69 +
 arch/arm/mach-bcm2708/include/mach/frc.h           |   38 +
 arch/arm/mach-bcm2708/include/mach/gpio.h          |   48 +
 arch/arm/mach-bcm2708/include/mach/hardware.h      |   28 +
 arch/arm/mach-bcm2708/include/mach/io.h            |   28 +
 arch/arm/mach-bcm2708/include/mach/irqs.h          |  190 +++
 arch/arm/mach-bcm2708/include/mach/irqs.h.orig     |  185 +++
 arch/arm/mach-bcm2708/include/mach/memory.h        |   59 +
 arch/arm/mach-bcm2708/include/mach/platform.h      |  210 +++
 arch/arm/mach-bcm2708/include/mach/platform.h.orig |  210 +++
 arch/arm/mach-bcm2708/include/mach/power.h         |   26 +
 arch/arm/mach-bcm2708/include/mach/system.h        |   53 +
 arch/arm/mach-bcm2708/include/mach/timex.h         |   23 +
 arch/arm/mach-bcm2708/include/mach/uncompress.h    |   49 +
 arch/arm/mach-bcm2708/include/mach/vc_mem.h        |   34 +
 arch/arm/mach-bcm2708/include/mach/vcio.h          |   42 +
 arch/arm/mach-bcm2708/include/mach/vmalloc.h       |   20 +
 arch/arm/mach-bcm2708/power.c                      |  193 +++
 arch/arm/mach-bcm2708/vc_mem.c                     |  467 ++++++
 arch/arm/mach-bcm2708/vcio.c                       |  309 ++++
 arch/arm/mm/Kconfig                                |    2 +-
 arch/arm/mm/alignment.c                            |    6 +-
 arch/arm/mm/proc-v6.S                              |   15 +-
 drivers/mmc/host/Kconfig                           |   29 +
 drivers/mmc/host/Makefile                          |    2 +
 drivers/mmc/host/bcm2708_mci.c                     |  889 +++++++++++
 drivers/mmc/host/bcm2708_mci.h                     |  101 ++
 drivers/mmc/host/sdhci-bcm2708.c                   | 1461 ++++++++++++++++++
 drivers/mmc/host/sdhci.c                           |  623 ++++++---
 drivers/mmc/host/sdhci.h                           |   46 +
 include/linux/mmc/host.h                           |   29 +
 include/linux/mmc/sdhci.h                          |   10 +
 59 files changed, 10481 insertions(+), 176 deletions(-)
 create mode 100644 arch/arm/boot/compressed/divdi3.c
 create mode 100644 arch/arm/boot/compressed/longlong.h
 create mode 100644 arch/arm/configs/bcmrpi_cutdown_defconfig
 create mode 100644 arch/arm/lib/divdi3.c
 create mode 100644 arch/arm/lib/longlong.h
 create mode 100644 arch/arm/mach-bcm2708/Kconfig
 create mode 100644 arch/arm/mach-bcm2708/Makefile
 create mode 100644 arch/arm/mach-bcm2708/Makefile.boot
 create mode 100644 arch/arm/mach-bcm2708/armctrl.c
 create mode 100644 arch/arm/mach-bcm2708/armctrl.h
 create mode 100644 arch/arm/mach-bcm2708/bcm2708.c
 create mode 100644 arch/arm/mach-bcm2708/bcm2708.h
 create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c
 create mode 100644 arch/arm/mach-bcm2708/clock.c
 create mode 100644 arch/arm/mach-bcm2708/clock.h
 create mode 100644 arch/arm/mach-bcm2708/dma.c
 create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_control.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_power.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-bcm2708/include/mach/dma.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-bcm2708/include/mach/frc.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/hardware.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/io.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h.orig
 create mode 100644 arch/arm/mach-bcm2708/include/mach/memory.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h.orig
 create mode 100644 arch/arm/mach-bcm2708/include/mach/power.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/system.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/timex.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_mem.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/vcio.h
 create mode 100644 arch/arm/mach-bcm2708/include/mach/vmalloc.h
 create mode 100644 arch/arm/mach-bcm2708/power.c
 create mode 100644 arch/arm/mach-bcm2708/vc_mem.c
 create mode 100644 arch/arm/mach-bcm2708/vcio.c
 create mode 100644 drivers/mmc/host/bcm2708_mci.c
 create mode 100644 drivers/mmc/host/bcm2708_mci.h
 create mode 100644 drivers/mmc/host/sdhci-bcm2708.c

--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -961,6 +961,20 @@ config PLAT_SPEAR
 	help
 	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
 
+config ARCH_BCM2708
+	bool "Broadcom BCM2708 family"
+	select CPU_V6
+	select ARM_AMBA
+	select HAVE_CLK
+	select CLKDEV_LOOKUP
+	select GENERIC_CLOCKEVENTS
+	select ARM_ERRATA_411920
+	select MACH_BCM2708
+	select VC4
+	select NEED_MACH_MEMORY_H
+	help
+	  This enables support for Broadcom BCM2708 boards.
+
 config ARCH_VT8500
 	bool "VIA/WonderMedia 85xx"
 	select CPU_ARM926T
@@ -1103,6 +1117,7 @@ source "arch/arm/plat-versatile/Kconfig"
 source "arch/arm/mach-vt8500/Kconfig"
 
 source "arch/arm/mach-w90x900/Kconfig"
+source "arch/arm/mach-bcm2708/Kconfig"
 
 # Definitions to make life easier
 config ARCH_ACORN
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -196,6 +196,7 @@ machine-$(CONFIG_MACH_SPEAR310)		:= spea
 machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
 machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
 machine-$(CONFIG_ARCH_ZYNQ)		:= zynq
+machine-$(CONFIG_ARCH_BCM2708)		:= bcm2708
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -147,11 +147,17 @@ LDFLAGS_vmlinux += -X
 LDFLAGS_vmlinux += -T
 
 # For __aeabi_uidivmod
-lib1funcs = $(obj)/lib1funcs.o
+lib1funcs = $(obj)/lib1funcs.o $(obj)/divdi3.o
 
 $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
 	$(call cmd,shipped)
 
+$(obj)/longlong.h: $(srctree)/arch/$(SRCARCH)/lib/longlong.h FORCE
+	$(call cmd,shipped)
+
+$(obj)/divdi3.c: $(srctree)/arch/$(SRCARCH)/lib/divdi3.c $(obj)/longlong.h FORCE
+	$(call cmd,shipped)
+
 # We need to prevent any GOTOFF relocs being used with references
 # to symbols in the .bss section since we cannot relocate them
 # independently from the rest at run time.  This can be achieved by
--- /dev/null
+++ b/arch/arm/boot/compressed/divdi3.c
@@ -0,0 +1,338 @@
+/* 64-bit multiplication and division
+   Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "longlong.h"
+
+#define W_TYPE_SIZE (sizeof(long))
+
+#ifdef __ARMEB__
+struct DWstruct { long high, low;};
+#else
+struct DWstruct { long low, high;};
+#endif
+
+typedef union { struct DWstruct s; long long ll; } DWunion;
+
+/* Prototypes of exported functions.  */
+long long __divdi3 (long long u, long long v);
+long long __moddi3 (long long u, long long v);
+unsigned long long __udivdi3 (unsigned long long u, unsigned long long v);
+unsigned long long __umoddi3 (unsigned long long u, unsigned long long v);
+
+static unsigned long long
+__udivmoddi4 (unsigned long long n, unsigned long long d, unsigned long long *rp)
+{
+  DWunion ww;
+  DWunion nn, dd;
+  DWunion rr;
+  unsigned long d0, d1, n0, n1, n2;
+  unsigned long q0, q1;
+  unsigned long b, bm;
+
+  nn.ll = n;
+  dd.ll = d;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+ 
+	  /* Remainder in n0.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  udiv_qrnnd (q1, n1, 0, n1, d0);
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0 >> bm;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.s.low = n0;
+	      rr.s.high = n1;
+	      *rp = rr.ll;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.s.low = n0;
+		  rr.s.high = n1;
+		  *rp = rr.ll;
+		}
+	    }
+	  else
+	    {
+	      unsigned long m1, m0;
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+		  rr.s.low = (n1 << b) | (n0 >> bm);
+		  rr.s.high = n1 >> bm;
+		  *rp = rr.ll;
+		}
+	    }
+	}
+    }
+
+  ww.s.low = q0;
+  ww.s.high = q1;
+  return ww.ll;
+}
+
+long long
+__divdi3 (long long u, long long v)
+{
+  long c = 0;
+  long long w;
+
+  if (u < 0)
+    {
+      c = ~c;
+      u = -u;
+    }
+  if (v < 0)
+    {
+      c = ~c;
+      v = -v;
+    }
+  w = __udivmoddi4 (u, v, 0);
+  if (c)
+    w = -w;
+  return w;
+}
+
+long long
+__moddi3 (long long u, long long v)
+{
+  long c = 0;
+  long long w;
+
+  if (u < 0)
+    {
+      c = ~c;
+      u = -u;
+    }
+  if (v < 0)
+    v = -v;
+  __udivmoddi4 (u, v, &w);
+  if (c)
+    w = -w;
+  return w;
+}
+
+unsigned long long
+__udivdi3 (unsigned long long u, unsigned long long v)
+{
+  return __udivmoddi4 (u, v, 0);
+}
+
+unsigned long long
+__umoddi3 (unsigned long long u, unsigned long long v)
+{
+  unsigned long long w;
+
+  __udivmoddi4 (u, v, &w);
+  return w;
+}
+
+long long
+__gnu_ldivmod_helper (long long a,
+ 
+		      long long b,
+		      long long *remainder)
+{
+  long long quotient;
+
+  quotient = __divdi3 (a, b);
+  *remainder = a - b * quotient;
+
+  return quotient;
+}
+
+unsigned long long
+
+__gnu_uldivmod_helper (unsigned long long a,
+
+		       unsigned long long b,
+		       unsigned long long *remainder)
+{
+  unsigned long long quotient;
+
+  quotient = __udivdi3 (a, b);
+  *remainder = a - b * quotient;
+  return quotient;
+}
--- /dev/null
+++ b/arch/arm/boot/compressed/longlong.h
@@ -0,0 +1,151 @@
+/* longlong.h -- based on code from gcc-2.95.3
+
+   definitions for mixed size 32/64 bit arithmetic.
+   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+   This definition file 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, or (at your option) any later version.
+
+   This definition file 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.  */
+
+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
+#define USItype unsigned long
+#define SI_TYPE_SIZE sizeof(USItype)
+
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
+/* Define auxiliary asm macros.
+
+   1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
+   multiplies two USItype integers MULTIPLER and MULTIPLICAND,
+   and generates a two-part USItype product in HIGH_PROD and
+   LOW_PROD.
+
+   2) __umulsidi3(a,b) multiplies two USItype integers A and B,
+   and returns a UDItype product.  This is just a variant of umul_ppmm.
+
+   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator) divides a two-word unsigned integer, composed by the
+   integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
+   places the quotient in QUOTIENT and the remainder in REMAINDER.
+   HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
+   If, in addition, the most significant bit of DENOMINATOR must be 1,
+   then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator).  Like udiv_qrnnd but the numbers are signed.  The
+   quotient is rounded towards 0.
+
+   5) count_leading_zeros(count, x) counts the number of zero-bits from
+   the msb to the first non-zero bit.  This is the number of steps X
+   needs to be shifted left to set the msb.  Undefined for X == 0.
+
+   6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+   high_addend_2, low_addend_2) adds two two-word unsigned integers,
+   composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
+   LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
+   LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
+   lost.
+
+   7) sub_ddmmss(high_difference, low_difference, high_minuend,
+   low_minuend, high_subtrahend, low_subtrahend) subtracts two
+   two-word unsigned integers, composed by HIGH_MINUEND_1 and
+   LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
+   respectively.  The result is placed in HIGH_DIFFERENCE and
+   LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
+   and is lost.
+
+   If any of these macros are left undefined for a particular CPU,
+   C macros are used.  */
+
+#if defined (__arm__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("adds	%1, %4, %5					\n\
+	adc	%0, %2, %3"						\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "%r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subs	%1, %4, %5					\n\
+	sbc	%0, %2, %3"						\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)))
+#define umul_ppmm(xh, xl, a, b)                                         \
+  __asm__ ("%@ Inlined umul_ppmm\n"                                     \
+           "umull %r1, %r0, %r2, %r3"                                   \
+                   : "=&r" ((USItype)(xh)),                             \
+                     "=r" ((USItype)(xl))                               \
+                   : "r" ((USItype)(a)),                                \
+                     "r" ((USItype)(b))                                 \
+                   : "r0", "r1")
+#define count_leading_zeros(count, x)                                   \
+  __asm__ ("clz %0, %1" : "=r"(count) : "r"(x))
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+  do {									\
+    USItype __d1, __d0, __q1, __q0;					\
+    USItype __r1, __r0, __m;						\
+    __d1 = __ll_highpart (d);						\
+    __d0 = __ll_lowpart (d);						\
+									\
+    __r1 = (n1) % __d1;							\
+    __q1 = (n1) / __d1;							\
+    __m = (USItype) __q1 * __d0;					\
+    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
+    if (__r1 < __m)							\
+      {									\
+	__q1--, __r1 += (d);						\
+	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+	  if (__r1 < __m)						\
+	    __q1--, __r1 += (d);					\
+      }									\
+    __r1 -= __m;							\
+									\
+    __r0 = __r1 % __d1;							\
+    __q0 = __r1 / __d1;							\
+    __m = (USItype) __q0 * __d0;					\
+    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
+    if (__r0 < __m)							\
+      {									\
+	__q0--, __r0 += (d);						\
+	if (__r0 >= (d))						\
+	  if (__r0 < __m)						\
+	    __q0--, __r0 += (d);					\
+      }									\
+    __r0 -= __m;							\
+									\
+    (q) = (USItype) __q1 * __ll_B | __q0;				\
+    (r) = __r0;								\
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
--- /dev/null
+++ b/arch/arm/configs/bcmrpi_cutdown_defconfig
@@ -0,0 +1,1558 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.1.9 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HAVE_SPARSE_IRQ=y
+CONFIG_GENERIC_IRQ_SHOW=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+# CONFIG_UID16 is not set
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_PRIMA2 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS4 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_TCC_926 is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+CONFIG_ARCH_BCM2708=y
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_ARCH_ZYNQ is not set
+
+#
+# System MMU
+#
+
+#
+# Broadcom BCM2708 Implementations
+#
+CONFIG_MACH_BCM2708=y
+CONFIG_BCM2708_GPIO=y
+CONFIG_BCM2708_VCMEM=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_USE_DOMAINS=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
+CONFIG_ARM_ERRATA_411920=y
+# CONFIG_ARM_ERRATA_364296 is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+CONFIG_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+CONFIG_BCM2708_VCHIQ=y
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+CONFIG_MDIO_BITBANG=m
+# CONFIG_MDIO_GPIO is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_AX88796=m
+# CONFIG_AX88796_93CX6 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=m
+# CONFIG_USB_NET_CDCETHER is not set
+# CONFIG_USB_NET_CDC_EEM is not set
+CONFIG_USB_NET_CDC_NCM=y
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC75XX is not set
+CONFIG_USB_NET_SMSC95XX=y
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_USB_NET_CX82310_ETH is not set
+# CONFIG_USB_NET_KALMIA is not set
+# CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_USB_SIERRA_NET is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_WMT_GE_ROPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_BCM2708=y
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EMS_FF is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+CONFIG_HID_KYE=m
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWII_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_ORTEK=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+# CONFIG_HID_SPEEDLINK is not set
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=m
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=m
+# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_DWCOTG=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+# CONFIG_MMC_SDHCI_PXAV3 is not set
+# CONFIG_MMC_SDHCI_PXAV2 is not set
+CONFIG_MMC_SDHCI_BCM2708=y
+CONFIG_MMC_SDHCI_BCM2708_DMA=y
+# CONFIG_MMC_BCM2708 is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+CONFIG_JBD2=m
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=y
+# CONFIG_FSCACHE_STATS is not set
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+CONFIG_CACHEFILES=y
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFS_FSCACHE=y
+# CONFIG_NFS_USE_LEGACY_DNS is not set
+CONFIG_NFS_USE_KERNEL_DNS=y
+# CONFIG_NFS_USE_NEW_IDMAPPER is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+# CONFIG_CIFS_UPCALL is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DFS_UPCALL is not set
+# CONFIG_CIFS_FSCACHE is not set
+# CONFIG_CIFS_ACL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -46,6 +46,8 @@ extern void __aeabi_lmul(void);
 extern void __aeabi_uidiv(void);
 extern void __aeabi_uidivmod(void);
 extern void __aeabi_ulcmp(void);
+extern void __aeabi_ldivmod(void);
+extern void __aeabi_uldivmod(void);
 
 extern void fpundefinstr(void);
 
@@ -131,6 +133,8 @@ EXPORT_SYMBOL(__aeabi_lmul);
 EXPORT_SYMBOL(__aeabi_uidiv);
 EXPORT_SYMBOL(__aeabi_uidivmod);
 EXPORT_SYMBOL(__aeabi_ulcmp);
+EXPORT_SYMBOL(__aeabi_ldivmod);
+EXPORT_SYMBOL(__aeabi_uldivmod);
 #endif
 
 	/* bitops */
--- /dev/null
+++ b/arch/arm/lib/divdi3.c
@@ -0,0 +1,338 @@
+/* 64-bit multiplication and division
+   Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "longlong.h"
+
+#define W_TYPE_SIZE (sizeof(long))
+
+#ifdef __ARMEB__
+struct DWstruct { long high, low;};
+#else
+struct DWstruct { long low, high;};
+#endif
+
+typedef union { struct DWstruct s; long long ll; } DWunion;
+
+/* Prototypes of exported functions.  */
+long long __divdi3 (long long u, long long v);
+long long __moddi3 (long long u, long long v);
+unsigned long long __udivdi3 (unsigned long long u, unsigned long long v);
+unsigned long long __umoddi3 (unsigned long long u, unsigned long long v);
+
+static unsigned long long
+__udivmoddi4 (unsigned long long n, unsigned long long d, unsigned long long *rp)
+{
+  DWunion ww;
+  DWunion nn, dd;
+  DWunion rr;
+  unsigned long d0, d1, n0, n1, n2;
+  unsigned long q0, q1;
+  unsigned long b, bm;
+
+  nn.ll = n;
+  dd.ll = d;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+ 
+	  /* Remainder in n0.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  udiv_qrnnd (q1, n1, 0, n1, d0);
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0 >> bm;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.s.low = n0;
+	      rr.s.high = n1;
+	      *rp = rr.ll;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.s.low = n0;
+		  rr.s.high = n1;
+		  *rp = rr.ll;
+		}
+	    }
+	  else
+	    {
+	      unsigned long m1, m0;
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+		  rr.s.low = (n1 << b) | (n0 >> bm);
+		  rr.s.high = n1 >> bm;
+		  *rp = rr.ll;
+		}
+	    }
+	}
+    }
+
+  ww.s.low = q0;
+  ww.s.high = q1;
+  return ww.ll;
+}
+
+long long
+__divdi3 (long long u, long long v)
+{
+  long c = 0;
+  long long w;
+
+  if (u < 0)
+    {
+      c = ~c;
+      u = -u;
+    }
+  if (v < 0)
+    {
+      c = ~c;
+      v = -v;
+    }
+  w = __udivmoddi4 (u, v, 0);
+  if (c)
+    w = -w;
+  return w;
+}
+
+long long
+__moddi3 (long long u, long long v)
+{
+  long c = 0;
+  long long w;
+
+  if (u < 0)
+    {
+      c = ~c;
+      u = -u;
+    }
+  if (v < 0)
+    v = -v;
+  __udivmoddi4 (u, v, &w);
+  if (c)
+    w = -w;
+  return w;
+}
+
+unsigned long long
+__udivdi3 (unsigned long long u, unsigned long long v)
+{
+  return __udivmoddi4 (u, v, 0);
+}
+
+unsigned long long
+__umoddi3 (unsigned long long u, unsigned long long v)
+{
+  unsigned long long w;
+
+  __udivmoddi4 (u, v, &w);
+  return w;
+}
+
+long long
+__gnu_ldivmod_helper (long long a,
+ 
+		      long long b,
+		      long long *remainder)
+{
+  long long quotient;
+
+  quotient = __divdi3 (a, b);
+  *remainder = a - b * quotient;
+
+  return quotient;
+}
+
+unsigned long long
+
+__gnu_uldivmod_helper (unsigned long long a,
+
+		       unsigned long long b,
+		       unsigned long long *remainder)
+{
+  unsigned long long quotient;
+
+  quotient = __udivdi3 (a, b);
+  *remainder = a - b * quotient;
+  return quotient;
+}
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -349,6 +349,33 @@ UNWIND(.save {r0, r1, ip, lr}	)
 UNWIND(.fnend)
 ENDPROC(__aeabi_idivmod)
 
+/* Added 64x64 bit division for use with OTG USB driver - multi-precision
+ * arithmetic for RSA encyrption.
+ */
+ENTRY(__aeabi_ldivmod)
+
+        sub     sp, sp, #8
+        stmfd   sp!, {sp, lr}
+        bl      __gnu_ldivmod_helper
+        ldr     lr, [sp, #4]
+        add     sp, sp, #8
+        ldmfd   sp!, {r2, r3}
+        mov     pc, lr
+
+ENDPROC(__aeabi_ldivmod)
+
+ENTRY(__aeabi_uldivmod)
+
+        sub     sp, sp, #8
+        stmfd   sp!, {sp, lr}
+        bl      __gnu_uldivmod_helper
+        ldr     lr, [sp, #4]
+        add     sp, sp, #8
+        ldmfd   sp!, {r2, r3}
+        mov     pc, lr
+
+ENDPROC(__aeabi_uldivmod)
+
 #endif
 
 Ldiv0:
--- /dev/null
+++ b/arch/arm/lib/longlong.h
@@ -0,0 +1,151 @@
+/* longlong.h -- based on code from gcc-2.95.3
+
+   definitions for mixed size 32/64 bit arithmetic.
+   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+   This definition file 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, or (at your option) any later version.
+
+   This definition file 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.  */
+
+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
+#define USItype unsigned long
+#define SI_TYPE_SIZE sizeof(USItype)
+
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
+/* Define auxiliary asm macros.
+
+   1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
+   multiplies two USItype integers MULTIPLER and MULTIPLICAND,
+   and generates a two-part USItype product in HIGH_PROD and
+   LOW_PROD.
+
+   2) __umulsidi3(a,b) multiplies two USItype integers A and B,
+   and returns a UDItype product.  This is just a variant of umul_ppmm.
+
+   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator) divides a two-word unsigned integer, composed by the
+   integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
+   places the quotient in QUOTIENT and the remainder in REMAINDER.
+   HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
+   If, in addition, the most significant bit of DENOMINATOR must be 1,
+   then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+   denominator).  Like udiv_qrnnd but the numbers are signed.  The
+   quotient is rounded towards 0.
+
+   5) count_leading_zeros(count, x) counts the number of zero-bits from
+   the msb to the first non-zero bit.  This is the number of steps X
+   needs to be shifted left to set the msb.  Undefined for X == 0.
+
+   6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+   high_addend_2, low_addend_2) adds two two-word unsigned integers,
+   composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
+   LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
+   LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
+   lost.
+
+   7) sub_ddmmss(high_difference, low_difference, high_minuend,
+   low_minuend, high_subtrahend, low_subtrahend) subtracts two
+   two-word unsigned integers, composed by HIGH_MINUEND_1 and
+   LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
+   respectively.  The result is placed in HIGH_DIFFERENCE and
+   LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
+   and is lost.
+
+   If any of these macros are left undefined for a particular CPU,
+   C macros are used.  */
+
+#if defined (__arm__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("adds	%1, %4, %5					\n\
+	adc	%0, %2, %3"						\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "%r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "%r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subs	%1, %4, %5					\n\
+	sbc	%0, %2, %3"						\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "r" ((USItype) (ah)),					\
+	     "rI" ((USItype) (bh)),					\
+	     "r" ((USItype) (al)),					\
+	     "rI" ((USItype) (bl)))
+#define umul_ppmm(xh, xl, a, b)                                         \
+  __asm__ ("%@ Inlined umul_ppmm\n"                                     \
+           "umull %r1, %r0, %r2, %r3"                                   \
+                   : "=&r" ((USItype)(xh)),                             \
+                     "=r" ((USItype)(xl))                               \
+                   : "r" ((USItype)(a)),                                \
+                     "r" ((USItype)(b))                                 \
+                   : "r0", "r1")
+#define count_leading_zeros(count, x)                                   \
+  __asm__ ("clz %0, %1" : "=r"(count) : "r"(x))
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+  do {									\
+    USItype __d1, __d0, __q1, __q0;					\
+    USItype __r1, __r0, __m;						\
+    __d1 = __ll_highpart (d);						\
+    __d0 = __ll_lowpart (d);						\
+									\
+    __r1 = (n1) % __d1;							\
+    __q1 = (n1) / __d1;							\
+    __m = (USItype) __q1 * __d0;					\
+    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
+    if (__r1 < __m)							\
+      {									\
+	__q1--, __r1 += (d);						\
+	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+	  if (__r1 < __m)						\
+	    __q1--, __r1 += (d);					\
+      }									\
+    __r1 -= __m;							\
+									\
+    __r0 = __r1 % __d1;							\
+    __q0 = __r1 / __d1;							\
+    __m = (USItype) __q0 * __d0;					\
+    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
+    if (__r0 < __m)							\
+      {									\
+	__q0--, __r0 += (d);						\
+	if (__r0 >= (d))						\
+	  if (__r0 < __m)						\
+	    __q0--, __r0 += (d);					\
+      }									\
+    __r0 -= __m;							\
+									\
+    (q) = (USItype) __q1 * __ll_B | __q0;				\
+    (r) = __r0;								\
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
--- /dev/null
+++ b/arch/arm/mach-bcm2708/Kconfig
@@ -0,0 +1,25 @@
+menu "Broadcom BCM2708 Implementations"
+	depends on ARCH_BCM2708
+
+config MACH_BCM2708
+	bool "Broadcom BCM2708 Development Platform"
+	select CPU_V6
+	help
+	  Include support for the Broadcom(R) BCM2708 platform.
+
+config BCM2708_GPIO
+	bool "BCM2708 gpio support"
+	depends on MACH_BCM2708
+	select ARCH_REQUIRE_GPIOLIB
+        default y
+	help
+	  Include support for the Broadcom(R) BCM2708 gpio.
+
+config BCM2708_VCMEM
+	bool "Videocore Memory"
+	depends on MACH_BCM2708
+        default y
+        help
+          Helper for videocore memory access and total size allocation.	   
+
+endmenu
--- /dev/null
+++ b/arch/arm/mach-bcm2708/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-$(CONFIG_MACH_BCM2708) 	+= clock.o bcm2708.o armctrl.o vcio.o power.o dma.o
+obj-$(CONFIG_BCM2708_GPIO)	+= bcm2708_gpio.o
+obj-$(CONFIG_BCM2708_VCMEM)	+= vc_mem.o
+
--- /dev/null
+++ b/arch/arm/mach-bcm2708/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
--- /dev/null
+++ b/arch/arm/mach-bcm2708/armctrl.c
@@ -0,0 +1,399 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/armctrl.c
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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 <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39)
+#include <linux/syscore_ops.h>
+#else
+#include <linux/sysdev.h>
+#endif
+#include <linux/interrupt.h>
+
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include "armctrl.h"
+
+/* For support of kernels >= 3.0 assume only one VIC for now*/
+static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = {
+	INTERRUPT_VC_JPEG,
+	INTERRUPT_VC_USB,
+	INTERRUPT_VC_3D,
+	INTERRUPT_VC_DMA2,
+	INTERRUPT_VC_DMA3,
+	INTERRUPT_VC_I2C,
+	INTERRUPT_VC_SPI,
+	INTERRUPT_VC_I2SPCM,
+	INTERRUPT_VC_SDIO,
+	INTERRUPT_VC_UART,
+	INTERRUPT_VC_ARASANSDIO
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+static void armctrl_mask_irq(struct irq_data *d)
+#else
+static void armctrl_mask_irq(unsigned int irq)
+#endif
+{
+	static const unsigned int disables[4] = {
+		IO_ADDRESS(ARM_IRQ_DIBL1),
+		IO_ADDRESS(ARM_IRQ_DIBL2),
+		IO_ADDRESS(ARM_IRQ_DIBL3),
+		0
+	};
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+	unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
+#else
+	unsigned int data = (unsigned int)get_irq_chip_data(irq);
+#endif
+	writel(1 << (data & 0x1f), __io(disables[(data >> 5) & 0x3]));
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+static void armctrl_unmask_irq(struct irq_data *d)
+#else
+static void armctrl_unmask_irq(unsigned int irq)
+#endif
+{
+	static const unsigned int enables[4] = {
+		IO_ADDRESS(ARM_IRQ_ENBL1),
+		IO_ADDRESS(ARM_IRQ_ENBL2),
+		IO_ADDRESS(ARM_IRQ_ENBL3),
+		0
+	};
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+	unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
+#else
+	unsigned int data = (unsigned int)get_irq_chip_data(irq);
+#endif
+	writel(1 << (data & 0x1f), __io(enables[(data >> 5) & 0x3]));
+}
+
+#if defined(CONFIG_PM)
+
+/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
+
+/* Static defines
+ * struct armctrl_device - VIC PM device (< 3.xx)
+ * @sysdev: The system device which is registered. (< 3.xx)
+ * @irq: The IRQ number for the base of the VIC.
+ * @base: The register base for the VIC.
+ * @resume_sources: A bitmask of interrupts for resume.
+ * @resume_irqs: The IRQs enabled for resume.
+ * @int_select: Save for VIC_INT_SELECT.
+ * @int_enable: Save for VIC_INT_ENABLE.
+ * @soft_int: Save for VIC_INT_SOFT.
+ * @protect: Save for VIC_PROTECT.
+ */
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+struct armctrl_device {
+	struct sys_device sysdev;
+#else
+	struct armctrl_info {
+#endif
+		void __iomem *base;
+		int irq;
+		u32 resume_sources;
+		u32 resume_irqs;
+		u32 int_select;
+		u32 int_enable;
+		u32 soft_int;
+		u32 protect;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+};
+#else
+	} armctrl;
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+
+static struct armctrl_device armctrl_devices[1];
+
+static inline struct armctrl_device *to_vic(struct sys_device *sys)
+{
+	return container_of(sys, struct armctrl_device, sysdev);
+}
+
+static int armctrl_id;
+
+static int armctrl_class_resume(struct sys_device *dev)
+{
+#if 0  // FIXME
+	struct armctrl_device *armctrl = to_vic(dev);
+	void __iomem *base = armctrl->base;
+
+	printk(KERN_DEBUG "%s: resuming armctrl at %p\n", __func__, base);
+
+	writel(armctrl->int_select, base + VIC_INT_SELECT);
+	writel(armctrl->protect, base + VIC_PROTECT);
+
+	/* set the enabled ints and then clear the non-enabled */
+	writel(armctrl->int_enable, base + VIC_INT_ENABLE);
+	writel(~armctrl->int_enable, base + VIC_INT_ENABLE_CLEAR);
+
+	/* and the same for the soft-int register */
+
+	writel(armctrl->soft_int, base + VIC_INT_SOFT);
+	writel(~armctrl->soft_int, base + VIC_INT_SOFT_CLEAR);
+#endif
+	return 0;
+}
+
+static int armctrl_class_suspend(struct sys_device *dev, pm_message_t state)
+{
+#if 0				// FIXME
+	struct armctrl_device *armctrl = to_vic(dev);
+	void __iomem *base = armctrl->base;
+
+	printk(KERN_DEBUG "%s: suspending armctrl at %p\n", __func__, base);
+
+	armctrl->int_select = readl(base + VIC_INT_SELECT);
+	armctrl->int_enable = readl(base + VIC_INT_ENABLE);
+	armctrl->soft_int = readl(base + VIC_INT_SOFT);
+	armctrl->protect = readl(base + VIC_PROTECT);
+
+	/* set the interrupts (if any) that are used for
+	 * resuming the system */
+
+	writel(armctrl->resume_irqs, base + VIC_INT_ENABLE);
+	writel(~armctrl->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
+#endif
+	return 0;
+}
+
+struct sysdev_class armctrl_class = {
+	.name = "armctrl",
+	.suspend = armctrl_class_suspend,
+	.resume = armctrl_class_resume,
+};
+
+#endif // < 2.6.39
+
+static int armctrl_suspend(void)
+{
+	return 0;
+}
+
+static void armctrl_resume(void)
+{
+	return;
+}
+
+
+/**
+ * armctrl_pm_register - Register a VIC for later power management control
+ * @base: The base address of the VIC.
+ * @irq: The base IRQ for the VIC.
+ * @resume_sources: bitmask of interrupts allowed for resume sources.
+ *
+ * For older kernels (< 3.xx) do -
+ * Register the VIC with the system device tree so that it can be notified
+ * of suspend and resume requests and ensure that the correct actions are
+ * taken to re-instate the settings on resume.
+ */
+static void __init armctrl_pm_register(void __iomem * base, unsigned int irq,
+				       u32 resume_sources)
+{
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+	struct armctrl_device *v;
+
+	if (armctrl_id >= ARRAY_SIZE(armctrl_devices))
+		printk(KERN_ERR
+		       "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n",
+		       __func__);
+	else {
+		v = &armctrl_devices[armctrl_id];
+		v->base = base;
+		v->resume_sources = resume_sources;
+		v->irq = irq;
+		armctrl_id++;
+	}
+#else
+	armctrl.base = base;
+	armctrl.resume_sources = resume_sources;
+	armctrl.irq = irq;
+#endif
+}
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+
+/**
+ * armctrl_pm_init - initicall to register VIC pm
+ *
+ * This is called via late_initcall() to register
+ * the resources for the VICs due to the early
+ * nature of the VIC's registration.
+*/
+static int __init armctrl_pm_init(void)
+{
+	struct armctrl_device *dev = armctrl_devices;
+	int err;
+	int id;
+
+	if (armctrl_id == 0)
+		return 0;
+
+	err = sysdev_class_register(&armctrl_class);
+	if (err) {
+		printk(KERN_ERR "%s: cannot register class\n", __func__);
+		return err;
+	}
+
+	for (id = 0; id < armctrl_id; id++, dev++) {
+		dev->sysdev.id = id;
+		dev->sysdev.cls = &armctrl_class;
+
+		err = sysdev_register(&dev->sysdev);
+		if (err) {
+			printk(KERN_ERR "%s: failed to register device\n",
+			       __func__);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+late_initcall(armctrl_pm_init);
+
+#endif // VERSION check
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+static int armctrl_set_wake(struct irq_data *d, unsigned int on)
+#else
+static int armctrl_set_wake(unsigned int irq, unsigned int on)
+#endif
+{
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+	struct armctrl_device *armctrl = &armctrl_devices[0];
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+	unsigned int off = d->irq & 31;
+#else
+	unsigned int off = irq & 31;
+#endif
+	u32 bit = 1 << off;
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+	if (!armctrl)
+		return -EINVAL;
+
+	if (!(bit & armctrl->resume_sources))
+		return -EINVAL;
+
+	if (on)
+		armctrl->resume_irqs |= bit;
+	else
+		armctrl->resume_irqs &= ~bit;
+#else
+	if (!(bit & armctrl.resume_sources))
+		return -EINVAL;
+
+	if (on)
+		armctrl.resume_irqs |= bit;
+	else
+		armctrl.resume_irqs &= ~bit;
+#endif
+
+	return 0;
+}
+
+#else
+static inline void armctrl_pm_register(void __iomem *base, unsigned int irq,
+				       u32 arg1)
+{
+}
+#define armctrl_suspend NULL
+#define armctrl_resume NULL
+#define armctrl_set_wake NULL
+#endif /* CONFIG_PM */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39)
+
+static struct syscore_ops armctrl_syscore_ops = {
+	.suspend = armctrl_suspend,
+        .resume = armctrl_resume,
+};
+
+/**
+ * armctrl_syscore_init - initicall to register VIC pm functions
+ *
+ * This is called via late_initcall() to register
+ * the resources for the VICs due to the early
+ * nature of the VIC's registration.
+*/
+static int __init armctrl_syscore_init(void)
+{
+	register_syscore_ops(&armctrl_syscore_ops);
+	return 0;
+}
+
+late_initcall(armctrl_syscore_init);
+
+#endif
+
+static struct irq_chip armctrl_chip = {
+	.name = "ARMCTRL",
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+	.irq_ack = armctrl_mask_irq,
+	.irq_mask = armctrl_mask_irq,
+	.irq_unmask = armctrl_unmask_irq,
+	.irq_set_wake = armctrl_set_wake,
+#else
+	.ack = armctrl_mask_irq,
+	.mask = armctrl_mask_irq,
+	.unmask = armctrl_unmask_irq,
+	.set_wake = armctrl_set_wake,
+#endif
+};
+
+/**
+ * armctrl_init - initialise a vectored interrupt controller
+ * @base: iomem base address
+ * @irq_start: starting interrupt number, must be muliple of 32
+ * @armctrl_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
+ */
+int __init armctrl_init(void __iomem * base, unsigned int irq_start,
+			u32 armctrl_sources, u32 resume_sources)
+{
+	unsigned int irq;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		unsigned int data = irq;
+		if (irq >= INTERRUPT_JPEG)
+			data = remap_irqs[irq - INTERRUPT_JPEG];
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+		irq_set_chip(irq, &armctrl_chip);
+		irq_set_chip_data(irq, (void *)data);
+		irq_set_handler(irq, handle_level_irq);
+#else
+		set_irq_chip(irq, &armctrl_chip);
+		set_irq_chip_data(irq, (void *)data);
+		set_irq_handler(irq, handle_level_irq);
+#endif
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED);
+	}
+
+	armctrl_pm_register(base, irq_start, resume_sources);
+	return 0;
+}
--- /dev/null
+++ b/arch/arm/mach-bcm2708/armctrl.h
@@ -0,0 +1,27 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/armctrl.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef __BCM2708_ARMCTRL_H
+#define __BCM2708_ARMCTRL_H
+
+extern int __init armctrl_init(void __iomem * base, unsigned int irq_start,
+			       u32 armctrl_sources, u32 resume_sources);
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -0,0 +1,657 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/bcm2708.c
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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 <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/clockchips.h>
+#include <linux/cnt32_to_63.h>
+#include <linux/io.h>
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+#include <linux/clkdev.h>
+#else
+#include <asm/clkdev.h>
+#endif
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/timex.h>
+#include <mach/dma.h>
+#include <mach/vcio.h>
+
+#include "bcm2708.h"
+#include "armctrl.h"
+#include "clock.h"
+
+/* Effectively we have an IOMMU (ARM<->VideoCore map) that is set up to
+ * give us IO access only to 64Mbytes of physical memory (26 bits).  We could
+ * represent this window by setting our dmamasks to 26 bits but, in fact
+ * we're not going to use addresses outside this range (they're not in real
+ * memory) so we don't bother.
+ *
+ * In the future we might include code to use this IOMMU to remap other
+ * physical addresses onto VideoCore memory then the use of 32-bits would be
+ * more legitimate.
+ */
+#define DMA_MASK_BITS_COMMON 32
+
+static void __init bcm2708_init_led(void);
+
+void __init bcm2708_init_irq(void)
+{
+	armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0);
+}
+
+static struct map_desc bcm2708_io_desc[] __initdata = {
+	{
+		.virtual	= IO_ADDRESS(ARMCTRL_BASE),
+		.pfn		= __phys_to_pfn(ARMCTRL_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(UART0_BASE),
+		.pfn		= __phys_to_pfn(UART0_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(UART1_BASE),
+		.pfn		= __phys_to_pfn(UART1_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+#ifdef CONFIG_MMC_BCM2708 /* broadcom legacy SD */
+		.virtual	= IO_ADDRESS(MMCI0_BASE),
+		.pfn		= __phys_to_pfn(MMCI0_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+#endif
+		.virtual	= IO_ADDRESS(DMA_BASE),
+		.pfn		= __phys_to_pfn(DMA_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(MCORE_BASE),
+		.pfn		= __phys_to_pfn(MCORE_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(ST_BASE),
+		.pfn		= __phys_to_pfn(ST_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	 }, {
+		.virtual	= IO_ADDRESS(USB_BASE),
+		.pfn		= __phys_to_pfn(USB_BASE),
+		.length		= SZ_128K,
+		.type		= MT_DEVICE
+	 }, {
+		.virtual        = IO_ADDRESS(PM_BASE),
+		.pfn	        = __phys_to_pfn(PM_BASE),
+		.length	        = SZ_4K,
+		.type	        = MT_DEVICE
+	}, {
+		.virtual	= IO_ADDRESS(GPIO_BASE),
+		.pfn		= __phys_to_pfn(GPIO_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	 }
+};
+
+void __init bcm2708_map_io(void)
+{
+	iotable_init(bcm2708_io_desc, ARRAY_SIZE(bcm2708_io_desc));
+}
+
+unsigned long frc_clock_ticks32(void)
+{
+	/* STC: a free running counter that increments at the rate of 1MHz */
+	return readl(__io_address(ST_BASE+0x04));
+}
+
+unsigned long long frc_clock_ticks63(void)
+{
+	unsigned long t = frc_clock_ticks32();
+	/* For cnt32_to_63 to work correctly we MUST call this routine
+	 * at least once every half-32-bit-wraparound period - that's once
+	 * every 35minutes or so - using it in sched_clock() should ensure this
+	 */
+	return cnt32_to_63(t);
+}
+
+unsigned long long sched_clock(void)
+{
+	return 1000ull * frc_clock_ticks63();
+}
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk ref24_clk = {
+	.rate	= 3000000,  /* The UART is clocked at 3MHz via APB_CLK */
+};
+static struct clk osc_clk = {
+#ifdef CONFIG_ARCH_BCM2708_CHIPIT
+	.rate	= 27000000,
+#else
+	.rate	= 500000000,  /* ARM clock is set from the VideoCore booter */
+#endif
+};
+/* warning - the USB needs a clock > 34MHz */
+
+#ifdef CONFIG_MMC_BCM2708
+static struct clk sdhost_clk = {
+#ifdef CONFIG_ARCH_BCM2708_CHIPIT
+	.rate	=   4000000, /* 4MHz */
+#else
+	.rate	= 250000000, /* 250MHz */
+#endif
+};
+#endif
+
+static struct clk_lookup lookups[] = {
+	{	/* UART0 */
+		.dev_id		= "dev:f1",
+		.clk		= &ref24_clk,
+	},
+	{	/* USB */
+		.dev_id		= "bcm2708_usb",
+		.clk		= &osc_clk,
+#ifdef CONFIG_MMC_BCM2708
+	},
+	{	/* MCI */
+		.dev_id		= "bcm2708_mci.0",
+		.clk		= &sdhost_clk,
+#endif
+	}
+};
+
+
+#define UART0_IRQ	{ IRQ_UART, NO_IRQ }
+#define UART0_DMA	{ 15, 14 }
+
+AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
+
+static struct amba_device *amba_devs[] __initdata = {
+	&uart0_device,
+};
+
+static struct resource bcm2708_dmaman_resources[] = {
+	{
+		.start			= DMA_BASE,
+		.end			= DMA_BASE + SZ_4K - 1,
+		.flags			= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device bcm2708_dmaman_device = {
+   .name			= BCM_DMAMAN_DRIVER_NAME,
+	.id			= 0, /* first bcm2708_dma */
+	.resource		= bcm2708_dmaman_resources,
+	.num_resources		= ARRAY_SIZE(bcm2708_dmaman_resources),
+};
+
+#ifdef CONFIG_MMC_BCM2708
+static struct resource bcm2708_mci_resources[] = {
+	{
+		.start			= MMCI0_BASE,
+		.end			= MMCI0_BASE + SZ_4K - 1,
+		.flags			= IORESOURCE_MEM,
+	}, {
+		.start                  = IRQ_SDIO,
+		.end                    = IRQ_SDIO,
+		.flags                  = IORESOURCE_IRQ,
+	}
+};
+
+
+static struct platform_device bcm2708_mci_device = {
+	.name			= "bcm2708_mci",
+	.id			= 0, /* first bcm2708_mci */
+	.resource		= bcm2708_mci_resources,
+	.num_resources		= ARRAY_SIZE(bcm2708_mci_resources),
+	.dev			= {
+	.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+#endif /* CONFIG_MMC_BCM2708 */
+
+
+static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_fb_device = {
+	.name			= "bcm2708_fb",
+	.id			= -1,  /* only one bcm2708_fb */
+	.resource               = NULL,
+	.num_resources          = 0,
+	.dev			= {
+		.dma_mask               = &fb_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+
+static struct plat_serial8250_port bcm2708_uart1_platform_data[] = {
+	{
+		.mapbase	= UART1_BASE + 0x40,
+		.irq		= IRQ_AUX,
+		.uartclk	= 125000000,
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST,
+		.type		= PORT_8250,
+	},
+	{ },
+};
+
+static struct platform_device bcm2708_uart1_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= bcm2708_uart1_platform_data,
+	},
+};
+
+static struct resource bcm2708_usb_resources[] = {
+	[0] =	{
+		.start			= USB_BASE,
+		.end			= USB_BASE + SZ_128K - 1,
+		.flags			= IORESOURCE_MEM,
+		},
+	[1] =	{
+		.start                  = IRQ_USB,
+		.end                    = IRQ_USB,
+		.flags                  = IORESOURCE_IRQ,
+		},
+};
+
+static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_usb_device = {
+	.name			= "bcm2708_usb",
+	.id			= -1, /* only one bcm2708_usb */
+	.resource		= bcm2708_usb_resources,
+	.num_resources		= ARRAY_SIZE(bcm2708_usb_resources),
+	.dev			= {
+		.dma_mask               = &usb_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+
+static struct resource bcm2708_vcio_resources[] = {
+	[0] =	{                       /* mailbox/semaphore/doorbell access */
+		.start			= MCORE_BASE,
+		.end			= MCORE_BASE + SZ_4K - 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_vcio_device = {
+	.name                   = BCM_VCIO_DRIVER_NAME,
+	.id                     = -1, /* only one VideoCore I/O area */
+	.resource               = bcm2708_vcio_resources,
+	.num_resources          = ARRAY_SIZE(bcm2708_vcio_resources),
+	.dev			= {
+		.dma_mask               = &vcio_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+
+#ifdef CONFIG_BCM2708_GPIO
+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
+
+static struct resource bcm2708_gpio_resources[] = {
+	[0] =	{                       /* general purpose I/O */
+		.start			= GPIO_BASE,
+		.end			= GPIO_BASE + SZ_4K - 1,
+		.flags			= IORESOURCE_MEM,
+	},
+};
+
+static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_gpio_device = {
+	.name                   = BCM_GPIO_DRIVER_NAME,
+	.id                     = -1, /* only one VideoCore I/O area */
+	.resource               = bcm2708_gpio_resources,
+	.num_resources          = ARRAY_SIZE(bcm2708_gpio_resources),
+	.dev			= {
+		.dma_mask               = &gpio_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+#endif
+
+#ifdef CONFIG_BCM2708_BUTTONS
+static struct resource bcm2708_vcbuttons_resources[] = {
+};
+
+static u64 vcbuttons_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_vcbuttons_device = {
+	.name                   = "bcm2708_vcbuttons",
+	.id                     = -1, /* only one VideoCore I/O area */
+	.resource               = bcm2708_vcbuttons_resources,
+	.num_resources          = ARRAY_SIZE(bcm2708_vcbuttons_resources),
+	.dev			= {
+		.dma_mask               = &vcbuttons_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+#endif
+
+#ifdef CONFIG_BCM2708_TOUCHSCREEN
+static struct resource bcm2708_vctouch_resources[] = {
+};
+
+static u64 vctouch_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_vctouch_device = {
+	.name                   = "bcm2708_vctouch",
+	.id                     = -1, /* only one VideoCore I/O area */
+	.resource               = bcm2708_vctouch_resources,
+	.num_resources          = ARRAY_SIZE(bcm2708_vctouch_resources),
+	.dev			= {
+		.dma_mask               = &vctouch_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+#endif
+
+static struct resource bcm2708_systemtimer_resources[] = {
+	[0] =	{                       /* system timer access */
+		.start			= ST_BASE,
+		.end			= ST_BASE + SZ_4K - 1,
+		.flags			= IORESOURCE_MEM,
+	}, {
+		.start                  = IRQ_TIMER3,
+		.end                    = IRQ_TIMER3,
+		.flags                  = IORESOURCE_IRQ,
+	}
+
+
+};
+
+static u64 systemtimer_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+static struct platform_device bcm2708_systemtimer_device = {
+	.name                   = "bcm2708_systemtimer",
+	.id                     = -1, /* only one VideoCore I/O area */
+	.resource               = bcm2708_systemtimer_resources,
+	.num_resources          = ARRAY_SIZE(bcm2708_systemtimer_resources),
+	.dev			= {
+		.dma_mask               = &systemtimer_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+	},
+};
+
+#ifdef CONFIG_MMC_SDHCI_BCM2708 /* Arasan emmc SD */
+static struct resource bcm2708_emmc_resources[] = {
+	[0] = {
+		.start = EMMC_BASE,
+		.end   = EMMC_BASE + SZ_256 - 1, /* we only need this area */
+		/* the memory map actually makes SZ_4K available  */
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_ARASANSDIO,
+		.end   = IRQ_ARASANSDIO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 bcm2708_emmc_dmamask = 0xffffffffUL;
+
+struct platform_device bcm2708_emmc_device = {
+	.name		= "bcm2708_sdhci",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(bcm2708_emmc_resources),
+	.resource	= bcm2708_emmc_resources,
+	.dev		= {
+		.dma_mask		= &bcm2708_emmc_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL
+	},
+};
+#endif /* CONFIG_MMC_SDHCI_BCM2708 */
+
+static struct resource bcm2708_powerman_resources[] = {
+	[0] = {
+		.start = PM_BASE,
+		.end   = PM_BASE + SZ_256 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static u64 powerman_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
+
+struct platform_device bcm2708_powerman_device = {
+	.name		= "bcm2708_powerman",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(bcm2708_powerman_resources),
+	.resource	= bcm2708_powerman_resources,
+	.dev		= {
+		.dma_mask     = &powerman_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	},
+};
+
+int __init bcm_register_device(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = platform_device_register(pdev);
+	if (ret)
+		pr_debug("Unable to register platform device '%s': %d\n",
+			 pdev->name, ret);
+
+	return ret;
+}
+
+void __init bcm2708_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	bcm_register_device(&bcm2708_dmaman_device);
+	bcm_register_device(&bcm2708_vcio_device);
+#ifdef CONFIG_BCM2708_GPIO
+	bcm_register_device(&bcm2708_gpio_device);
+#endif
+	bcm_register_device(&bcm2708_systemtimer_device);
+#ifdef CONFIG_MMC_BCM2708
+	bcm_register_device(&bcm2708_mci_device);
+#endif
+	bcm_register_device(&bcm2708_fb_device);
+	bcm_register_device(&bcm2708_usb_device);
+	bcm_register_device(&bcm2708_uart1_device);
+#ifdef CONFIG_BCM2708_BUTTONS
+	bcm_register_device(&bcm2708_vcbuttons_device);
+#endif
+#ifdef CONFIG_BCM2708_TOUCHSCREEN
+	bcm_register_device(&bcm2708_vctouch_device);
+#endif
+	bcm_register_device(&bcm2708_powerman_device);
+#ifdef CONFIG_MMC_SDHCI_BCM2708
+	bcm_register_device(&bcm2708_emmc_device);
+#endif
+        bcm2708_init_led();
+#ifdef CONFIG_BCM2708_VCMEM
+{
+	extern void vc_mem_connected_init(void);
+        vc_mem_connected_init();
+}
+#endif
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+		struct amba_device *d = amba_devs[i];
+		amba_device_register(d, &iomem_resource);
+	}
+}
+
+#define TIMER_PERIOD 10000 /* HZ in microsecs */
+
+static void timer_set_mode(enum clock_event_mode mode,
+			   struct clock_event_device *clk)
+{
+	unsigned long stc;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		stc = readl(__io_address(ST_BASE+0x04));
+		writel(stc + TIMER_PERIOD,
+			__io_address(ST_BASE+0x18));/* stc3 */
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n",
+			(int)mode);
+		break;
+	}
+
+}
+
+static int timer_set_next_event(unsigned long evt,
+				struct clock_event_device *unused)
+{
+	unsigned long stc;
+
+	 stc = readl(__io_address(ST_BASE + 0x04));
+	 writel(stc + TIMER_PERIOD, __io_address(ST_BASE+0x18)); /* stc3 */
+	return 0;
+}
+
+static struct clock_event_device timer0_clockevent =	 {
+	.name		= "timer0",
+	.shift		= 32,
+	.features       = CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= timer_set_mode,
+	.set_next_event	= timer_set_next_event,
+};
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t bcm2708_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &timer0_clockevent;
+
+	writel(1<<3, __io_address(ST_BASE+0x00)); /* stcs clear timer int */
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction bcm2708_timer_irq = {
+	.name		= "BCM2708 Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= bcm2708_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static void __init bcm2708_timer_init(void)
+{
+	/*
+	 * Initialise to a known state (all timers off)
+	 */
+	writel(0, __io_address(ARM_T_CONTROL));
+	/*
+	 * Make irqs happen for the system timer
+	 */
+	setup_irq(IRQ_TIMER3, &bcm2708_timer_irq);
+
+	timer0_clockevent.mult =
+		div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
+	timer0_clockevent.max_delta_ns =
+		clockevent_delta2ns(0xffffffff, &timer0_clockevent);
+	timer0_clockevent.min_delta_ns =
+		clockevent_delta2ns(0xf, &timer0_clockevent);
+
+	timer0_clockevent.cpumask = cpumask_of(0);
+	clockevents_register_device(&timer0_clockevent);
+}
+
+struct sys_timer bcm2708_timer = {
+	.init		= bcm2708_timer_init,
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led bcm2708_leds[] = {
+	[0] = {
+		.gpio			= 16,
+		.name			= "led0",
+		.default_trigger	= "mmc0",
+		.active_low		= 0,
+	},
+};
+
+static struct gpio_led_platform_data bcm2708_led_pdata = {
+	.num_leds	= ARRAY_SIZE(bcm2708_leds),
+	.leds		= bcm2708_leds,
+};
+
+static struct platform_device bcm2708_led_device = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &bcm2708_led_pdata,
+	},
+};
+
+static void __init bcm2708_init_led(void)
+{
+	platform_device_register(&bcm2708_led_device);
+}
+#else
+static inline void bcm2708_init_led(void) {}
+#endif
+
+
+MACHINE_START(BCM2708, "BCM2708")
+	/* Maintainer: Broadcom Europe Ltd. */
+	.map_io		= bcm2708_map_io,
+	.init_irq	= bcm2708_init_irq,
+	.timer		= &bcm2708_timer,
+	.init_machine	= bcm2708_init,
+MACHINE_END
--- /dev/null
+++ b/arch/arm/mach-bcm2708/bcm2708.h
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/arm/mach-bcm2708/bcm2708.h
+ *
+ * BCM2708 machine support header
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef __BCM2708_BCM2708_H
+#define __BCM2708_BCM2708_H
+
+#include <linux/amba/bus.h>
+
+extern void __init bcm2708_init(void);
+extern void __init bcm2708_init_irq(void);
+extern void __init bcm2708_map_io(void);
+extern struct sys_timer bcm2708_timer;
+extern unsigned int mmc_status(struct device *dev);
+
+#define AMBA_DEVICE(name, busid, base, plat)			\
+static struct amba_device name##_device = {			\
+	.dev		= {					\
+		.coherent_dma_mask = ~0,			\
+		.init_name = busid,				\
+		.platform_data = plat,				\
+	},							\
+	.res		= {					\
+		.start	= base##_BASE,		\
+		.end	= (base##_BASE) + SZ_4K - 1,\
+		.flags	= IORESOURCE_MEM,			\
+	},							\
+	.dma_mask	= ~0,					\
+	.irq		= base##_IRQ,				\
+	/* .dma		= base##_DMA,*/				\
+}
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c
@@ -0,0 +1,323 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/bcm2708_gpio.c
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <mach/platform.h>
+#include <mach/gpio.h>
+
+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
+#define DRIVER_NAME BCM_GPIO_DRIVER_NAME
+#define BCM_GPIO_USE_IRQ 0
+
+#define GPIOFSEL(x)  (0x00+(x)*4)
+#define GPIOSET(x)   (0x1c+(x)*4)
+#define GPIOCLR(x)   (0x28+(x)*4)
+#define GPIOLEV(x)   (0x34+(x)*4)
+#define GPIOEDS(x)   (0x40+(x)*4)
+#define GPIOREN(x)   (0x4c+(x)*4)
+#define GPIOFEN(x)   (0x58+(x)*4)
+#define GPIOHEN(x)   (0x64+(x)*4)
+#define GPIOLEN(x)   (0x70+(x)*4)
+#define GPIOAREN(x)  (0x7c+(x)*4)
+#define GPIOAFEN(x)  (0x88+(x)*4)
+#define GPIOUD(x)    (0x94+(x)*4)
+#define GPIOUDCLK(x) (0x98+(x)*4)
+
+enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, 
+       GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, 
+       GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, 
+       GPIO_FSEL_ALT2, GPIO_FSEL_ALT3, };
+
+	/* Each of the two spinlocks protects a different set of hardware
+	 * regiters and data structurs. This decouples the code of the IRQ from
+	 * the GPIO code. This also makes the case of a GPIO routine call from
+	 * the IRQ code simpler.
+	 */
+static DEFINE_SPINLOCK(lock);		/* GPIO registers */
+static DEFINE_SPINLOCK(irq_lock);	/* IRQ registers */
+
+
+struct bcm2708_gpio {
+	/* We use a list of bcm2708_gpio structs for each trigger IRQ in the main
+	 * interrupts controller of the system. We need this to support systems
+	 * in which more that one bcm2708s are connected to the same IRQ. The ISR
+	 * interates through this list to find the source of the interrupt.
+	 */
+	struct list_head	list;
+
+	void __iomem		*base;
+	unsigned		irq_base;
+        struct gpio_chip        gc;
+};
+
+static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, int function)
+{
+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+	unsigned long flags;
+	unsigned gpiodir;
+        unsigned gpio_bank = offset/10;
+        unsigned gpio_field_offset = (offset - 10*gpio_bank) * 3;
+
+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set_function %p (%d,%d)\n", gc, offset, function);
+	if (offset >= ARCH_NR_GPIOS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&lock, flags);
+
+	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
+	gpiodir &= ~(7 << gpio_field_offset);
+        gpiodir |= function << gpio_field_offset;
+	writel(gpiodir, gpio->base + GPIOFSEL(gpio_bank));
+	spin_unlock_irqrestore(&lock, flags);
+	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
+
+	return 0;
+}
+
+
+static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset)
+{
+	return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT);
+}
+
+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
+static int bcm2708_gpio_dir_out(struct gpio_chip *gc, unsigned offset, int value)
+{
+	int ret;
+        ret = bcm2708_set_function(gc, offset, GPIO_FSEL_OUTPUT);
+        if (ret >= 0)
+           bcm2708_gpio_set(gc, offset, value);
+	return ret;
+}
+
+static int bcm2708_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+        unsigned gpio_bank = offset/32;
+	unsigned gpio_field_offset = (offset - 32*gpio_bank);
+        unsigned lev;
+
+	if (offset >= ARCH_NR_GPIOS)
+		return 0;
+        lev = readl(gpio->base + GPIOLEV(gpio_bank));
+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_get %p (%d)=%d\n", gc, offset, 0x1 & (lev>>gpio_field_offset));
+	return 0x1 & (lev>>gpio_field_offset);
+}
+
+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
+        unsigned gpio_bank = offset/32;
+	unsigned gpio_field_offset = (offset - 32*gpio_bank);
+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value);
+	if (offset >= ARCH_NR_GPIOS)
+		return;
+	if (value)
+	        writel(1<<gpio_field_offset, gpio->base + GPIOSET(gpio_bank));
+	else
+	        writel(1<<gpio_field_offset, gpio->base + GPIOCLR(gpio_bank));
+}
+
+/*
+ * bcm2708 GPIO IRQ
+ */
+
+#if BCM_GPIO_USE_IRQ
+static void bcm2708_irq_disable(unsigned irq)
+{
+	struct bcm2708_gpio *chip = get_irq_chip_data(irq);
+	//int offset = irq - gpio->irq_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->irq_lock, flags);
+        // disable gpio interrupts here
+	spin_unlock_irqrestore(&chip->irq_lock, flags);
+}
+
+static void bcm2708_irq_enable(unsigned irq)
+{
+	struct bcm2708_gpio *chip = get_irq_chip_data(irq);
+	//int offset = irq - chip->irq_base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->irq_lock, flags);
+        // enable gpio interrupts here
+	spin_unlock_irqrestore(&chip->irq_lock, flags);
+}
+
+static int bcm2708_irq_type(unsigned irq, unsigned trigger)
+{
+	struct bcm2708_gpio *chip = get_irq_chip_data(irq);
+	int offset = irq - chip->irq_base;
+	unsigned long flags;
+        unsigned gpio_bank = offset/32;
+	unsigned gpio_field_offset = (offset - 32*gpio_bank);
+	unsigned gpioren, gpiofen, gpiohen, gpiolen;
+
+	if (offset < 0 || offset >= ARCH_NR_GPIOS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&chip->irq_lock, flags);
+
+	gpioren = readl(chip->base + GPIOREN(gpio_bank));
+	gpiofen = readl(chip->base + GPIOFEN(gpio_bank));
+	gpiohen = readl(chip->base + GPIOHEN(gpio_bank));
+	gpiolen = readl(chip->base + GPIOLEN(gpio_bank));
+
+	if (trigger & (IRQ_TYPE_EDGE_RISING))
+		gpioren |=  (1<<gpio_field_offset);
+	else
+		gpioren &= ~(1<<gpio_field_offset);
+	if (trigger & (IRQ_TYPE_EDGE_FALLING))
+		gpiofen |=  (1<<gpio_field_offset);
+	else
+		gpiofen &= ~(1<<gpio_field_offset);
+	if (trigger & (IRQ_TYPE_LEVEL_HIGH))
+		gpiohen |=  (1<<gpio_field_offset);
+	else
+		gpiohen &= ~(1<<gpio_field_offset);
+	if (trigger & (IRQ_TYPE_LEVEL_LOW))
+		gpiolen |=  (1<<gpio_field_offset);
+	else
+		gpiolen &= ~(1<<gpio_field_offset);
+
+	writel(gpioren, chip->base + GPIOREN(gpio_bank));
+	writel(gpiofen, chip->base + GPIOFEN(gpio_bank));
+	writel(gpiohen, chip->base + GPIOHEN(gpio_bank));
+	writel(gpiolen, chip->base + GPIOLEN(gpio_bank));
+
+	spin_unlock_irqrestore(&chip->irq_lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip bcm2708_irqchip = {
+	.name		= "GPIO",
+	.enable		= bcm2708_irq_enable,
+	.disable	= bcm2708_irq_disable,
+	.set_type	= bcm2708_irq_type,
+};
+
+static void bcm2708_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+	struct list_head *chip_list = get_irq_data(irq);
+	struct list_head *ptr;
+	struct bcm2708_gpio *chip;
+	unsigned gpio_bank;
+
+	desc->chip->ack(irq);
+	list_for_each(ptr, chip_list) {
+		unsigned long pending;
+		int offset;
+
+		chip = list_entry(ptr, struct bcm2708_gpio, list);
+		for (gpio_bank = 0; gpio_bank < ARCH_NR_GPIOS/32; gpio_bank++) {
+			pending = readl(chip->base + GPIOEDS(gpio_bank));
+			writel(pending, chip->base + GPIOEDS(gpio_bank));
+
+			if (pending == 0)
+				continue;
+
+			for_each_set_bit(offset, &pending, ARCH_NR_GPIOS)
+				generic_handle_irq(gpio_to_irq(offset+32*gpio_bank));
+		}
+	}
+	desc->chip->unmask(irq);
+}
+#endif /* #if BCM_GPIO_USE_IRQ */
+
+static int bcm2708_gpio_probe(struct platform_device *dev)
+{
+	struct bcm2708_gpio *ucb;
+	struct resource *res;
+	int err = 0;
+
+        printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev);
+
+	ucb = kzalloc(sizeof(*ucb), GFP_KERNEL);
+	if (NULL == ucb) {
+		printk(KERN_ERR DRIVER_NAME ": failed to allocate "
+		       "mailbox memory\n");
+		err = -ENOMEM;
+		goto err;
+	}
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
+	platform_set_drvdata(dev, ucb);
+        ucb->base = __io_address(GPIO_BASE);
+
+	ucb->gc.label = "bcm2708_gpio";
+	ucb->gc.base = 0;
+	ucb->gc.ngpio = ARCH_NR_GPIOS;
+	ucb->gc.owner = THIS_MODULE;
+
+	ucb->gc.direction_input = bcm2708_gpio_dir_in;
+	ucb->gc.direction_output = bcm2708_gpio_dir_out;
+	ucb->gc.get = bcm2708_gpio_get;
+	ucb->gc.set = bcm2708_gpio_set;
+	ucb->gc.can_sleep = 0;
+
+	err = gpiochip_add(&ucb->gc);
+	if (err)
+		goto err;
+
+err:
+	return err;
+
+}
+
+static int bcm2708_gpio_remove(struct platform_device *dev)
+{
+	int err = 0;
+	struct bcm2708_gpio *ucb = platform_get_drvdata(dev);
+
+	printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_remove %p\n", dev);
+
+	err = gpiochip_remove(&ucb->gc);
+
+	platform_set_drvdata(dev, NULL);
+	kfree(ucb);
+
+	return err;
+}
+
+static struct platform_driver bcm2708_gpio_driver = {
+	.probe	= bcm2708_gpio_probe,
+	.remove	= bcm2708_gpio_remove,
+	.driver	= {
+		.name	= "bcm2708_gpio"
+	},
+};
+
+static int __init bcm2708_gpio_init(void)
+{
+	return platform_driver_register(&bcm2708_gpio_driver);
+}
+
+static void __exit bcm2708_gpio_exit(void)
+{
+	platform_driver_unregister(&bcm2708_gpio_driver);
+}
+
+module_init(bcm2708_gpio_init);
+module_exit(bcm2708_gpio_exit);
+
+MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver");
+MODULE_LICENSE("GPL");
+
--- /dev/null
+++ b/arch/arm/mach-bcm2708/clock.c
@@ -0,0 +1,61 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/clock.c
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <asm/clkdev.h>
+
+#include "clock.h"
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	return -EIO;
+}
+EXPORT_SYMBOL(clk_set_rate);
--- /dev/null
+++ b/arch/arm/mach-bcm2708/clock.h
@@ -0,0 +1,24 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/clock.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+struct module;
+
+struct clk {
+	unsigned long		rate;
+};
--- /dev/null
+++ b/arch/arm/mach-bcm2708/dma.c
@@ -0,0 +1,397 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/dma.c
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+/*****************************************************************************\
+ *									     *
+ * Configuration							     *
+ *									     *
+\*****************************************************************************/
+
+#define CACHE_LINE_MASK 31
+#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME
+#define DEFAULT_DMACHAN_BITMAP 0x10  /* channel 4 only */
+
+/* valid only for channels 0 - 14, 15 has its own base address */
+#define BCM2708_DMA_CHAN(n)	((n)<<8) /* base address */
+#define BCM2708_DMA_CHANIO(dma_base, n) \
+   ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n)))
+
+
+/*****************************************************************************\
+ *									     *
+ * DMA Auxilliary Functions						     *
+ *									     *
+\*****************************************************************************/
+
+/* A DMA buffer on an arbitrary boundary may separate a cache line into a
+   section inside the DMA buffer and another section outside it.
+   Even if we flush DMA buffers from the cache there is always the chance that
+   during a DMA someone will access the part of a cache line that is outside
+   the DMA buffer - which will then bring in unwelcome data.
+   Without being able to dictate our own buffer pools we must insist that
+   DMA buffers consist of a whole number of cache lines.
+*/
+
+extern int
+bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len)
+{
+	int i;
+
+	for (i = 0; i < sg_len; i++) {
+		if (sg_ptr[i].offset & CACHE_LINE_MASK ||
+		    sg_ptr[i].length & CACHE_LINE_MASK)
+			return 0;
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma);
+
+extern void
+bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block)
+{
+	dsb();	/* ARM data synchronization (push) operation */
+
+	writel(control_block,	     dma_chan_base + BCM2708_DMA_ADDR);
+	writel(BCM2708_DMA_ACTIVE,   dma_chan_base + BCM2708_DMA_CS);
+}
+
+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base)
+{
+  dsb();
+
+  /* ugly busy wait only option for now */
+  while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE);
+}
+
+EXPORT_SYMBOL_GPL(bcm_dma_start);
+
+/* Complete an ongoing DMA (assuming its results are to be ignored)
+   Does nothing if there is no DMA in progress.
+   This routine waits for the current AXI transfer to complete before
+   terminating the current DMA.	 If the current transfer is hung on a DREQ used
+   by an uncooperative peripheral the AXI transfer may never complete.	In this
+   case the routine times out and return a non-zero error code.
+   Use of this routine doesn't guarantee that the ongoing or aborted DMA
+   does not produce an interrupt.
+*/
+extern int
+bcm_dma_abort(void __iomem *dma_chan_base)
+{
+	unsigned long int cs;
+	int rc = 0;
+
+	cs = readl(dma_chan_base + BCM2708_DMA_CS);
+
+	if (BCM2708_DMA_ACTIVE & cs) {
+		long int timeout = 10000;
+
+		/* write 0 to the active bit - pause the DMA */
+		writel(0, dma_chan_base + BCM2708_DMA_CS);
+
+		/* wait for any current AXI transfer to complete */
+		while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0)
+			cs = readl(dma_chan_base + BCM2708_DMA_CS);
+
+		if (0 != (cs & BCM2708_DMA_ISPAUSED)) {
+			/* we'll un-pause when we set of our next DMA */
+			rc = -ETIMEDOUT;
+
+		} else if (BCM2708_DMA_ACTIVE & cs) {
+			/* terminate the control block chain */
+			writel(0, dma_chan_base + BCM2708_DMA_NEXTCB);
+
+			/* abort the whole DMA */
+			writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE,
+			       dma_chan_base + BCM2708_DMA_CS);
+		}
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(bcm_dma_abort);
+
+
+/***************************************************************************** \
+ *									     *
+ * DMA Manager Device Methods						     *
+ *									     *
+\*****************************************************************************/
+
+struct vc_dmaman {
+	void __iomem *dma_base;
+	u32 chan_available; /* bitmap of available channels */
+	u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */
+};
+
+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base,
+			   u32 chans_available)
+{
+	dmaman->dma_base = dma_base;
+	dmaman->chan_available = chans_available;
+	dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c;  /* chans 2 & 3 */
+}
+
+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman,
+				unsigned preferred_feature_set)
+{
+	u32 chans;
+	int feature;
+
+	chans = dmaman->chan_available;
+	for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++)
+		/* select the subset of available channels with the desired
+		   feature so long as some of the candidate channels have that
+		   feature */
+		if ((preferred_feature_set & (1 << feature)) &&
+		    (chans & dmaman->has_feature[feature]))
+			chans &= dmaman->has_feature[feature];
+
+	if (chans) {
+		int chan = 0;
+		/* return the ordinal of the first channel in the bitmap */
+		while (chans != 0 && (chans & 1) == 0) {
+			chans >>= 1;
+			chan++;
+		}
+		/* claim the channel */
+		dmaman->chan_available &= ~(1 << chan);
+		return chan;
+	} else
+		return -ENOMEM;
+}
+
+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan)
+{
+	if (chan < 0)
+		return -EINVAL;
+	else if ((1 << chan) & dmaman->chan_available)
+		return -EIDRM;
+	else {
+		dmaman->chan_available |= (1 << chan);
+		return 0;
+	}
+}
+
+/*****************************************************************************\
+ *									     *
+ * DMA IRQs								     *
+ *									     *
+\*****************************************************************************/
+
+static unsigned char bcm_dma_irqs[] = {
+	IRQ_DMA0,
+	IRQ_DMA1,
+	IRQ_DMA2,
+	IRQ_DMA3,
+	IRQ_DMA4,
+	IRQ_DMA5,
+	IRQ_DMA6,
+	IRQ_DMA7,
+	IRQ_DMA8,
+	IRQ_DMA9,
+	IRQ_DMA10,
+	IRQ_DMA11,
+	IRQ_DMA12
+};
+
+
+/***************************************************************************** \
+ *									     *
+ * DMA Manager Monitor							     *
+ *									     *
+\*****************************************************************************/
+
+static struct device *dmaman_dev;	/* we assume there's only one! */
+
+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set,
+			      void __iomem **out_dma_base, int *out_dma_irq)
+{
+	if (!dmaman_dev)
+		return -ENODEV;
+	else {
+		struct vc_dmaman *dmaman  = dev_get_drvdata(dmaman_dev);
+		int rc;
+
+		device_lock(dmaman_dev);
+		rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set);
+		if (rc >= 0) {
+			*out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base,
+							   rc);
+			*out_dma_irq = bcm_dma_irqs[rc];
+		}
+		device_unlock(dmaman_dev);
+
+		return rc;
+	}
+}
+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc);
+
+extern int bcm_dma_chan_free(int channel)
+{
+	if (dmaman_dev) {
+		struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev);
+		int rc;
+
+		device_lock(dmaman_dev);
+		rc = vc_dmaman_chan_free(dmaman, channel);
+		device_unlock(dmaman_dev);
+
+		return rc;
+	} else
+		return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(bcm_dma_chan_free);
+
+static int dev_dmaman_register(const char *dev_name, struct device *dev)
+{
+	int rc = dmaman_dev ? -EINVAL : 0;
+	dmaman_dev = dev;
+	return rc;
+}
+
+static void dev_dmaman_deregister(const char *dev_name, struct device *dev)
+{
+	dmaman_dev = NULL;
+}
+
+/*****************************************************************************\
+ *									     *
+ * DMA Device								     *
+ *									     *
+\*****************************************************************************/
+
+static int dmachans = -1; /* module parameter */
+
+static int bcm_dmaman_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct vc_dmaman *dmaman;
+	struct resource *dma_res = NULL;
+	void __iomem *dma_base = NULL;
+	int have_dma_region = 0;
+
+	dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL);
+	if (NULL == dmaman) {
+		printk(KERN_ERR DRIVER_NAME ": failed to allocate "
+		       "DMA management memory\n");
+		ret = -ENOMEM;
+	} else {
+
+		dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (dma_res == NULL) {
+			printk(KERN_ERR DRIVER_NAME ": failed to obtain memory "
+			       "resource\n");
+			ret = -ENODEV;
+		} else if (!request_mem_region(dma_res->start,
+					       resource_size(dma_res),
+					       DRIVER_NAME)) {
+			dev_err(&pdev->dev, "cannot obtain DMA region\n");
+			ret = -EBUSY;
+		} else {
+			have_dma_region = 1;
+			dma_base = ioremap(dma_res->start,
+					   resource_size(dma_res));
+			if (!dma_base) {
+				dev_err(&pdev->dev, "cannot map DMA region\n");
+				ret = -ENOMEM;
+			} else {
+				/* use module parameter if one was provided */
+				if (dmachans > 0)
+					vc_dmaman_init(dmaman, dma_base,
+						       dmachans);
+				else
+					vc_dmaman_init(dmaman, dma_base,
+						       DEFAULT_DMACHAN_BITMAP);
+
+				platform_set_drvdata(pdev, dmaman);
+				dev_dmaman_register(DRIVER_NAME, &pdev->dev);
+
+				printk(KERN_INFO DRIVER_NAME ": DMA manager "
+				       "at %p\n", dma_base);
+			}
+		}
+	}
+	if (ret != 0) {
+		if (dma_base)
+			iounmap(dma_base);
+		if (dma_res && have_dma_region)
+			release_mem_region(dma_res->start,
+					   resource_size(dma_res));
+		if (dmaman)
+			kfree(dmaman);
+	}
+	return ret;
+}
+
+static int bcm_dmaman_remove(struct platform_device *pdev)
+{
+	struct vc_dmaman *dmaman = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	dev_dmaman_deregister(DRIVER_NAME, &pdev->dev);
+	kfree(dmaman);
+
+	return 0;
+}
+
+static struct platform_driver bcm_dmaman_driver = {
+	.probe = bcm_dmaman_probe,
+	.remove = bcm_dmaman_remove,
+
+	.driver = {
+		   .name = DRIVER_NAME,
+		   .owner = THIS_MODULE,
+		   },
+};
+
+/*****************************************************************************\
+ *									     *
+ * Driver init/exit							     *
+ *									     *
+\*****************************************************************************/
+
+static int __init bcm_dmaman_drv_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&bcm_dmaman_driver);
+	if (ret != 0) {
+		printk(KERN_ERR DRIVER_NAME ": failed to register "
+		       "on platform\n");
+	}
+
+	return ret;
+}
+
+static void __exit bcm_dmaman_drv_exit(void)
+{
+	platform_driver_unregister(&bcm_dmaman_driver);
+}
+
+module_init(bcm_dmaman_drv_init);
+module_exit(bcm_dmaman_drv_exit);
+
+module_param(dmachans, int, 0644);
+
+MODULE_AUTHOR("Gray Girling <grayg@broadcom.com>");
+MODULE_DESCRIPTION("DMA channel manager driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM");
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/arm_control.h
@@ -0,0 +1,419 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/arm_control.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef __BCM2708_ARM_CONTROL_H
+#define __BCM2708_ARM_CONTROL_H
+
+/*
+ * Definitions and addresses for the ARM CONTROL logic
+ * This file is manually generated.
+ */
+
+#define ARM_BASE  0x7E00B000
+
+/* Basic configuration */
+#define ARM_CONTROL0  HW_REGISTER_RW(ARM_BASE+0x000)
+#define ARM_C0_SIZ128M   0x00000000
+#define ARM_C0_SIZ256M   0x00000001
+#define ARM_C0_SIZ512M   0x00000002
+#define ARM_C0_SIZ1G     0x00000003
+#define ARM_C0_BRESP0    0x00000000
+#define ARM_C0_BRESP1    0x00000004
+#define ARM_C0_BRESP2    0x00000008
+#define ARM_C0_BOOTHI    0x00000010
+#define ARM_C0_UNUSED05  0x00000020 /* free */
+#define ARM_C0_FULLPERI  0x00000040
+#define ARM_C0_UNUSED78  0x00000180 /* free */
+#define ARM_C0_JTAGMASK  0x00000E00
+#define ARM_C0_JTAGOFF   0x00000000
+#define ARM_C0_JTAGBASH  0x00000800 /* Debug on GPIO off */
+#define ARM_C0_JTAGGPIO  0x00000C00 /* Debug on GPIO on */
+#define ARM_C0_APROTMSK  0x0000F000
+#define ARM_C0_DBG0SYNC  0x00010000 /* VPU0 halt sync */
+#define ARM_C0_DBG1SYNC  0x00020000 /* VPU1 halt sync */
+#define ARM_C0_SWDBGREQ  0x00040000 /* HW debug request */
+#define ARM_C0_PASSHALT  0x00080000 /* ARM halt passed to debugger */
+#define ARM_C0_PRIO_PER  0x00F00000 /* per priority mask */
+#define ARM_C0_PRIO_L2   0x0F000000
+#define ARM_C0_PRIO_UC   0xF0000000
+
+#define ARM_C0_APROTPASS  0x0000A000 /* Translate 1:1 */
+#define ARM_C0_APROTUSER  0x00000000 /* Only user mode */
+#define ARM_C0_APROTSYST  0x0000F000 /* Only system mode */
+
+
+#define ARM_CONTROL1  HW_REGISTER_RW(ARM_BASE+0x440)
+#define ARM_C1_TIMER     0x00000001 /* re-route timer IRQ  to VC */
+#define ARM_C1_MAIL      0x00000002 /* re-route Mail IRQ   to VC */
+#define ARM_C1_BELL0     0x00000004 /* re-route Doorbell 0 to VC */
+#define ARM_C1_BELL1     0x00000008 /* re-route Doorbell 1 to VC */
+#define ARM_C1_PERSON    0x00000100 /* peripherals on */
+#define ARM_C1_REQSTOP   0x00000200 /* ASYNC bridge request stop */
+
+#define ARM_STATUS    HW_REGISTER_RW(ARM_BASE+0x444)
+#define ARM_S_ACKSTOP    0x80000000 /* Bridge stopped */
+#define ARM_S_READPEND   0x000003FF /* pending reads counter */
+#define ARM_S_WRITPEND   0x000FFC00 /* pending writes counter */
+
+#define ARM_ERRHALT   HW_REGISTER_RW(ARM_BASE+0x448)
+#define ARM_EH_PERIBURST  0x00000001 /* Burst write seen on peri bus */
+#define ARM_EH_ILLADDRS1  0x00000002 /* Address bits 25-27 error */
+#define ARM_EH_ILLADDRS2  0x00000004 /* Address bits 31-28 error */
+#define ARM_EH_VPU0HALT   0x00000008 /* VPU0 halted & in debug mode */
+#define ARM_EH_VPU1HALT   0x00000010 /* VPU1 halted & in debug mode */
+#define ARM_EH_ARMHALT    0x00000020 /* ARM in halted debug mode */
+
+#define ARM_ID_SECURE HW_REGISTER_RW(ARM_BASE+0x00C)
+#define ARM_ID        HW_REGISTER_RW(ARM_BASE+0x44C)
+#define ARM_IDVAL        0x364D5241
+
+/* Translation memory */
+#define ARM_TRANSLATE HW_REGISTER_RW(ARM_BASE+0x100)
+/* 32 locations: 0x100.. 0x17F */
+/* 32 spare means we CAN go to 64 pages.... */
+
+
+/* Interrupts */
+#define ARM_IRQ_PEND0 HW_REGISTER_RW(ARM_BASE+0x200)        /* Top IRQ bits */
+#define ARM_I0_TIMER    0x00000001 /* timer IRQ */
+#define ARM_I0_MAIL     0x00000002 /* Mail IRQ */
+#define ARM_I0_BELL0    0x00000004 /* Doorbell 0 */
+#define ARM_I0_BELL1    0x00000008 /* Doorbell 1 */
+#define ARM_I0_BANK1    0x00000100 /* Bank1 IRQ */
+#define ARM_I0_BANK2    0x00000200 /* Bank2 IRQ */
+
+#define ARM_IRQ_PEND1 HW_REGISTER_RW(ARM_BASE+0x204) /* All bank1 IRQ bits */
+/* todo: all I1_interrupt sources */
+#define ARM_IRQ_PEND2 HW_REGISTER_RW(ARM_BASE+0x208) /* All bank2 IRQ bits */
+/* todo: all I2_interrupt sources */
+
+#define ARM_IRQ_FAST  HW_REGISTER_RW(ARM_BASE+0x20C) /* FIQ control */
+#define ARM_IF_INDEX    0x0000007F     /* FIQ select */
+#define ARM_IF_ENABLE   0x00000080     /* FIQ enable */
+#define ARM_IF_VCMASK   0x0000003F     /* FIQ = (index from VC source) */
+#define ARM_IF_TIMER    0x00000040     /* FIQ = ARM timer */
+#define ARM_IF_MAIL     0x00000041     /* FIQ = ARM Mail */
+#define ARM_IF_BELL0    0x00000042     /* FIQ = ARM Doorbell 0 */
+#define ARM_IF_BELL1    0x00000043     /* FIQ = ARM Doorbell 1 */
+#define ARM_IF_VP0HALT  0x00000044     /* FIQ = VPU0 Halt seen */
+#define ARM_IF_VP1HALT  0x00000045     /* FIQ = VPU1 Halt seen */
+#define ARM_IF_ILLEGAL  0x00000046     /* FIQ = Illegal access seen */
+
+#define ARM_IRQ_ENBL1 HW_REGISTER_RW(ARM_BASE+0x210) /* Bank1 enable bits */
+#define ARM_IRQ_ENBL2 HW_REGISTER_RW(ARM_BASE+0x214) /* Bank2 enable bits */
+#define ARM_IRQ_ENBL3 HW_REGISTER_RW(ARM_BASE+0x218) /* ARM irqs enable bits */
+#define ARM_IRQ_DIBL1 HW_REGISTER_RW(ARM_BASE+0x21C) /* Bank1 disable bits */
+#define ARM_IRQ_DIBL2 HW_REGISTER_RW(ARM_BASE+0x220) /* Bank2 disable bits */
+#define ARM_IRQ_DIBL3 HW_REGISTER_RW(ARM_BASE+0x224) /* ARM irqs disable bits */
+#define ARM_IE_TIMER    0x00000001     /* Timer IRQ */
+#define ARM_IE_MAIL     0x00000002     /* Mail IRQ */
+#define ARM_IE_BELL0    0x00000004     /* Doorbell 0 */
+#define ARM_IE_BELL1    0x00000008     /* Doorbell 1 */
+#define ARM_IE_VP0HALT  0x00000010     /* VPU0 Halt */
+#define ARM_IE_VP1HALT  0x00000020     /* VPU1 Halt */
+#define ARM_IE_ILLEGAL  0x00000040     /* Illegal access seen */
+
+/* Timer */
+/* For reg. fields see sp804 spec. */
+#define ARM_T_LOAD    HW_REGISTER_RW(ARM_BASE+0x400)
+#define ARM_T_VALUE   HW_REGISTER_RW(ARM_BASE+0x404)
+#define ARM_T_CONTROL HW_REGISTER_RW(ARM_BASE+0x408)
+#define ARM_T_IRQCNTL HW_REGISTER_RW(ARM_BASE+0x40C)
+#define ARM_T_RAWIRQ  HW_REGISTER_RW(ARM_BASE+0x410)
+#define ARM_T_MSKIRQ  HW_REGISTER_RW(ARM_BASE+0x414)
+#define ARM_T_RELOAD  HW_REGISTER_RW(ARM_BASE+0x418)
+#define ARM_T_PREDIV  HW_REGISTER_RW(ARM_BASE+0x41c)
+#define ARM_T_FREECNT HW_REGISTER_RW(ARM_BASE+0x420)
+
+#define TIMER_CTRL_ONESHOT  (1 << 0)
+#define TIMER_CTRL_32BIT    (1 << 1)
+#define TIMER_CTRL_DIV1     (0 << 2)
+#define TIMER_CTRL_DIV16    (1 << 2)
+#define TIMER_CTRL_DIV256   (2 << 2)
+#define TIMER_CTRL_IE       (1 << 5)
+#define TIMER_CTRL_PERIODIC (1 << 6)
+#define TIMER_CTRL_ENABLE   (1 << 7)
+#define TIMER_CTRL_DBGHALT  (1 << 8)
+#define TIMER_CTRL_ENAFREE  (1 << 9)
+#define TIMER_CTRL_FREEDIV_SHIFT 16)
+#define TIMER_CTRL_FREEDIV_MASK  0xff
+
+/* Semaphores, Doorbells, Mailboxes */
+#define ARM_SBM_OWN0  (ARM_BASE+0x800)
+#define ARM_SBM_OWN1  (ARM_BASE+0x900)
+#define ARM_SBM_OWN2  (ARM_BASE+0xA00)
+#define ARM_SBM_OWN3  (ARM_BASE+0xB00)
+
+/* MAILBOXES
+ * Register flags are common across all
+ * owner registers. See end of this section
+ *
+ * Semaphores, Doorbells, Mailboxes Owner 0
+ *
+ */
+
+#define ARM_0_SEMS       HW_REGISTER_RW(ARM_SBM_OWN0+0x00)
+#define ARM_0_SEM0       HW_REGISTER_RW(ARM_SBM_OWN0+0x00)
+#define ARM_0_SEM1       HW_REGISTER_RW(ARM_SBM_OWN0+0x04)
+#define ARM_0_SEM2       HW_REGISTER_RW(ARM_SBM_OWN0+0x08)
+#define ARM_0_SEM3       HW_REGISTER_RW(ARM_SBM_OWN0+0x0C)
+#define ARM_0_SEM4       HW_REGISTER_RW(ARM_SBM_OWN0+0x10)
+#define ARM_0_SEM5       HW_REGISTER_RW(ARM_SBM_OWN0+0x14)
+#define ARM_0_SEM6       HW_REGISTER_RW(ARM_SBM_OWN0+0x18)
+#define ARM_0_SEM7       HW_REGISTER_RW(ARM_SBM_OWN0+0x1C)
+#define ARM_0_BELL0      HW_REGISTER_RW(ARM_SBM_OWN0+0x40)
+#define ARM_0_BELL1      HW_REGISTER_RW(ARM_SBM_OWN0+0x44)
+#define ARM_0_BELL2      HW_REGISTER_RW(ARM_SBM_OWN0+0x48)
+#define ARM_0_BELL3      HW_REGISTER_RW(ARM_SBM_OWN0+0x4C)
+/* MAILBOX 0 access in Owner 0 area */
+/* Some addresses should ONLY be used by owner 0 */
+#define ARM_0_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN0+0x80)  /* .. 0x8C (4 locations) */
+#define ARM_0_MAIL0_RD   HW_REGISTER_RW(ARM_SBM_OWN0+0x80)  /* .. 0x8C (4 locations) Normal read */
+#define ARM_0_MAIL0_POL  HW_REGISTER_RW(ARM_SBM_OWN0+0x90)  /* none-pop read */
+#define ARM_0_MAIL0_SND  HW_REGISTER_RW(ARM_SBM_OWN0+0x94)  /* Sender read (only LS 2 bits) */
+#define ARM_0_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN0+0x98)  /* Status read */
+#define ARM_0_MAIL0_CNF  HW_REGISTER_RW(ARM_SBM_OWN0+0x9C)  /* Config read/write */
+/* MAILBOX 1 access in Owner 0 area */
+/* Owner 0 should only WRITE to this mailbox */
+#define ARM_0_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN0+0xA0)   /* .. 0xAC (4 locations) */
+/*#define ARM_0_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_0_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN0+0xB0) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_0_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN0+0xB4) */ /* DO NOT USE THIS !!!!! */
+#define ARM_0_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN0+0xB8)   /* Status read */
+/*#define ARM_0_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN0+0xBC) */ /* DO NOT USE THIS !!!!! */
+/* General SEM, BELL, MAIL config/status */
+#define ARM_0_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN0+0xE0)  /* semaphore clear/debug register */
+#define ARM_0_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN0+0xE4)  /* Doorbells clear/debug register */
+#define ARM_0_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN0+0xF8)  /* ALL interrupts */
+#define ARM_0_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN0+0xFC)  /* IRQS pending for owner 0 */
+
+/* Semaphores, Doorbells, Mailboxes Owner 1 */
+#define ARM_1_SEMS       HW_REGISTER_RW(ARM_SBM_OWN1+0x00)
+#define ARM_1_SEM0       HW_REGISTER_RW(ARM_SBM_OWN1+0x00)
+#define ARM_1_SEM1       HW_REGISTER_RW(ARM_SBM_OWN1+0x04)
+#define ARM_1_SEM2       HW_REGISTER_RW(ARM_SBM_OWN1+0x08)
+#define ARM_1_SEM3       HW_REGISTER_RW(ARM_SBM_OWN1+0x0C)
+#define ARM_1_SEM4       HW_REGISTER_RW(ARM_SBM_OWN1+0x10)
+#define ARM_1_SEM5       HW_REGISTER_RW(ARM_SBM_OWN1+0x14)
+#define ARM_1_SEM6       HW_REGISTER_RW(ARM_SBM_OWN1+0x18)
+#define ARM_1_SEM7       HW_REGISTER_RW(ARM_SBM_OWN1+0x1C)
+#define ARM_1_BELL0      HW_REGISTER_RW(ARM_SBM_OWN1+0x40)
+#define ARM_1_BELL1      HW_REGISTER_RW(ARM_SBM_OWN1+0x44)
+#define ARM_1_BELL2      HW_REGISTER_RW(ARM_SBM_OWN1+0x48)
+#define ARM_1_BELL3      HW_REGISTER_RW(ARM_SBM_OWN1+0x4C)
+/* MAILBOX 0 access in Owner 0 area */
+/* Owner 1 should only WRITE to this mailbox */
+#define ARM_1_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN1+0x80)  /* .. 0x8C (4 locations) */
+/*#define ARM_1_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN1+0x80) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_1_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN1+0x90) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_1_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN1+0x94) */ /* DO NOT USE THIS !!!!! */
+#define ARM_1_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN1+0x98)  /* Status read */
+/*#define ARM_1_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0x9C) */ /* DO NOT USE THIS !!!!! */
+/* MAILBOX 1 access in Owner 0 area */
+#define ARM_1_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN1+0xA0)  /* .. 0xAC (4 locations) */
+#define ARM_1_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN1+0xA0)  /* .. 0xAC (4 locations) Normal read */
+#define ARM_1_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN1+0xB0)  /* none-pop read */
+#define ARM_1_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN1+0xB4)  /* Sender read (only LS 2 bits) */
+#define ARM_1_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN1+0xB8)  /* Status read */
+#define ARM_1_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN1+0xBC)
+/* General SEM, BELL, MAIL config/status */
+#define ARM_1_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN1+0xE0)  /* semaphore clear/debug register */
+#define ARM_1_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN1+0xE4)  /* Doorbells clear/debug register */
+#define ARM_1_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN1+0xFC)  /* IRQS pending for owner 1 */
+#define ARM_1_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN1+0xF8)  /* ALL interrupts */
+
+/* Semaphores, Doorbells, Mailboxes Owner 2 */
+#define ARM_2_SEMS       HW_REGISTER_RW(ARM_SBM_OWN2+0x00)
+#define ARM_2_SEM0       HW_REGISTER_RW(ARM_SBM_OWN2+0x00)
+#define ARM_2_SEM1       HW_REGISTER_RW(ARM_SBM_OWN2+0x04)
+#define ARM_2_SEM2       HW_REGISTER_RW(ARM_SBM_OWN2+0x08)
+#define ARM_2_SEM3       HW_REGISTER_RW(ARM_SBM_OWN2+0x0C)
+#define ARM_2_SEM4       HW_REGISTER_RW(ARM_SBM_OWN2+0x10)
+#define ARM_2_SEM5       HW_REGISTER_RW(ARM_SBM_OWN2+0x14)
+#define ARM_2_SEM6       HW_REGISTER_RW(ARM_SBM_OWN2+0x18)
+#define ARM_2_SEM7       HW_REGISTER_RW(ARM_SBM_OWN2+0x1C)
+#define ARM_2_BELL0      HW_REGISTER_RW(ARM_SBM_OWN2+0x40)
+#define ARM_2_BELL1      HW_REGISTER_RW(ARM_SBM_OWN2+0x44)
+#define ARM_2_BELL2      HW_REGISTER_RW(ARM_SBM_OWN2+0x48)
+#define ARM_2_BELL3      HW_REGISTER_RW(ARM_SBM_OWN2+0x4C)
+/* MAILBOX 0 access in Owner 2 area */
+/* Owner 2 should only WRITE to this mailbox */
+#define ARM_2_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN2+0x80)   /* .. 0x8C (4 locations) */
+/*#define ARM_2_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN2+0x80)  */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_2_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN2+0x90)  */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_2_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN2+0x94)  */ /* DO NOT USE THIS !!!!! */
+#define ARM_2_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN2+0x98)   /* Status read */
+/*#define ARM_2_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0x9C)  */ /* DO NOT USE THIS !!!!! */
+/* MAILBOX 1 access in Owner 2 area */
+/* Owner 2 should only WRITE to this mailbox */
+#define ARM_2_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN2+0xA0)   /* .. 0xAC (4 locations) */
+/*#define ARM_2_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_2_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN2+0xB0) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_2_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN2+0xB4) */ /* DO NOT USE THIS !!!!! */
+#define ARM_2_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN2+0xB8)   /* Status read */
+/*#define ARM_2_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN2+0xBC) */ /* DO NOT USE THIS !!!!! */
+/* General SEM, BELL, MAIL config/status */
+#define ARM_2_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN2+0xE0)  /* semaphore clear/debug register */
+#define ARM_2_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN2+0xE4)  /* Doorbells clear/debug register */
+#define ARM_2_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN2+0xFC)  /* IRQS pending for owner 2 */
+#define ARM_2_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN2+0xF8)  /* ALL interrupts */
+
+/* Semaphores, Doorbells, Mailboxes Owner 3 */
+#define ARM_3_SEMS       HW_REGISTER_RW(ARM_SBM_OWN3+0x00)
+#define ARM_3_SEM0       HW_REGISTER_RW(ARM_SBM_OWN3+0x00)
+#define ARM_3_SEM1       HW_REGISTER_RW(ARM_SBM_OWN3+0x04)
+#define ARM_3_SEM2       HW_REGISTER_RW(ARM_SBM_OWN3+0x08)
+#define ARM_3_SEM3       HW_REGISTER_RW(ARM_SBM_OWN3+0x0C)
+#define ARM_3_SEM4       HW_REGISTER_RW(ARM_SBM_OWN3+0x10)
+#define ARM_3_SEM5       HW_REGISTER_RW(ARM_SBM_OWN3+0x14)
+#define ARM_3_SEM6       HW_REGISTER_RW(ARM_SBM_OWN3+0x18)
+#define ARM_3_SEM7       HW_REGISTER_RW(ARM_SBM_OWN3+0x1C)
+#define ARM_3_BELL0      HW_REGISTER_RW(ARM_SBM_OWN3+0x40)
+#define ARM_3_BELL1      HW_REGISTER_RW(ARM_SBM_OWN3+0x44)
+#define ARM_3_BELL2      HW_REGISTER_RW(ARM_SBM_OWN3+0x48)
+#define ARM_3_BELL3      HW_REGISTER_RW(ARM_SBM_OWN3+0x4C)
+/* MAILBOX 0 access in Owner 3 area */
+/* Owner 3 should only WRITE to this mailbox */
+#define ARM_3_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN3+0x80)   /* .. 0x8C (4 locations) */
+/*#define ARM_3_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN3+0x80)  */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_3_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN3+0x90)  */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_3_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN3+0x94)  */ /* DO NOT USE THIS !!!!! */
+#define ARM_3_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN3+0x98)    /* Status read */
+/*#define ARM_3_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0x9C)  */ /* DO NOT USE THIS !!!!! */
+/* MAILBOX 1 access in Owner 3 area */
+/* Owner 3 should only WRITE to this mailbox */
+#define ARM_3_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN3+0xA0)   /* .. 0xAC (4 locations) */
+/*#define ARM_3_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_3_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN3+0xB0) */ /* DO NOT USE THIS !!!!! */
+/*#define ARM_3_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN3+0xB4) */ /* DO NOT USE THIS !!!!! */
+#define ARM_3_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN3+0xB8)   /* Status read */
+/*#define ARM_3_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN3+0xBC) */ /* DO NOT USE THIS !!!!! */
+/* General SEM, BELL, MAIL config/status */
+#define ARM_3_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN3+0xE0)  /* semaphore clear/debug register */
+#define ARM_3_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN3+0xE4)  /* Doorbells clear/debug register */
+#define ARM_3_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN3+0xFC)  /* IRQS pending for owner 3 */
+#define ARM_3_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN3+0xF8)  /* ALL interrupts */
+
+
+
+/*  Mailbox flags. Valid for all owners */
+
+/* Mailbox status register (...0x98) */
+#define ARM_MS_FULL       0x80000000
+#define ARM_MS_EMPTY      0x40000000
+#define ARM_MS_LEVEL      0x400000FF /* Max. value depdnds on mailbox depth parameter */
+
+/* MAILBOX config/status register (...0x9C) */
+/* ANY write to this register clears the error bits! */
+#define ARM_MC_IHAVEDATAIRQEN    0x00000001 /* mailbox irq enable:  has data */
+#define ARM_MC_IHAVESPACEIRQEN   0x00000002 /* mailbox irq enable:  has space */
+#define ARM_MC_OPPISEMPTYIRQEN   0x00000004 /* mailbox irq enable: Opp. is empty */
+#define ARM_MC_MAIL_CLEAR        0x00000008 /* mailbox clear write 1, then  0 */
+#define ARM_MC_IHAVEDATAIRQPEND  0x00000010 /* mailbox irq pending:  has space */
+#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mailbox irq pending: Opp. is empty */
+#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mailbox irq pending */
+/* Bit 7 is unused */
+#define ARM_MC_ERRNOOWN   0x00000100 /* error : none owner read from mailbox */
+#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */
+#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */
+
+/* Semaphore clear/debug register (...0xE0) */
+#define ARM_SD_OWN0      0x00000003  /* Owner of sem 0 */
+#define ARM_SD_OWN1      0x0000000C  /* Owner of sem 1 */
+#define ARM_SD_OWN2      0x00000030  /* Owner of sem 2 */
+#define ARM_SD_OWN3      0x000000C0  /* Owner of sem 3 */
+#define ARM_SD_OWN4      0x00000300  /* Owner of sem 4 */
+#define ARM_SD_OWN5      0x00000C00  /* Owner of sem 5 */
+#define ARM_SD_OWN6      0x00003000  /* Owner of sem 6 */
+#define ARM_SD_OWN7      0x0000C000  /* Owner of sem 7 */
+#define ARM_SD_SEM0      0x00010000  /* Status of sem 0 */
+#define ARM_SD_SEM1      0x00020000  /* Status of sem 1 */
+#define ARM_SD_SEM2      0x00040000  /* Status of sem 2 */
+#define ARM_SD_SEM3      0x00080000  /* Status of sem 3 */
+#define ARM_SD_SEM4      0x00100000  /* Status of sem 4 */
+#define ARM_SD_SEM5      0x00200000  /* Status of sem 5 */
+#define ARM_SD_SEM6      0x00400000  /* Status of sem 6 */
+#define ARM_SD_SEM7      0x00800000  /* Status of sem 7 */
+
+/* Doorbells clear/debug register (...0xE4) */
+#define ARM_BD_OWN0      0x00000003  /* Owner of doorbell 0 */
+#define ARM_BD_OWN1      0x0000000C  /* Owner of doorbell 1 */
+#define ARM_BD_OWN2      0x00000030  /* Owner of doorbell 2 */
+#define ARM_BD_OWN3      0x000000C0  /* Owner of doorbell 3 */
+#define ARM_BD_BELL0     0x00000100  /* Status of doorbell 0 */
+#define ARM_BD_BELL1     0x00000200  /* Status of doorbell 1 */
+#define ARM_BD_BELL2     0x00000400  /* Status of doorbell 2 */
+#define ARM_BD_BELL3     0x00000800  /* Status of doorbell 3 */
+
+/* MY IRQS register (...0xF8) */
+#define ARM_MYIRQ_BELL   0x00000001  /* This owner has a doorbell IRQ */
+#define ARM_MYIRQ_MAIL   0x00000002  /* This owner has a mailbox  IRQ */
+
+/* ALL IRQS register (...0xF8) */
+#define ARM_AIS_BELL0 0x00000001  /* Doorbell 0 IRQ pending */
+#define ARM_AIS_BELL1 0x00000002  /* Doorbell 1 IRQ pending */
+#define ARM_AIS_BELL2 0x00000004  /* Doorbell 2 IRQ pending */
+#define ARM_AIS_BELL3 0x00000008  /* Doorbell 3 IRQ pending */
+#define ARM_AIS0_HAVEDATA 0x00000010  /* MAIL 0 has data IRQ pending */
+#define ARM_AIS0_HAVESPAC 0x00000020  /* MAIL 0 has space IRQ pending */
+#define ARM_AIS0_OPPEMPTY 0x00000040  /* MAIL 0 opposite is empty IRQ */
+#define ARM_AIS1_HAVEDATA 0x00000080  /* MAIL 1 has data IRQ pending */
+#define ARM_AIS1_HAVESPAC 0x00000100  /* MAIL 1 has space IRQ pending */
+#define ARM_AIS1_OPPEMPTY 0x00000200  /* MAIL 1 opposite is empty IRQ */
+/* Note   that bell-0, bell-1 and MAIL0 IRQ go only to the ARM */
+/* Whilst that bell-2, bell-3 and MAIL1 IRQ go only to the VC */
+/* */
+/* ARM JTAG BASH */
+/* */
+#define AJB_BASE 0x7e2000c0
+
+#define AJBCONF HW_REGISTER_RW(AJB_BASE+0x00)
+#define   AJB_BITS0    0x000000
+#define   AJB_BITS4    0x000004
+#define   AJB_BITS8    0x000008
+#define   AJB_BITS12   0x00000C
+#define   AJB_BITS16   0x000010
+#define   AJB_BITS20   0x000014
+#define   AJB_BITS24   0x000018
+#define   AJB_BITS28   0x00001C
+#define   AJB_BITS32   0x000020
+#define   AJB_BITS34   0x000022
+#define   AJB_OUT_MS   0x000040
+#define   AJB_OUT_LS   0x000000
+#define   AJB_INV_CLK  0x000080
+#define   AJB_D0_RISE  0x000100
+#define   AJB_D0_FALL  0x000000
+#define   AJB_D1_RISE  0x000200
+#define   AJB_D1_FALL  0x000000
+#define   AJB_IN_RISE  0x000400
+#define   AJB_IN_FALL  0x000000
+#define   AJB_ENABLE   0x000800
+#define   AJB_HOLD0    0x000000
+#define   AJB_HOLD1    0x001000
+#define   AJB_HOLD2    0x002000
+#define   AJB_HOLD3    0x003000
+#define   AJB_RESETN   0x004000
+#define   AJB_CLKSHFT  16
+#define   AJB_BUSY     0x80000000
+#define AJBTMS HW_REGISTER_RW(AJB_BASE+0x04)
+#define AJBTDI HW_REGISTER_RW(AJB_BASE+0x08)
+#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c)
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/arm_power.h
@@ -0,0 +1,60 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/include/mach/arm_power.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef _ARM_POWER_H
+#define _ARM_POWER_H
+
+/* Use meaningful names on each side */
+#ifdef __VIDEOCORE__
+#define PREFIX(x) ARM_##x
+#else
+#define PREFIX(x) BCM_##x
+#endif
+
+enum {
+	PREFIX(POWER_SDCARD_BIT),
+	PREFIX(POWER_UART_BIT),
+	PREFIX(POWER_MINIUART_BIT),
+	PREFIX(POWER_USB_BIT),
+	PREFIX(POWER_I2C0_BIT),
+	PREFIX(POWER_I2C1_BIT),
+	PREFIX(POWER_I2C2_BIT),
+	PREFIX(POWER_SPI_BIT),
+	PREFIX(POWER_CCP2TX_BIT),
+
+	PREFIX(POWER_MAX)
+};
+
+enum {
+	PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)),
+	PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)),
+	PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)),
+	PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)),
+	PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)),
+	PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)),
+	PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)),
+	PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)),
+	PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)),
+
+	PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1,
+	PREFIX(POWER_NONE) = 0
+};
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
@@ -0,0 +1,24 @@
+/* arch/arm/mach-bcm2708/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 2010 Broadcom
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart, rx, tmp
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx,      #0x08000000
+		movne	\rx,      #0xf8000000	@ virtual base
+		orr	\rx, \rx, #0x00200000
+		orr	\rx, \rx, #0x00001000
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/dma.h
@@ -0,0 +1,84 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/include/mach/dma.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef _MACH_BCM2708_DMA_H
+#define _MACH_BCM2708_DMA_H
+
+#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma"
+
+/* DMA CS Control and Status bits */
+#define BCM2708_DMA_ACTIVE	(1 << 0)
+#define BCM2708_DMA_INT		(1 << 2)
+#define BCM2708_DMA_ISPAUSED	(1 << 4)  /* Pause requested or not active */
+#define BCM2708_DMA_ISHELD	(1 << 5)  /* Is held by DREQ flow control */
+#define BCM2708_DMA_ERR		(1 << 8)
+#define BCM2708_DMA_ABORT	(1 << 30) /* stop current CB, go to next, WO */
+#define BCM2708_DMA_RESET	(1 << 31) /* WO, self clearing */
+
+/* DMA control block "info" field bits */
+#define BCM2708_DMA_INT_EN	(1 << 0)
+#define BCM2708_DMA_TDMODE	(1 << 1)
+#define BCM2708_DMA_WAIT_RESP	(1 << 3)
+#define BCM2708_DMA_D_INC	(1 << 4)
+#define BCM2708_DMA_D_WIDTH	(1 << 5)
+#define BCM2708_DMA_D_DREQ	(1 << 6)
+#define BCM2708_DMA_S_INC	(1 << 8)
+#define BCM2708_DMA_S_WIDTH	(1 << 9)
+#define BCM2708_DMA_S_DREQ	(1 << 10)
+
+#define	BCM2708_DMA_BURST(x)	(((x)&0xf) << 12)
+#define	BCM2708_DMA_PER_MAP(x)	((x) << 16)
+#define	BCM2708_DMA_WAITS(x)	(((x)&0x1f) << 21)
+
+#define BCM2708_DMA_DREQ_EMMC	11
+#define BCM2708_DMA_DREQ_SDHOST	13
+
+#define BCM2708_DMA_CS		0x00 /* Control and Status */
+#define BCM2708_DMA_ADDR	0x04
+/* the current control block appears in the following registers - read only */
+#define BCM2708_DMA_INFO	0x08
+#define BCM2708_DMA_NEXTCB	0x1C
+#define BCM2708_DMA_DEBUG	0x20
+
+#define BCM2708_DMA4_CS		(BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS)
+#define BCM2708_DMA4_ADDR	(BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR)
+
+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w))
+
+struct bcm2708_dma_cb {
+	unsigned long info;
+	unsigned long src;
+	unsigned long dst;
+	unsigned long length;
+	unsigned long stride;
+	unsigned long next;
+	unsigned long pad[2];
+};
+
+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len);
+extern void bcm_dma_start(void __iomem *dma_chan_base,
+			  dma_addr_t control_block);
+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base);
+extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base);
+
+/* When listing features we can ask for when allocating DMA channels give
+   those with higher priority smaller ordinal numbers */
+#define BCM_DMA_FEATURE_FAST_ORD 0
+#define BCM_DMA_FEATURE_FAST	 (1<<BCM_DMA_FEATURE_FAST_ORD)
+#define BCM_DMA_FEATURE_COUNT	 1
+
+/* return channel no or -ve error */
+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set,
+			      void __iomem **out_dma_base, int *out_dma_irq);
+extern int bcm_dma_chan_free(int channel);
+
+
+#endif /* _MACH_BCM2708_DMA_H */
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/entry-macro.S
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-bcm2708/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for BCM2708 platforms
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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 <mach/hardware.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr	\base, =IO_ADDRESS(ARMCTRL_IC_BASE)
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		/* get masked status */
+		ldr	\irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
+		mov	\irqnr, #(ARM_IRQ0_BASE + 31)
+		and	\tmp, \irqstat, #0x300		 @ save bits 8 and 9
+		/* clear bits 8 and 9, and test */
+		bics	\irqstat, \irqstat, #0x300
+		bne	1010f
+
+		tst	\tmp, #0x100
+		ldrne	\irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
+		movne \irqnr, #(ARM_IRQ1_BASE + 31)
+		@ Mask out the interrupts also present in PEND0 - see SW-5809
+		bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
+		bicne \irqstat, #((1<<18) | (1<<19))
+		bne	1010f
+
+		tst	\tmp, #0x200
+		ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
+		movne \irqnr, #(ARM_IRQ2_BASE + 31)
+		@ Mask out the interrupts also present in PEND0 - see SW-5809
+		bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
+		bicne \irqstat, #((1<<30))
+		beq 1020f
+
+1010:
+		@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
+		@ N.B. CLZ is an ARM5 instruction.
+		sub	\tmp, \irqstat, #1
+		eor	\irqstat, \irqstat, \tmp
+		clz	\tmp, \irqstat
+		sub	\irqnr, \tmp
+
+1020:	@ EQ will be set if no irqs pending
+
+		.endm
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/frc.h
@@ -0,0 +1,38 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/timex.h
+ *
+ *  BCM2708 free running counter (timer)
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef _MACH_FRC_H
+#define _MACH_FRC_H
+
+#define FRC_TICK_RATE		(1000000)
+
+/*! Free running counter incrementing at the CLOCK_TICK_RATE
+    (slightly faster than frc_clock_ticks63()
+ */
+extern unsigned long frc_clock_ticks32(void);
+
+/*! Free running counter incrementing at the CLOCK_TICK_RATE
+ *  Note - top bit should be ignored (see cnt32_to_63)
+ */
+extern unsigned long long frc_clock_ticks63(void);
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/gpio.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-bcm2708/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#define ARCH_NR_GPIOS 54 // number of gpio lines
+
+#include <asm-generic/gpio.h>
+
+
+#ifdef CONFIG_GPIOLIB
+
+static inline int gpio_get_value(unsigned gpio)
+{
+        return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+        __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+        return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+        WARN_ON(1);
+        return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+        WARN_ON(1);
+        return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/hardware.h
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/hardware.h
+ *
+ *  This file contains the hardware definitions of the BCM2708 devices.
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/platform.h>
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/io.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/irqs.h
@@ -0,0 +1,190 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/irqs.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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
+ */
+
+#ifndef _BCM2708_IRQS_H_
+#define _BCM2708_IRQS_H_
+
+#include <mach/platform.h>
+
+/*
+ *  IRQ interrupts definitions are the same as the INT definitions
+ *  held within platform.h
+ */
+#define IRQ_ARMCTRL_START     0
+#define IRQ_TIMER0            (IRQ_ARMCTRL_START + INTERRUPT_TIMER0)
+#define IRQ_TIMER1            (IRQ_ARMCTRL_START + INTERRUPT_TIMER1)
+#define IRQ_TIMER2            (IRQ_ARMCTRL_START + INTERRUPT_TIMER2)
+#define IRQ_TIMER3            (IRQ_ARMCTRL_START + INTERRUPT_TIMER3)
+#define IRQ_CODEC0            (IRQ_ARMCTRL_START + INTERRUPT_CODEC0)
+#define IRQ_CODEC1            (IRQ_ARMCTRL_START + INTERRUPT_CODEC1)
+#define IRQ_CODEC2            (IRQ_ARMCTRL_START + INTERRUPT_CODEC2)
+#define IRQ_JPEG              (IRQ_ARMCTRL_START + INTERRUPT_JPEG)
+#define IRQ_ISP               (IRQ_ARMCTRL_START + INTERRUPT_ISP)
+#define IRQ_USB               (IRQ_ARMCTRL_START + INTERRUPT_USB)
+#define IRQ_3D                (IRQ_ARMCTRL_START + INTERRUPT_3D)
+#define IRQ_TRANSPOSER        (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER)
+#define IRQ_MULTICORESYNC0    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0)
+#define IRQ_MULTICORESYNC1    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1)
+#define IRQ_MULTICORESYNC2    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2)
+#define IRQ_MULTICORESYNC3    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3)
+#define IRQ_DMA0              (IRQ_ARMCTRL_START + INTERRUPT_DMA0)
+#define IRQ_DMA1              (IRQ_ARMCTRL_START + INTERRUPT_DMA1)
+#define IRQ_DMA2              (IRQ_ARMCTRL_START + INTERRUPT_DMA2)
+#define IRQ_DMA3              (IRQ_ARMCTRL_START + INTERRUPT_DMA3)
+#define IRQ_DMA4              (IRQ_ARMCTRL_START + INTERRUPT_DMA4)
+#define IRQ_DMA5              (IRQ_ARMCTRL_START + INTERRUPT_DMA5)
+#define IRQ_DMA6              (IRQ_ARMCTRL_START + INTERRUPT_DMA6)
+#define IRQ_DMA7              (IRQ_ARMCTRL_START + INTERRUPT_DMA7)
+#define IRQ_DMA8              (IRQ_ARMCTRL_START + INTERRUPT_DMA8)
+#define IRQ_DMA9              (IRQ_ARMCTRL_START + INTERRUPT_DMA9)
+#define IRQ_DMA10             (IRQ_ARMCTRL_START + INTERRUPT_DMA10)
+#define IRQ_DMA11             (IRQ_ARMCTRL_START + INTERRUPT_DMA11)
+#define IRQ_DMA12             (IRQ_ARMCTRL_START + INTERRUPT_DMA12)
+#define IRQ_AUX               (IRQ_ARMCTRL_START + INTERRUPT_AUX)
+#define IRQ_ARM               (IRQ_ARMCTRL_START + INTERRUPT_ARM)
+#define IRQ_VPUDMA            (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA)
+#define IRQ_HOSTPORT          (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT)
+#define IRQ_VIDEOSCALER       (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER)
+#define IRQ_CCP2TX            (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX)
+#define IRQ_SDC               (IRQ_ARMCTRL_START + INTERRUPT_SDC)
+#define IRQ_DSI0              (IRQ_ARMCTRL_START + INTERRUPT_DSI0)
+#define IRQ_AVE               (IRQ_ARMCTRL_START + INTERRUPT_AVE)
+#define IRQ_CAM0              (IRQ_ARMCTRL_START + INTERRUPT_CAM0)
+#define IRQ_CAM1              (IRQ_ARMCTRL_START + INTERRUPT_CAM1)
+#define IRQ_HDMI0             (IRQ_ARMCTRL_START + INTERRUPT_HDMI0)
+#define IRQ_HDMI1             (IRQ_ARMCTRL_START + INTERRUPT_HDMI1)
+#define IRQ_PIXELVALVE1       (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1)
+#define IRQ_I2CSPISLV         (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV)
+#define IRQ_DSI1              (IRQ_ARMCTRL_START + INTERRUPT_DSI1)
+#define IRQ_PWA0              (IRQ_ARMCTRL_START + INTERRUPT_PWA0)
+#define IRQ_PWA1              (IRQ_ARMCTRL_START + INTERRUPT_PWA1)
+#define IRQ_CPR               (IRQ_ARMCTRL_START + INTERRUPT_CPR)
+#define IRQ_SMI               (IRQ_ARMCTRL_START + INTERRUPT_SMI)
+#define IRQ_GPIO0             (IRQ_ARMCTRL_START + INTERRUPT_GPIO0)
+#define IRQ_GPIO1             (IRQ_ARMCTRL_START + INTERRUPT_GPIO1)
+#define IRQ_GPIO2             (IRQ_ARMCTRL_START + INTERRUPT_GPIO2)
+#define IRQ_GPIO3             (IRQ_ARMCTRL_START + INTERRUPT_GPIO3)
+#define IRQ_I2C               (IRQ_ARMCTRL_START + INTERRUPT_I2C)
+#define IRQ_SPI               (IRQ_ARMCTRL_START + INTERRUPT_SPI)
+#define IRQ_I2SPCM            (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM)
+#define IRQ_SDIO              (IRQ_ARMCTRL_START + INTERRUPT_SDIO)
+#define IRQ_UART              (IRQ_ARMCTRL_START + INTERRUPT_UART)
+#define IRQ_SLIMBUS           (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS)
+#define IRQ_VEC               (IRQ_ARMCTRL_START + INTERRUPT_VEC)
+#define IRQ_CPG               (IRQ_ARMCTRL_START + INTERRUPT_CPG)
+#define IRQ_RNG               (IRQ_ARMCTRL_START + INTERRUPT_RNG)
+#define IRQ_ARASANSDIO        (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO)
+#define IRQ_AVSPMON           (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON)
+
+#define IRQ_ARM_TIMER         (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER)
+#define IRQ_ARM_MAILBOX       (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX)
+#define IRQ_ARM_DOORBELL_0    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0)
+#define IRQ_ARM_DOORBELL_1    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1)
+#define IRQ_VPU0_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED)
+#define IRQ_VPU1_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED)
+#define IRQ_ILLEGAL_TYPE0     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0)
+#define IRQ_ILLEGAL_TYPE1     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1)
+#define IRQ_PENDING1          (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
+#define IRQ_PENDING2          (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
+
+/*
+ *  FIQ interrupts definitions are the same as the INT definitions.
+ */
+#define FIQ_TIMER0            INT_TIMER0
+#define FIQ_TIMER1            INT_TIMER1
+#define FIQ_TIMER2            INT_TIMER2
+#define FIQ_TIMER3            INT_TIMER3
+#define FIQ_CODEC0            INT_CODEC0
+#define FIQ_CODEC1            INT_CODEC1
+#define FIQ_CODEC2            INT_CODEC2
+#define FIQ_JPEG              INT_JPEG
+#define FIQ_ISP               INT_ISP
+#define FIQ_USB               INT_USB
+#define FIQ_3D                INT_3D
+#define FIQ_TRANSPOSER        INT_TRANSPOSER
+#define FIQ_MULTICORESYNC0    INT_MULTICORESYNC0
+#define FIQ_MULTICORESYNC1    INT_MULTICORESYNC1
+#define FIQ_MULTICORESYNC2    INT_MULTICORESYNC2
+#define FIQ_MULTICORESYNC3    INT_MULTICORESYNC3
+#define FIQ_DMA0              INT_DMA0
+#define FIQ_DMA1              INT_DMA1
+#define FIQ_DMA2              INT_DMA2
+#define FIQ_DMA3              INT_DMA3
+#define FIQ_DMA4              INT_DMA4
+#define FIQ_DMA5              INT_DMA5
+#define FIQ_DMA6              INT_DMA6
+#define FIQ_DMA7              INT_DMA7
+#define FIQ_DMA8              INT_DMA8
+#define FIQ_DMA9              INT_DMA9
+#define FIQ_DMA10             INT_DMA10
+#define FIQ_DMA11             INT_DMA11
+#define FIQ_DMA12             INT_DMA12
+#define FIQ_AUX               INT_AUX
+#define FIQ_ARM               INT_ARM
+#define FIQ_VPUDMA            INT_VPUDMA
+#define FIQ_HOSTPORT          INT_HOSTPORT
+#define FIQ_VIDEOSCALER       INT_VIDEOSCALER
+#define FIQ_CCP2TX            INT_CCP2TX
+#define FIQ_SDC               INT_SDC
+#define FIQ_DSI0              INT_DSI0
+#define FIQ_AVE               INT_AVE
+#define FIQ_CAM0              INT_CAM0
+#define FIQ_CAM1              INT_CAM1
+#define FIQ_HDMI0             INT_HDMI0
+#define FIQ_HDMI1             INT_HDMI1
+#define FIQ_PIXELVALVE1       INT_PIXELVALVE1
+#define FIQ_I2CSPISLV         INT_I2CSPISLV
+#define FIQ_DSI1              INT_DSI1
+#define FIQ_PWA0              INT_PWA0
+#define FIQ_PWA1              INT_PWA1
+#define FIQ_CPR               INT_CPR
+#define FIQ_SMI               INT_SMI
+#define FIQ_GPIO0             INT_GPIO0
+#define FIQ_GPIO1             INT_GPIO1
+#define FIQ_GPIO2             INT_GPIO2
+#define FIQ_GPIO3             INT_GPIO3
+#define FIQ_I2C               INT_I2C
+#define FIQ_SPI               INT_SPI
+#define FIQ_I2SPCM            INT_I2SPCM
+#define FIQ_SDIO              INT_SDIO
+#define FIQ_UART              INT_UART
+#define FIQ_SLIMBUS           INT_SLIMBUS
+#define FIQ_VEC               INT_VEC
+#define FIQ_CPG               INT_CPG
+#define FIQ_RNG               INT_RNG
+#define FIQ_ARASANSDIO        INT_ARASANSDIO
+#define FIQ_AVSPMON           INT_AVSPMON
+
+#define FIQ_ARM_TIMER         INT_ARM_TIMER
+#define FIQ_ARM_MAILBOX       INT_ARM_MAILBOX
+#define FIQ_ARM_DOORBELL_0    INT_ARM_DOORBELL_0
+#define FIQ_ARM_DOORBELL_1    INT_ARM_DOORBELL_1
+#define FIQ_VPU0_HALTED       INT_VPU0_HALTED
+#define FIQ_VPU1_HALTED       INT_VPU1_HALTED
+#define FIQ_ILLEGAL_TYPE0     INT_ILLEGAL_TYPE0
+#define FIQ_ILLEGAL_TYPE1     INT_ILLEGAL_TYPE1
+#define FIQ_PENDING1          INT_PENDING1
+#define FIQ_PENDING2          INT_PENDING2
+
+#define NR_IRQS			      (64 + 21)
+
+#endif /* _BCM2708_IRQS_H_ */
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/irqs.h.orig
@@ -0,0 +1,185 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/irqs.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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 <mach/platform.h>
+
+/*
+ *  IRQ interrupts definitions are the same as the INT definitions
+ *  held within platform.h
+ */
+#define IRQ_ARMCTRL_START     0
+#define IRQ_TIMER0            (IRQ_ARMCTRL_START + INTERRUPT_TIMER0)
+#define IRQ_TIMER1            (IRQ_ARMCTRL_START + INTERRUPT_TIMER1)
+#define IRQ_TIMER2            (IRQ_ARMCTRL_START + INTERRUPT_TIMER2)
+#define IRQ_TIMER3            (IRQ_ARMCTRL_START + INTERRUPT_TIMER3)
+#define IRQ_CODEC0            (IRQ_ARMCTRL_START + INTERRUPT_CODEC0)
+#define IRQ_CODEC1            (IRQ_ARMCTRL_START + INTERRUPT_CODEC1)
+#define IRQ_CODEC2            (IRQ_ARMCTRL_START + INTERRUPT_CODEC2)
+#define IRQ_JPEG              (IRQ_ARMCTRL_START + INTERRUPT_JPEG)
+#define IRQ_ISP               (IRQ_ARMCTRL_START + INTERRUPT_ISP)
+#define IRQ_USB               (IRQ_ARMCTRL_START + INTERRUPT_USB)
+#define IRQ_3D                (IRQ_ARMCTRL_START + INTERRUPT_3D)
+#define IRQ_TRANSPOSER        (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER)
+#define IRQ_MULTICORESYNC0    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0)
+#define IRQ_MULTICORESYNC1    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1)
+#define IRQ_MULTICORESYNC2    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2)
+#define IRQ_MULTICORESYNC3    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3)
+#define IRQ_DMA0              (IRQ_ARMCTRL_START + INTERRUPT_DMA0)
+#define IRQ_DMA1              (IRQ_ARMCTRL_START + INTERRUPT_DMA1)
+#define IRQ_DMA2              (IRQ_ARMCTRL_START + INTERRUPT_DMA2)
+#define IRQ_DMA3              (IRQ_ARMCTRL_START + INTERRUPT_DMA3)
+#define IRQ_DMA4              (IRQ_ARMCTRL_START + INTERRUPT_DMA4)
+#define IRQ_DMA5              (IRQ_ARMCTRL_START + INTERRUPT_DMA5)
+#define IRQ_DMA6              (IRQ_ARMCTRL_START + INTERRUPT_DMA6)
+#define IRQ_DMA7              (IRQ_ARMCTRL_START + INTERRUPT_DMA7)
+#define IRQ_DMA8              (IRQ_ARMCTRL_START + INTERRUPT_DMA8)
+#define IRQ_DMA9              (IRQ_ARMCTRL_START + INTERRUPT_DMA9)
+#define IRQ_DMA10             (IRQ_ARMCTRL_START + INTERRUPT_DMA10)
+#define IRQ_DMA11             (IRQ_ARMCTRL_START + INTERRUPT_DMA11)
+#define IRQ_DMA12             (IRQ_ARMCTRL_START + INTERRUPT_DMA12)
+#define IRQ_AUX               (IRQ_ARMCTRL_START + INTERRUPT_AUX)
+#define IRQ_ARM               (IRQ_ARMCTRL_START + INTERRUPT_ARM)
+#define IRQ_VPUDMA            (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA)
+#define IRQ_HOSTPORT          (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT)
+#define IRQ_VIDEOSCALER       (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER)
+#define IRQ_CCP2TX            (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX)
+#define IRQ_SDC               (IRQ_ARMCTRL_START + INTERRUPT_SDC)
+#define IRQ_DSI0              (IRQ_ARMCTRL_START + INTERRUPT_DSI0)
+#define IRQ_AVE               (IRQ_ARMCTRL_START + INTERRUPT_AVE)
+#define IRQ_CAM0              (IRQ_ARMCTRL_START + INTERRUPT_CAM0)
+#define IRQ_CAM1              (IRQ_ARMCTRL_START + INTERRUPT_CAM1)
+#define IRQ_HDMI0             (IRQ_ARMCTRL_START + INTERRUPT_HDMI0)
+#define IRQ_HDMI1             (IRQ_ARMCTRL_START + INTERRUPT_HDMI1)
+#define IRQ_PIXELVALVE1       (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1)
+#define IRQ_I2CSPISLV         (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV)
+#define IRQ_DSI1              (IRQ_ARMCTRL_START + INTERRUPT_DSI1)
+#define IRQ_PWA0              (IRQ_ARMCTRL_START + INTERRUPT_PWA0)
+#define IRQ_PWA1              (IRQ_ARMCTRL_START + INTERRUPT_PWA1)
+#define IRQ_CPR               (IRQ_ARMCTRL_START + INTERRUPT_CPR)
+#define IRQ_SMI               (IRQ_ARMCTRL_START + INTERRUPT_SMI)
+#define IRQ_GPIO0             (IRQ_ARMCTRL_START + INTERRUPT_GPIO0)
+#define IRQ_GPIO1             (IRQ_ARMCTRL_START + INTERRUPT_GPIO1)
+#define IRQ_GPIO2             (IRQ_ARMCTRL_START + INTERRUPT_GPIO2)
+#define IRQ_GPIO3             (IRQ_ARMCTRL_START + INTERRUPT_GPIO3)
+#define IRQ_I2C               (IRQ_ARMCTRL_START + INTERRUPT_I2C)
+#define IRQ_SPI               (IRQ_ARMCTRL_START + INTERRUPT_SPI)
+#define IRQ_I2SPCM            (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM)
+#define IRQ_SDIO              (IRQ_ARMCTRL_START + INTERRUPT_SDIO)
+#define IRQ_UART              (IRQ_ARMCTRL_START + INTERRUPT_UART)
+#define IRQ_SLIMBUS           (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS)
+#define IRQ_VEC               (IRQ_ARMCTRL_START + INTERRUPT_VEC)
+#define IRQ_CPG               (IRQ_ARMCTRL_START + INTERRUPT_CPG)
+#define IRQ_RNG               (IRQ_ARMCTRL_START + INTERRUPT_RNG)
+#define IRQ_ARASANSDIO        (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO)
+#define IRQ_AVSPMON           (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON)
+
+#define IRQ_ARM_TIMER         (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER)
+#define IRQ_ARM_MAILBOX       (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX)
+#define IRQ_ARM_DOORBELL_0    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0)
+#define IRQ_ARM_DOORBELL_1    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1)
+#define IRQ_VPU0_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED)
+#define IRQ_VPU1_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED)
+#define IRQ_ILLEGAL_TYPE0     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0)
+#define IRQ_ILLEGAL_TYPE1     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1)
+#define IRQ_PENDING1          (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
+#define IRQ_PENDING2          (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
+
+/*
+ *  FIQ interrupts definitions are the same as the INT definitions.
+ */
+#define FIQ_TIMER0            INT_TIMER0
+#define FIQ_TIMER1            INT_TIMER1
+#define FIQ_TIMER2            INT_TIMER2
+#define FIQ_TIMER3            INT_TIMER3
+#define FIQ_CODEC0            INT_CODEC0
+#define FIQ_CODEC1            INT_CODEC1
+#define FIQ_CODEC2            INT_CODEC2
+#define FIQ_JPEG              INT_JPEG
+#define FIQ_ISP               INT_ISP
+#define FIQ_USB               INT_USB
+#define FIQ_3D                INT_3D
+#define FIQ_TRANSPOSER        INT_TRANSPOSER
+#define FIQ_MULTICORESYNC0    INT_MULTICORESYNC0
+#define FIQ_MULTICORESYNC1    INT_MULTICORESYNC1
+#define FIQ_MULTICORESYNC2    INT_MULTICORESYNC2
+#define FIQ_MULTICORESYNC3    INT_MULTICORESYNC3
+#define FIQ_DMA0              INT_DMA0
+#define FIQ_DMA1              INT_DMA1
+#define FIQ_DMA2              INT_DMA2
+#define FIQ_DMA3              INT_DMA3
+#define FIQ_DMA4              INT_DMA4
+#define FIQ_DMA5              INT_DMA5
+#define FIQ_DMA6              INT_DMA6
+#define FIQ_DMA7              INT_DMA7
+#define FIQ_DMA8              INT_DMA8
+#define FIQ_DMA9              INT_DMA9
+#define FIQ_DMA10             INT_DMA10
+#define FIQ_DMA11             INT_DMA11
+#define FIQ_DMA12             INT_DMA12
+#define FIQ_AUX               INT_AUX
+#define FIQ_ARM               INT_ARM
+#define FIQ_VPUDMA            INT_VPUDMA
+#define FIQ_HOSTPORT          INT_HOSTPORT
+#define FIQ_VIDEOSCALER       INT_VIDEOSCALER
+#define FIQ_CCP2TX            INT_CCP2TX
+#define FIQ_SDC               INT_SDC
+#define FIQ_DSI0              INT_DSI0
+#define FIQ_AVE               INT_AVE
+#define FIQ_CAM0              INT_CAM0
+#define FIQ_CAM1              INT_CAM1
+#define FIQ_HDMI0             INT_HDMI0
+#define FIQ_HDMI1             INT_HDMI1
+#define FIQ_PIXELVALVE1       INT_PIXELVALVE1
+#define FIQ_I2CSPISLV         INT_I2CSPISLV
+#define FIQ_DSI1              INT_DSI1
+#define FIQ_PWA0              INT_PWA0
+#define FIQ_PWA1              INT_PWA1
+#define FIQ_CPR               INT_CPR
+#define FIQ_SMI               INT_SMI
+#define FIQ_GPIO0             INT_GPIO0
+#define FIQ_GPIO1             INT_GPIO1
+#define FIQ_GPIO2             INT_GPIO2
+#define FIQ_GPIO3             INT_GPIO3
+#define FIQ_I2C               INT_I2C
+#define FIQ_SPI               INT_SPI
+#define FIQ_I2SPCM            INT_I2SPCM
+#define FIQ_SDIO              INT_SDIO
+#define FIQ_UART              INT_UART
+#define FIQ_SLIMBUS           INT_SLIMBUS
+#define FIQ_VEC               INT_VEC
+#define FIQ_CPG               INT_CPG
+#define FIQ_RNG               INT_RNG
+#define FIQ_ARASANSDIO        INT_ARASANSDIO
+#define FIQ_AVSPMON           INT_AVSPMON
+
+#define FIQ_ARM_TIMER         INT_ARM_TIMER
+#define FIQ_ARM_MAILBOX       INT_ARM_MAILBOX
+#define FIQ_ARM_DOORBELL_0    INT_ARM_DOORBELL_0
+#define FIQ_ARM_DOORBELL_1    INT_ARM_DOORBELL_1
+#define FIQ_VPU0_HALTED       INT_VPU0_HALTED
+#define FIQ_VPU1_HALTED       INT_VPU1_HALTED
+#define FIQ_ILLEGAL_TYPE0     INT_ILLEGAL_TYPE0
+#define FIQ_ILLEGAL_TYPE1     INT_ILLEGAL_TYPE1
+#define FIQ_PENDING1          INT_PENDING1
+#define FIQ_PENDING2          INT_PENDING2
+
+#define NR_IRQS			      (64 + 21)
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/memory.h
@@ -0,0 +1,59 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/memory.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/* Memory overview:
+
+   [ARMcore] <--virtual addr-->
+   [ARMmmu] <--physical addr-->
+   [GERTmap] <--bus add-->
+   [VCperiph]
+
+*/
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	 UL(0x00000000)
+#define ARMMEM_OFFSET    UL(0x00000000)   /* offset in VC of ARM memory */
+#define _REAL_BUS_OFFSET UL(0xC0000000)   /* don't use L1 or L2 caches */
+
+/* We're using the memory at 64M in the VideoCore for Linux - this adjustment
+ * will provide the offset into this area as well as setting the bits that
+ * stop the L1 and L2 cache from being used
+ *
+ * WARNING: this only works because the ARM is given memory at a fixed location
+ *          (ARMMEM_OFFSET)
+ */
+#define BUS_OFFSET          (ARMMEM_OFFSET + _REAL_BUS_OFFSET)
+#define __virt_to_bus(x)    ((x) + (BUS_OFFSET - PAGE_OFFSET))
+#define __bus_to_virt(x)    ((x) - (BUS_OFFSET - PAGE_OFFSET))
+#define __pfn_to_bus(x)     (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
+#define __bus_to_pfn(x)     __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
+
+/*
+ * Consistent DMA area set to 2M. Framebuffer now allocated on host
+ */
+
+
+#define CONSISTENT_DMA_SIZE 0x00200000
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/platform.h
@@ -0,0 +1,210 @@
+/*
+ * arch/arm/mach-bcm2708/include/mach/platform.h
+ *
+ * Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef _BCM2708_PLATFORM_H
+#define _BCM2708_PLATFORM_H
+
+
+/* macros to get at IO space when running virtually */
+#define IO_ADDRESS(x)	(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+
+#define __io_address(a)     __io(IO_ADDRESS(a))
+
+
+/*
+ *  SDRAM
+ */
+#define BCM2708_SDRAM_BASE           0x00000000
+
+/*
+ *  Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  BCM2708 ARMCTRL Registers
+ * ------------------------------------------------------------------------
+ */
+
+#define HW_REGISTER_RW(addr) (addr)
+#define HW_REGISTER_RO(addr) (addr)
+
+#include "arm_control.h"
+#undef ARM_BASE
+
+/*
+ * Definitions and addresses for the ARM CONTROL logic
+ * This file is manually generated.
+ */
+
+#define BCM2708_PERI_BASE        0x20000000
+#define ST_BASE                  (BCM2708_PERI_BASE + 0x3000)   /* System Timer */
+#define DMA_BASE		 (BCM2708_PERI_BASE + 0x7000)	/* DMA controller */
+#define ARM_BASE                 (BCM2708_PERI_BASE + 0xB000)	 /* BCM2708 ARM control block */
+#define PM_BASE			 (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
+#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO */
+#define UART0_BASE               (BCM2708_PERI_BASE + 0x201000)	/* Uart 0 */
+#define MMCI0_BASE               (BCM2708_PERI_BASE + 0x202000) /* MMC interface */
+#define UART1_BASE               (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */
+#define EMMC_BASE                (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */
+#define SMI_BASE		 (BCM2708_PERI_BASE + 0x600000) /* SMI */
+#define USB_BASE                 (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB controller */
+#define MCORE_BASE               (BCM2708_PERI_BASE + 0x0000)   /* Fake frame buffer device (actually the multicore sync block*/
+
+#define ARMCTRL_BASE             (ARM_BASE + 0x000)
+#define ARMCTRL_IC_BASE          (ARM_BASE + 0x200)           /* ARM interrupt controller */
+#define ARMCTRL_TIMER0_1_BASE    (ARM_BASE + 0x400)           /* Timer 0 and 1 */
+#define ARMCTRL_0_SBM_BASE       (ARM_BASE + 0x800)           /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */
+
+
+/*
+ * Interrupt assignments
+ */
+
+#define ARM_IRQ1_BASE                  0
+#define INTERRUPT_TIMER0               (ARM_IRQ1_BASE + 0)
+#define INTERRUPT_TIMER1               (ARM_IRQ1_BASE + 1)
+#define INTERRUPT_TIMER2               (ARM_IRQ1_BASE + 2)
+#define INTERRUPT_TIMER3               (ARM_IRQ1_BASE + 3)
+#define INTERRUPT_CODEC0               (ARM_IRQ1_BASE + 4)
+#define INTERRUPT_CODEC1               (ARM_IRQ1_BASE + 5)
+#define INTERRUPT_CODEC2               (ARM_IRQ1_BASE + 6)
+#define INTERRUPT_VC_JPEG              (ARM_IRQ1_BASE + 7)
+#define INTERRUPT_ISP                  (ARM_IRQ1_BASE + 8)
+#define INTERRUPT_VC_USB               (ARM_IRQ1_BASE + 9)
+#define INTERRUPT_VC_3D                (ARM_IRQ1_BASE + 10)
+#define INTERRUPT_TRANSPOSER           (ARM_IRQ1_BASE + 11)
+#define INTERRUPT_MULTICORESYNC0       (ARM_IRQ1_BASE + 12)
+#define INTERRUPT_MULTICORESYNC1       (ARM_IRQ1_BASE + 13)
+#define INTERRUPT_MULTICORESYNC2       (ARM_IRQ1_BASE + 14)
+#define INTERRUPT_MULTICORESYNC3       (ARM_IRQ1_BASE + 15)
+#define INTERRUPT_DMA0                 (ARM_IRQ1_BASE + 16)
+#define INTERRUPT_DMA1                 (ARM_IRQ1_BASE + 17)
+#define INTERRUPT_VC_DMA2              (ARM_IRQ1_BASE + 18)
+#define INTERRUPT_VC_DMA3              (ARM_IRQ1_BASE + 19)
+#define INTERRUPT_DMA4                 (ARM_IRQ1_BASE + 20)
+#define INTERRUPT_DMA5                 (ARM_IRQ1_BASE + 21)
+#define INTERRUPT_DMA6                 (ARM_IRQ1_BASE + 22)
+#define INTERRUPT_DMA7                 (ARM_IRQ1_BASE + 23)
+#define INTERRUPT_DMA8                 (ARM_IRQ1_BASE + 24)
+#define INTERRUPT_DMA9                 (ARM_IRQ1_BASE + 25)
+#define INTERRUPT_DMA10                (ARM_IRQ1_BASE + 26)
+#define INTERRUPT_DMA11                (ARM_IRQ1_BASE + 27)
+#define INTERRUPT_DMA12                (ARM_IRQ1_BASE + 28)
+#define INTERRUPT_AUX                (ARM_IRQ1_BASE + 29)
+#define INTERRUPT_ARM                  (ARM_IRQ1_BASE + 30)
+#define INTERRUPT_VPUDMA               (ARM_IRQ1_BASE + 31)
+
+#define ARM_IRQ2_BASE                  32
+#define INTERRUPT_HOSTPORT             (ARM_IRQ2_BASE + 0)
+#define INTERRUPT_VIDEOSCALER          (ARM_IRQ2_BASE + 1)
+#define INTERRUPT_CCP2TX               (ARM_IRQ2_BASE + 2)
+#define INTERRUPT_SDC                  (ARM_IRQ2_BASE + 3)
+#define INTERRUPT_DSI0                 (ARM_IRQ2_BASE + 4)
+#define INTERRUPT_AVE                  (ARM_IRQ2_BASE + 5)
+#define INTERRUPT_CAM0                 (ARM_IRQ2_BASE + 6)
+#define INTERRUPT_CAM1                 (ARM_IRQ2_BASE + 7)
+#define INTERRUPT_HDMI0                (ARM_IRQ2_BASE + 8)
+#define INTERRUPT_HDMI1                (ARM_IRQ2_BASE + 9)
+#define INTERRUPT_PIXELVALVE1          (ARM_IRQ2_BASE + 10)
+#define INTERRUPT_I2CSPISLV            (ARM_IRQ2_BASE + 11)
+#define INTERRUPT_DSI1                 (ARM_IRQ2_BASE + 12)
+#define INTERRUPT_PWA0                 (ARM_IRQ2_BASE + 13)
+#define INTERRUPT_PWA1                 (ARM_IRQ2_BASE + 14)
+#define INTERRUPT_CPR                  (ARM_IRQ2_BASE + 15)
+#define INTERRUPT_SMI                  (ARM_IRQ2_BASE + 16)
+#define INTERRUPT_GPIO0                (ARM_IRQ2_BASE + 17)
+#define INTERRUPT_GPIO1                (ARM_IRQ2_BASE + 18)
+#define INTERRUPT_GPIO2                (ARM_IRQ2_BASE + 19)
+#define INTERRUPT_GPIO3                (ARM_IRQ2_BASE + 20)
+#define INTERRUPT_VC_I2C               (ARM_IRQ2_BASE + 21)
+#define INTERRUPT_VC_SPI               (ARM_IRQ2_BASE + 22)
+#define INTERRUPT_VC_I2SPCM            (ARM_IRQ2_BASE + 23)
+#define INTERRUPT_VC_SDIO              (ARM_IRQ2_BASE + 24)
+#define INTERRUPT_VC_UART              (ARM_IRQ2_BASE + 25)
+#define INTERRUPT_SLIMBUS              (ARM_IRQ2_BASE + 26)
+#define INTERRUPT_VEC                  (ARM_IRQ2_BASE + 27)
+#define INTERRUPT_CPG                  (ARM_IRQ2_BASE + 28)
+#define INTERRUPT_RNG                  (ARM_IRQ2_BASE + 29)
+#define INTERRUPT_VC_ARASANSDIO        (ARM_IRQ2_BASE + 30)
+#define INTERRUPT_AVSPMON              (ARM_IRQ2_BASE + 31)
+
+#define ARM_IRQ0_BASE                  64
+#define INTERRUPT_ARM_TIMER            (ARM_IRQ0_BASE + 0)
+#define INTERRUPT_ARM_MAILBOX          (ARM_IRQ0_BASE + 1)
+#define INTERRUPT_ARM_DOORBELL_0       (ARM_IRQ0_BASE + 2)
+#define INTERRUPT_ARM_DOORBELL_1       (ARM_IRQ0_BASE + 3)
+#define INTERRUPT_VPU0_HALTED          (ARM_IRQ0_BASE + 4)
+#define INTERRUPT_VPU1_HALTED          (ARM_IRQ0_BASE + 5)
+#define INTERRUPT_ILLEGAL_TYPE0        (ARM_IRQ0_BASE + 6)
+#define INTERRUPT_ILLEGAL_TYPE1        (ARM_IRQ0_BASE + 7)
+#define INTERRUPT_PENDING1             (ARM_IRQ0_BASE + 8)
+#define INTERRUPT_PENDING2             (ARM_IRQ0_BASE + 9)
+#define INTERRUPT_JPEG                 (ARM_IRQ0_BASE + 10)
+#define INTERRUPT_USB                  (ARM_IRQ0_BASE + 11)
+#define INTERRUPT_3D                   (ARM_IRQ0_BASE + 12)
+#define INTERRUPT_DMA2                 (ARM_IRQ0_BASE + 13)
+#define INTERRUPT_DMA3                 (ARM_IRQ0_BASE + 14)
+#define INTERRUPT_I2C                  (ARM_IRQ0_BASE + 15)
+#define INTERRUPT_SPI                  (ARM_IRQ0_BASE + 16)
+#define INTERRUPT_I2SPCM               (ARM_IRQ0_BASE + 17)
+#define INTERRUPT_SDIO                 (ARM_IRQ0_BASE + 18)
+#define INTERRUPT_UART                 (ARM_IRQ0_BASE + 19)
+#define INTERRUPT_ARASANSDIO           (ARM_IRQ0_BASE + 20)
+
+#define MAXIRQNUM                      (32 + 32 + 20)
+#define MAXFIQNUM                      (32 + 32 + 20)
+
+#define MAX_TIMER                       2
+#define MAX_PERIOD                      699050
+#define TICKS_PER_uSEC                  1
+
+/*
+ *  These are useconds NOT ticks.
+ *
+ */
+#define mSEC_1                          1000
+#define mSEC_5                          (mSEC_1 * 5)
+#define mSEC_10                         (mSEC_1 * 10)
+#define mSEC_25                         (mSEC_1 * 25)
+#define SEC_1                           (mSEC_1 * 1000)
+
+/*
+ * Watchdog
+ */
+#define PM_RSTC			       (PM_BASE+0x1c)
+#define PM_WDOG			       (PM_BASE+0x24)
+
+#define PM_WDOG_RESET                                         0000000000
+#define PM_PASSWORD		       0x5a000000
+#define PM_WDOG_TIME_SET	       0x000fffff
+#define PM_RSTC_WRCFG_CLR              0xffffffcf
+#define PM_RSTC_WRCFG_SET              0x00000030
+#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
+#define PM_RSTC_RESET			0x00000102
+
+
+
+
+
+#endif
+
+/* END */
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/platform.h.orig
@@ -0,0 +1,210 @@
+/*
+ * arch/arm/mach-bcm2708/include/mach/platform.h
+ *
+ * Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+
+#ifndef _BCM2708_PLATFORM_H
+#define _BCM2708_PLATFORM_H
+
+
+/* macros to get at IO space when running virtually */
+#define IO_ADDRESS(x)	(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+
+#define __io_address(a)     __io(IO_ADDRESS(a))
+
+
+/*
+ *  SDRAM
+ */
+#define BCM2708_SDRAM_BASE           0x00000000
+
+/*
+ *  Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  BCM2708 ARMCTRL Registers
+ * ------------------------------------------------------------------------
+ */
+
+#define HW_REGISTER_RW(addr) (addr)
+#define HW_REGISTER_RO(addr) (addr)
+
+#include "arm_control.h"
+#undef ARM_BASE
+
+/*
+ * Definitions and addresses for the ARM CONTROL logic
+ * This file is manually generated.
+ */
+
+#define BCM2708_PERI_BASE        0x20000000
+#define ST_BASE                  (BCM2708_PERI_BASE + 0x3000)   /* System Timer */
+#define DMA_BASE		 (BCM2708_PERI_BASE + 0x7000)	/* DMA controller */
+#define ARM_BASE                 (BCM2708_PERI_BASE + 0xB000)	 /* BCM2708 ARM control block */
+#define PM_BASE			 (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
+#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO */
+#define UART0_BASE               (BCM2708_PERI_BASE + 0x201000)	/* Uart 0 */
+#define MMCI0_BASE               (BCM2708_PERI_BASE + 0x202000) /* MMC interface */
+#define UART1_BASE               (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */
+#define EMMC_BASE                (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */
+#define SMI_BASE		 (BCM2708_PERI_BASE + 0x600000) /* SMI */
+#define USB_BASE                 (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB controller */
+
+
+#define ARMCTRL_BASE             (ARM_BASE + 0x000)
+#define ARMCTRL_IC_BASE          (ARM_BASE + 0x200)           /* ARM interrupt controller */
+#define ARMCTRL_TIMER0_1_BASE    (ARM_BASE + 0x400)           /* Timer 0 and 1 */
+#define ARMCTRL_0_SBM_BASE       (ARM_BASE + 0x800)           /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */
+
+
+/*
+ * Interrupt assignments
+ */
+
+#define ARM_IRQ1_BASE                  0
+#define INTERRUPT_TIMER0               (ARM_IRQ1_BASE + 0)
+#define INTERRUPT_TIMER1               (ARM_IRQ1_BASE + 1)
+#define INTERRUPT_TIMER2               (ARM_IRQ1_BASE + 2)
+#define INTERRUPT_TIMER3               (ARM_IRQ1_BASE + 3)
+#define INTERRUPT_CODEC0               (ARM_IRQ1_BASE + 4)
+#define INTERRUPT_CODEC1               (ARM_IRQ1_BASE + 5)
+#define INTERRUPT_CODEC2               (ARM_IRQ1_BASE + 6)
+#define INTERRUPT_VC_JPEG              (ARM_IRQ1_BASE + 7)
+#define INTERRUPT_ISP                  (ARM_IRQ1_BASE + 8)
+#define INTERRUPT_VC_USB               (ARM_IRQ1_BASE + 9)
+#define INTERRUPT_VC_3D                (ARM_IRQ1_BASE + 10)
+#define INTERRUPT_TRANSPOSER           (ARM_IRQ1_BASE + 11)
+#define INTERRUPT_MULTICORESYNC0       (ARM_IRQ1_BASE + 12)
+#define INTERRUPT_MULTICORESYNC1       (ARM_IRQ1_BASE + 13)
+#define INTERRUPT_MULTICORESYNC2       (ARM_IRQ1_BASE + 14)
+#define INTERRUPT_MULTICORESYNC3       (ARM_IRQ1_BASE + 15)
+#define INTERRUPT_DMA0                 (ARM_IRQ1_BASE + 16)
+#define INTERRUPT_DMA1                 (ARM_IRQ1_BASE + 17)
+#define INTERRUPT_VC_DMA2              (ARM_IRQ1_BASE + 18)
+#define INTERRUPT_VC_DMA3              (ARM_IRQ1_BASE + 19)
+#define INTERRUPT_DMA4                 (ARM_IRQ1_BASE + 20)
+#define INTERRUPT_DMA5                 (ARM_IRQ1_BASE + 21)
+#define INTERRUPT_DMA6                 (ARM_IRQ1_BASE + 22)
+#define INTERRUPT_DMA7                 (ARM_IRQ1_BASE + 23)
+#define INTERRUPT_DMA8                 (ARM_IRQ1_BASE + 24)
+#define INTERRUPT_DMA9                 (ARM_IRQ1_BASE + 25)
+#define INTERRUPT_DMA10                (ARM_IRQ1_BASE + 26)
+#define INTERRUPT_DMA11                (ARM_IRQ1_BASE + 27)
+#define INTERRUPT_DMA12                (ARM_IRQ1_BASE + 28)
+#define INTERRUPT_AUX                (ARM_IRQ1_BASE + 29)
+#define INTERRUPT_ARM                  (ARM_IRQ1_BASE + 30)
+#define INTERRUPT_VPUDMA               (ARM_IRQ1_BASE + 31)
+
+#define ARM_IRQ2_BASE                  32
+#define INTERRUPT_HOSTPORT             (ARM_IRQ2_BASE + 0)
+#define INTERRUPT_VIDEOSCALER          (ARM_IRQ2_BASE + 1)
+#define INTERRUPT_CCP2TX               (ARM_IRQ2_BASE + 2)
+#define INTERRUPT_SDC                  (ARM_IRQ2_BASE + 3)
+#define INTERRUPT_DSI0                 (ARM_IRQ2_BASE + 4)
+#define INTERRUPT_AVE                  (ARM_IRQ2_BASE + 5)
+#define INTERRUPT_CAM0                 (ARM_IRQ2_BASE + 6)
+#define INTERRUPT_CAM1                 (ARM_IRQ2_BASE + 7)
+#define INTERRUPT_HDMI0                (ARM_IRQ2_BASE + 8)
+#define INTERRUPT_HDMI1                (ARM_IRQ2_BASE + 9)
+#define INTERRUPT_PIXELVALVE1          (ARM_IRQ2_BASE + 10)
+#define INTERRUPT_I2CSPISLV            (ARM_IRQ2_BASE + 11)
+#define INTERRUPT_DSI1                 (ARM_IRQ2_BASE + 12)
+#define INTERRUPT_PWA0                 (ARM_IRQ2_BASE + 13)
+#define INTERRUPT_PWA1                 (ARM_IRQ2_BASE + 14)
+#define INTERRUPT_CPR                  (ARM_IRQ2_BASE + 15)
+#define INTERRUPT_SMI                  (ARM_IRQ2_BASE + 16)
+#define INTERRUPT_GPIO0                (ARM_IRQ2_BASE + 17)
+#define INTERRUPT_GPIO1                (ARM_IRQ2_BASE + 18)
+#define INTERRUPT_GPIO2                (ARM_IRQ2_BASE + 19)
+#define INTERRUPT_GPIO3                (ARM_IRQ2_BASE + 20)
+#define INTERRUPT_VC_I2C               (ARM_IRQ2_BASE + 21)
+#define INTERRUPT_VC_SPI               (ARM_IRQ2_BASE + 22)
+#define INTERRUPT_VC_I2SPCM            (ARM_IRQ2_BASE + 23)
+#define INTERRUPT_VC_SDIO              (ARM_IRQ2_BASE + 24)
+#define INTERRUPT_VC_UART              (ARM_IRQ2_BASE + 25)
+#define INTERRUPT_SLIMBUS              (ARM_IRQ2_BASE + 26)
+#define INTERRUPT_VEC                  (ARM_IRQ2_BASE + 27)
+#define INTERRUPT_CPG                  (ARM_IRQ2_BASE + 28)
+#define INTERRUPT_RNG                  (ARM_IRQ2_BASE + 29)
+#define INTERRUPT_VC_ARASANSDIO        (ARM_IRQ2_BASE + 30)
+#define INTERRUPT_AVSPMON              (ARM_IRQ2_BASE + 31)
+
+#define ARM_IRQ0_BASE                  64
+#define INTERRUPT_ARM_TIMER            (ARM_IRQ0_BASE + 0)
+#define INTERRUPT_ARM_MAILBOX          (ARM_IRQ0_BASE + 1)
+#define INTERRUPT_ARM_DOORBELL_0       (ARM_IRQ0_BASE + 2)
+#define INTERRUPT_ARM_DOORBELL_1       (ARM_IRQ0_BASE + 3)
+#define INTERRUPT_VPU0_HALTED          (ARM_IRQ0_BASE + 4)
+#define INTERRUPT_VPU1_HALTED          (ARM_IRQ0_BASE + 5)
+#define INTERRUPT_ILLEGAL_TYPE0        (ARM_IRQ0_BASE + 6)
+#define INTERRUPT_ILLEGAL_TYPE1        (ARM_IRQ0_BASE + 7)
+#define INTERRUPT_PENDING1             (ARM_IRQ0_BASE + 8)
+#define INTERRUPT_PENDING2             (ARM_IRQ0_BASE + 9)
+#define INTERRUPT_JPEG                 (ARM_IRQ0_BASE + 10)
+#define INTERRUPT_USB                  (ARM_IRQ0_BASE + 11)
+#define INTERRUPT_3D                   (ARM_IRQ0_BASE + 12)
+#define INTERRUPT_DMA2                 (ARM_IRQ0_BASE + 13)
+#define INTERRUPT_DMA3                 (ARM_IRQ0_BASE + 14)
+#define INTERRUPT_I2C                  (ARM_IRQ0_BASE + 15)
+#define INTERRUPT_SPI                  (ARM_IRQ0_BASE + 16)
+#define INTERRUPT_I2SPCM               (ARM_IRQ0_BASE + 17)
+#define INTERRUPT_SDIO                 (ARM_IRQ0_BASE + 18)
+#define INTERRUPT_UART                 (ARM_IRQ0_BASE + 19)
+#define INTERRUPT_ARASANSDIO           (ARM_IRQ0_BASE + 20)
+
+#define MAXIRQNUM                      (32 + 32 + 20)
+#define MAXFIQNUM                      (32 + 32 + 20)
+
+#define MAX_TIMER                       2
+#define MAX_PERIOD                      699050
+#define TICKS_PER_uSEC                  1
+
+/*
+ *  These are useconds NOT ticks.
+ *
+ */
+#define mSEC_1                          1000
+#define mSEC_5                          (mSEC_1 * 5)
+#define mSEC_10                         (mSEC_1 * 10)
+#define mSEC_25                         (mSEC_1 * 25)
+#define SEC_1                           (mSEC_1 * 1000)
+
+/*
+ * Watchdog
+ */
+#define PM_RSTC			       (PM_BASE+0x1c)
+#define PM_WDOG			       (PM_BASE+0x24)
+
+#define PM_WDOG_RESET                                         0000000000
+#define PM_PASSWORD		       0x5a000000
+#define PM_WDOG_TIME_SET	       0x000fffff
+#define PM_RSTC_WRCFG_CLR              0xffffffcf
+#define PM_RSTC_WRCFG_SET              0x00000030
+#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
+#define PM_RSTC_RESET			0x00000102
+
+
+
+
+
+#endif
+
+/* END */
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/power.h
@@ -0,0 +1,26 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/power.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This device provides a shared mechanism for controlling the power to
+ * VideoCore subsystems.
+ */
+
+#ifndef _MACH_BCM2708_POWER_H
+#define _MACH_BCM2708_POWER_H
+
+#include <linux/types.h>
+#include <mach/arm_power.h>
+
+typedef unsigned int BCM_POWER_HANDLE_T;
+
+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle);
+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request);
+extern int bcm_power_close(BCM_POWER_HANDLE_T handle);
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/system.h
@@ -0,0 +1,53 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/system.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	uint32_t pm_rstc, pm_wdog;
+	uint32_t timeout = 10;
+
+	/* Setup watchdog for reset */
+	pm_rstc = readl(IO_ADDRESS(PM_RSTC));
+
+	pm_wdog = PM_PASSWORD | (timeout & PM_WDOG_TIME_SET); // watchdog timer = timer clock / 16; need password (31:16) + value (11:0)
+	pm_rstc = PM_PASSWORD | (pm_rstc & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET;
+
+	writel(pm_wdog, IO_ADDRESS(PM_WDOG));
+	writel(pm_rstc, IO_ADDRESS(PM_RSTC));
+}
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/timex.h
@@ -0,0 +1,23 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/timex.h
+ *
+ *  BCM2708 sysem clock frequency
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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 CLOCK_TICK_RATE		(1000000)
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/uncompress.h
@@ -0,0 +1,49 @@
+/*
+ *  arch/arm/mach-bcn2708/include/mach/uncompress.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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 <linux/io.h>
+#include <mach/hardware.h>
+
+#define BCM2708_UART_DR	__io_address(UART0_BASE + 0x00)
+#define BCM2708_UART_FR	__io_address(UART0_BASE + 0x18)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+	while (readl(BCM2708_UART_FR) & (1 << 5))
+		barrier();
+
+	writel(c, BCM2708_UART_DR);
+}
+
+static inline void flush(void)
+{
+	while (readl(BCM2708_UART_FR) & (1 << 3))
+		barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/vc_mem.h
@@ -0,0 +1,34 @@
+/*****************************************************************************
+* Copyright 2010 - 2011 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#if !defined( VC_MEM_H )
+#define VC_MEM_H
+
+#include <linux/ioctl.h>
+
+#define VC_MEM_IOC_MAGIC  'v'
+
+#define VC_MEM_IOC_MEM_PHYS_ADDR    _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long )
+#define VC_MEM_IOC_MEM_SIZE         _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int )
+
+#if defined( __KERNEL__ )
+#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF
+
+extern unsigned long mm_vc_mem_phys_addr;
+extern unsigned int  mm_vc_mem_size;
+extern int vc_mem_get_current_size( void );
+#endif
+
+#endif  /* VC_MEM_H */
+
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h
@@ -0,0 +1,42 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/vcio.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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
+ */
+#ifndef _MACH_BCM2708_VCIO_H
+#define _MACH_BCM2708_VCIO_H
+
+/* Routines to handle I/O via the VideoCore "ARM control" registers
+ * (semaphores, doorbells, mailboxes)
+ */
+
+#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio"
+
+/* Constants shared with the ARM identifying separate mailbox channels */
+#define MBOX_CHAN_POWER   0 /* for use by the power management interface */
+#define MBOX_CHAN_FB      1 /* for use by the frame buffer */
+#define MBOX_CHAN_VUART   2 /* for use by the virtual UART */
+#define MBOX_CHAN_VCHIQ   3 /* for use by the VCHIQ interface */
+#define MBOX_CHAN_LEDS    4 /* for use by the leds interface */
+#define MBOX_CHAN_BUTTONS 5 /* for use by the buttons interface */
+#define MBOX_CHAN_TOUCH   6 /* for use by the touchscreen interface */
+#define MBOX_CHAN_COUNT   7
+
+extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28);
+extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28);
+
+#endif
--- /dev/null
+++ b/arch/arm/mach-bcm2708/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ *  arch/arm/mach-bcm2708/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * 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 VMALLOC_END		(0xd8000000)
--- /dev/null
+++ b/arch/arm/mach-bcm2708/power.c
@@ -0,0 +1,193 @@
+/*
+ *	 linux/arch/arm/mach-bcm2708/power.c
+ *
+ *	 Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This device provides a shared mechanism for controlling the power to
+ * VideoCore subsystems.
+ */
+
+#include <linux/module.h>
+#include <linux/semaphore.h>
+#include <linux/bug.h>
+#include <mach/power.h>
+#include <mach/vcio.h>
+#include <mach/arm_power.h>
+
+#define DRIVER_NAME "bcm2708_power"
+
+#define BCM_POWER_MAXCLIENTS 4
+#define BCM_POWER_NOCLIENT (1<<31)
+
+/* Some drivers expect there devices to be permanently powered */
+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB)
+
+#if 1
+#define DPRINTK printk
+#else
+#define DPRINTK if (0) printk
+#endif
+
+struct state_struct {
+	uint32_t global_request;
+	uint32_t client_request[BCM_POWER_MAXCLIENTS];
+	struct semaphore client_mutex;
+	struct semaphore mutex;
+} g_state;
+
+int bcm_power_open(BCM_POWER_HANDLE_T *handle)
+{
+	BCM_POWER_HANDLE_T i;
+	int ret = -EBUSY;
+
+	down(&g_state.client_mutex);
+
+	for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) {
+		if (g_state.client_request[i] == BCM_POWER_NOCLIENT) {
+			g_state.client_request[i] = BCM_POWER_NONE;
+			*handle = i;
+			ret = 0;
+			break;
+		}
+	}
+
+	up(&g_state.client_mutex);
+
+	DPRINTK("bcm_power_open() -> %d\n", *handle);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_power_open);
+
+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request)
+{
+	int rc = 0;
+
+	DPRINTK("bcm_power_request(%d, %x)\n", handle, request);
+
+	if ((handle < BCM_POWER_MAXCLIENTS) &&
+	    (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) {
+		if (down_interruptible(&g_state.mutex) != 0) {
+			DPRINTK("bcm_power_request -> interrupted\n");
+			return -EINTR;
+		}
+
+		if (request != g_state.client_request[handle]) {
+			uint32_t others_request = 0;
+			uint32_t global_request;
+			BCM_POWER_HANDLE_T i;
+
+			for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) {
+				if (i != handle)
+					others_request |=
+					    g_state.client_request[i];
+			}
+			others_request &= ~BCM_POWER_NOCLIENT;
+
+			global_request = request | others_request;
+			if (global_request != g_state.global_request) {
+				uint32_t actual;
+
+				/* Send a request to VideoCore */
+				bcm_mailbox_write(MBOX_CHAN_POWER,
+						  global_request << 4);
+
+				/* Wait for a response during power-up */
+				if (global_request & ~g_state.global_request) {
+					rc = bcm_mailbox_read(MBOX_CHAN_POWER,
+							      &actual);
+					DPRINTK
+					    ("bcm_mailbox_read -> %08x, %d\n",
+					     actual, rc);
+					actual >>= 4;
+				} else {
+					rc = 0;
+					actual = global_request;
+				}
+
+				if (rc == 0) {
+					if (actual != global_request) {
+						printk(KERN_ERR
+						     "%s: prev global %x, new global %x, actual %x, request %x, others_request %x\n",
+						     __func__,
+						     g_state.global_request,
+						     global_request, actual, request, others_request);
+						/* A failure */
+						BUG_ON((others_request & actual)
+						       != others_request);
+						request &= actual;
+						rc = -EIO;
+					}
+
+					g_state.global_request = actual;
+					g_state.client_request[handle] =
+					    request;
+				}
+			}
+		}
+		up(&g_state.mutex);
+	} else {
+		rc = -EINVAL;
+	}
+	DPRINTK("bcm_power_request -> %d\n", rc);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(bcm_power_request);
+
+int bcm_power_close(BCM_POWER_HANDLE_T handle)
+{
+	int rc;
+
+	DPRINTK("bcm_power_close(%d)\n", handle);
+
+	rc = bcm_power_request(handle, BCM_POWER_NONE);
+	if (rc == 0)
+		g_state.client_request[handle] = BCM_POWER_NOCLIENT;
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(bcm_power_close);
+
+static int __init bcm_power_init(void)
+{
+#if defined(BCM_POWER_ALWAYS_ON)
+	BCM_POWER_HANDLE_T always_on_handle;
+#endif
+	int rc = 0;
+	int i;
+
+	printk(KERN_INFO "bcm_power: Broadcom power driver\n");
+
+	for (i = 0; i < BCM_POWER_MAXCLIENTS; i++)
+		g_state.client_request[i] = BCM_POWER_NOCLIENT;
+
+	sema_init(&g_state.client_mutex, 1);
+	sema_init(&g_state.mutex, 1);
+
+	g_state.global_request = 0;
+
+#if defined(BCM_POWER_ALWAYS_ON)
+	if (BCM_POWER_ALWAYS_ON) {
+		bcm_power_open(&always_on_handle);
+		bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON);
+	}
+#endif
+
+	return rc;
+}
+
+static void __exit bcm_power_exit(void)
+{
+	bcm_mailbox_write(MBOX_CHAN_POWER, 0);
+}
+
+arch_initcall(bcm_power_init);	/* Initialize early */
+module_exit(bcm_power_exit);
+
+MODULE_AUTHOR("Phil Elwell");
+MODULE_DESCRIPTION("Interface to BCM2708 power management");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/arch/arm/mach-bcm2708/vc_mem.c
@@ -0,0 +1,467 @@
+/*****************************************************************************
+* Copyright 2010 - 2011 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_ARCH_KONA
+#include <chal/chal_ipc.h>
+#elif CONFIG_ARCH_BCM2708
+#else
+#include <csp/chal_ipc.h>
+#endif
+
+#include "mach/vc_mem.h"
+//#include "interface/vchiq_arm/vchiq_connected.h"
+
+#define DRIVER_NAME  "vc-mem"
+
+// Uncomment to enable debug logging
+//#define ENABLE_DBG
+
+#if defined(ENABLE_DBG)
+#define LOG_DBG( fmt, ... )  printk( KERN_INFO fmt "\n", ##__VA_ARGS__ )
+#else
+#define LOG_DBG( fmt, ... )
+#endif
+#define LOG_ERR( fmt, ... )  printk( KERN_ERR fmt "\n", ##__VA_ARGS__ )
+
+// Device (/dev) related variables
+static dev_t vc_mem_devnum = 0;
+static struct class *vc_mem_class = NULL;
+static struct cdev vc_mem_cdev;
+static int vc_mem_inited = 0;
+
+// Proc entry
+static struct proc_dir_entry *vc_mem_proc_entry;
+
+/*
+ * Videocore memory addresses and size
+ *
+ * Drivers that wish to know the videocore memory addresses and sizes should
+ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in
+ * headers. This allows the other drivers to not be tied down to a a certain
+ * address/size at compile time.
+ *
+ * In the future, the goal is to have the videocore memory virtual address and
+ * size be calculated at boot time rather than at compile time. The decision of
+ * where the videocore memory resides and its size would be in the hands of the
+ * bootloader (and/or kernel). When that happens, the values of these variables
+ * would be calculated and assigned in the init function.
+ */
+#ifdef CONFIG_ARCH_KONA
+
+#include <mach/io_map.h>
+unsigned long mm_vc_mem_phys_addr = VC_EMI;
+
+#elif CONFIG_ARCH_BCM2708
+
+// in the 2835 VC in mapped above ARM, but ARM has full access to VC space
+unsigned long mm_vc_mem_phys_addr = 0x00000000;
+
+#else
+
+#include <mach/csp/mm_io.h>
+unsigned long mm_vc_mem_phys_addr = MM_ADDR_IO_VC_EMI;
+
+#endif
+
+unsigned int mm_vc_mem_size = 0;
+
+EXPORT_SYMBOL(mm_vc_mem_phys_addr);
+EXPORT_SYMBOL(mm_vc_mem_size);
+
+/****************************************************************************
+*
+*   vc_mem_open
+*
+***************************************************************************/
+
+static int
+vc_mem_open(struct inode *inode, struct file *file)
+{
+	(void) inode;
+	(void) file;
+
+	LOG_DBG("%s: called file = 0x%p", __func__, file);
+
+	return 0;
+}
+
+/****************************************************************************
+*
+*   vc_mem_release
+*
+***************************************************************************/
+
+static int
+vc_mem_release(struct inode *inode, struct file *file)
+{
+	(void) inode;
+	(void) file;
+
+	LOG_DBG("%s: called file = 0x%p", __func__, file);
+
+	return 0;
+}
+
+/****************************************************************************
+*
+*   vc_mem_get_size
+*
+***************************************************************************/
+
+static void
+vc_mem_get_size(void)
+{
+#ifdef CONFIG_ARCH_BCM2708
+	mm_vc_mem_size = 256 * 1024 * 1024;	// Static for now
+#else
+	CHAL_IPC_HANDLE ipc_handle;
+	uint32_t wakeup_register;
+
+	// Get the videocore memory size from the IPC mailbox if not yet
+	// assigned.
+	if (mm_vc_mem_size == 0) {
+		ipc_handle = chal_ipc_config(NULL);
+		if (ipc_handle == NULL) {
+			LOG_ERR("%s: failed to get IPC handlle", __func__);
+			return;
+		}
+
+		chal_ipc_query_wakeup_vc(ipc_handle, &wakeup_register);
+		if ((wakeup_register & ~1) == 0) {
+			LOG_DBG("%s: videocore not yet loaded, skipping...",
+				__func__);
+		} else {
+			if (chal_ipc_read_mailbox(ipc_handle,
+						  IPC_MAILBOX_ID_0,
+						  &mm_vc_mem_size) !=
+			    BCM_SUCCESS) {
+				LOG_ERR("%s: failed to read from IPC mailbox",
+					__func__);
+			}
+		}
+	}
+#endif
+}
+
+/****************************************************************************
+*
+*   vc_mem_get_current_size
+*
+***************************************************************************/
+
+int
+vc_mem_get_current_size(void)
+{
+	vc_mem_get_size();
+	return mm_vc_mem_size;
+}
+
+EXPORT_SYMBOL_GPL(vc_mem_get_current_size);
+
+/****************************************************************************
+*
+*   vc_mem_ioctl
+*
+***************************************************************************/
+
+static long
+vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+
+	(void) cmd;
+	(void) arg;
+
+	LOG_DBG("%s: called file = 0x%p", __func__, file);
+
+	switch (cmd) {
+	case VC_MEM_IOC_MEM_PHYS_ADDR:
+		{
+			LOG_DBG("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p",
+				__func__, (void *) mm_vc_mem_phys_addr);
+
+			if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr,
+					 sizeof (mm_vc_mem_phys_addr)) != 0) {
+				rc = -EFAULT;
+			}
+			break;
+		}
+	case VC_MEM_IOC_MEM_SIZE:
+		{
+			// Get the videocore memory size first
+			vc_mem_get_size();
+
+			LOG_DBG("%s: VC_MEM_IOC_MEM_SIZE=%u", __func__,
+				mm_vc_mem_size);
+
+			if (copy_to_user((void *) arg, &mm_vc_mem_size,
+					 sizeof (mm_vc_mem_size)) != 0) {
+				rc = -EFAULT;
+			}
+			break;
+		}
+	default:
+		{
+			return -ENOTTY;
+		}
+	}
+	LOG_DBG("%s: file = 0x%p returning %d", __func__, file, rc);
+
+	return rc;
+}
+
+/****************************************************************************
+*
+*   vc_mem_mmap
+*
+***************************************************************************/
+
+static int
+vc_mem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	int rc = 0;
+	unsigned long length = vma->vm_end - vma->vm_start;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+	LOG_DBG("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx",
+		__func__, (long) vma->vm_start, (long) vma->vm_end,
+		(long) vma->vm_pgoff);
+
+	if (offset + length > mm_vc_mem_size) {
+		LOG_ERR("%s: length %ld is too big", __func__, length);
+		return -EINVAL;
+	}
+	// Do not cache the memory map
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	rc = remap_pfn_range(vma, vma->vm_start,
+			     (mm_vc_mem_phys_addr >> PAGE_SHIFT) +
+			     vma->vm_pgoff, length, vma->vm_page_prot);
+	if (rc != 0) {
+		LOG_ERR("%s: remap_pfn_range failed (rc=%d)", __func__, rc);
+	}
+
+	return rc;
+}
+
+/****************************************************************************
+*
+*   File Operations for the driver.
+*
+***************************************************************************/
+
+static const struct file_operations vc_mem_fops = {
+	.owner = THIS_MODULE,
+	.open = vc_mem_open,
+	.release = vc_mem_release,
+	.unlocked_ioctl = vc_mem_ioctl,
+	.mmap = vc_mem_mmap,
+};
+
+/****************************************************************************
+*
+*   vc_mem_proc_read
+*
+***************************************************************************/
+
+static int
+vc_mem_proc_read(char *buf, char **start, off_t offset, int count, int *eof,
+		 void *data)
+{
+	char *p = buf;
+
+	(void) start;
+	(void) count;
+	(void) data;
+
+	if (offset > 0) {
+		*eof = 1;
+		return 0;
+	}
+	// Get the videocore memory size first
+	vc_mem_get_size();
+
+	p += sprintf(p, "Videocore memory:\n");
+	if (mm_vc_mem_phys_addr != 0)
+		p += sprintf(p, "   Physical address: 0x%p\n",
+			     (void *) mm_vc_mem_phys_addr);
+	else
+		p += sprintf(p, "   Physical address: 0x00000000\n");
+	p += sprintf(p, "   Length (bytes):   %u\n", mm_vc_mem_size);
+
+	*eof = 1;
+	return p - buf;
+}
+
+/****************************************************************************
+*
+*   vc_mem_proc_write
+*
+***************************************************************************/
+
+static int
+vc_mem_proc_write(struct file *file, const char __user * buffer,
+		  unsigned long count, void *data)
+{
+	int rc = -EFAULT;
+	char input_str[10];
+
+	memset(input_str, 0, sizeof (input_str));
+
+	if (count > sizeof (input_str)) {
+		LOG_ERR("%s: input string length too long", __func__);
+		goto out;
+	}
+
+	if (copy_from_user(input_str, buffer, count - 1)) {
+		LOG_ERR("%s: failed to get input string", __func__);
+		goto out;
+	}
+
+	if (strncmp(input_str, "connect", strlen("connect")) == 0) {
+		// Get the videocore memory size from the videocore
+		vc_mem_get_size();
+	}
+
+      out:
+	return rc;
+}
+
+/****************************************************************************
+*
+*   vc_mem_connected_init
+*
+*   This function is called once the videocore has been connected.
+*
+***************************************************************************/
+
+void
+vc_mem_connected_init(void)
+{
+	int rc = -EFAULT;
+	struct device *dev;
+
+	LOG_DBG("%s: called", __func__);
+
+	vc_mem_get_size();
+
+	printk("vc-mem: mm_vc_mem_phys_addr = 0x%08lx\n", mm_vc_mem_phys_addr);
+	printk("vc-mem: mm_vc_mem_size      = 0x%08x (%u MiB)\n",
+	       mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024));
+
+	if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) {
+		LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__, rc);
+		goto out_err;
+	}
+
+	cdev_init(&vc_mem_cdev, &vc_mem_fops);
+	if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) {
+		LOG_ERR("%s: cdev_add failed (rc=%d)", __func__, rc);
+		goto out_unregister;
+	}
+
+	vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME);
+	if (IS_ERR(vc_mem_class)) {
+		rc = PTR_ERR(vc_mem_class);
+		LOG_ERR("%s: class_create failed (rc=%d)", __func__, rc);
+		goto out_cdev_del;
+	}
+
+	dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL,
+			    DRIVER_NAME);
+	if (IS_ERR(dev)) {
+		rc = PTR_ERR(dev);
+		LOG_ERR("%s: device_create failed (rc=%d)", __func__, rc);
+		goto out_class_destroy;
+	}
+
+	vc_mem_proc_entry = create_proc_entry(DRIVER_NAME, 0444, NULL);
+	if (vc_mem_proc_entry == NULL) {
+		rc = -EFAULT;
+		LOG_ERR("%s: create_proc_entry failed", __func__);
+		goto out_device_destroy;
+	}
+	vc_mem_proc_entry->read_proc = vc_mem_proc_read;
+	vc_mem_proc_entry->write_proc = vc_mem_proc_write;
+
+	vc_mem_inited = 1;
+	return;
+
+      out_device_destroy:
+	device_destroy(vc_mem_class, vc_mem_devnum);
+
+      out_class_destroy:
+	class_destroy(vc_mem_class);
+	vc_mem_class = NULL;
+
+      out_cdev_del:
+	cdev_del(&vc_mem_cdev);
+
+      out_unregister:
+	unregister_chrdev_region(vc_mem_devnum, 1);
+
+      out_err:
+	return;
+}
+
+/****************************************************************************
+*
+*   vc_mem_init
+*
+***************************************************************************/
+
+static int __init
+vc_mem_init(void)
+{
+	printk(KERN_INFO "vc-mem: Videocore memory driver\n");
+
+	//vchiq_add_connected_callback(vc_mem_connected_init);
+
+	return 0;
+}
+
+/****************************************************************************
+*
+*   vc_mem_exit
+*
+***************************************************************************/
+
+static void __exit
+vc_mem_exit(void)
+{
+	LOG_DBG("%s: called", __func__);
+
+	if (vc_mem_inited) {
+		remove_proc_entry(vc_mem_proc_entry->name, NULL);
+		device_destroy(vc_mem_class, vc_mem_devnum);
+		class_destroy(vc_mem_class);
+		cdev_del(&vc_mem_cdev);
+		unregister_chrdev_region(vc_mem_devnum, 1);
+	}
+}
+
+module_init(vc_mem_init);
+module_exit(vc_mem_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Broadcom Corporation");
--- /dev/null
+++ b/arch/arm/mach-bcm2708/vcio.c
@@ -0,0 +1,309 @@
+/*
+ *  linux/arch/arm/mach-bcm2708/vcio.c
+ *
+ *  Copyright (C) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This device provides a shared mechanism for writing to the mailboxes,
+ * semaphores, doorbells etc. that are shared between the ARM and the
+ * VideoCore processor
+ */
+
+#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <linux/io.h>
+
+#include <mach/vcio.h>
+#include <mach/platform.h>
+
+#define DRIVER_NAME BCM_VCIO_DRIVER_NAME
+
+/* ----------------------------------------------------------------------
+ *	Mailbox
+ * -------------------------------------------------------------------- */
+
+/* offsets from a mail box base address */
+#define MAIL_WRT	0x00	/* write - and next 4 words */
+#define MAIL_RD		0x00	/* read - and next 4 words */
+#define MAIL_POL	0x10	/* read without popping the fifo */
+#define MAIL_SND	0x14	/* sender ID (bottom two bits) */
+#define MAIL_STA	0x18	/* status */
+#define MAIL_CNF	0x1C	/* configuration */
+
+#define MBOX_MSG(chan, data28)		(((data28) & ~0xf) | ((chan) & 0xf))
+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf))
+#define MBOX_CHAN(msg)			((msg) & 0xf)
+#define MBOX_DATA28(msg)		((msg) & ~0xf)
+#define MBOX_DATA28_LSB(msg)		(((uint32_t)msg) >> 4)
+
+#define MBOX_MAGIC 0xd0d0c0de
+
+struct vc_mailbox {
+	struct device *dev;	/* parent device */
+	void __iomem *status;
+	void __iomem *config;
+	void __iomem *read;
+	void __iomem *write;
+	uint32_t msg[MBOX_CHAN_COUNT];
+	struct semaphore sema[MBOX_CHAN_COUNT];
+	uint32_t magic;
+};
+
+static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev,
+		      uint32_t addr_mbox)
+{
+	int i;
+
+	mbox_out->dev = dev;
+	mbox_out->status = __io_address(addr_mbox + MAIL_STA);
+	mbox_out->config = __io_address(addr_mbox + MAIL_CNF);
+	mbox_out->read = __io_address(addr_mbox + MAIL_RD);
+	/* Write to the other mailbox */
+	mbox_out->write =
+	    __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) +
+			 MAIL_WRT);
+
+	for (i = 0; i < MBOX_CHAN_COUNT; i++) {
+		mbox_out->msg[i] = 0;
+		sema_init(&mbox_out->sema[i], 0);
+	}
+
+	/* Enable the interrupt on data reception */
+	writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config);
+
+	mbox_out->magic = MBOX_MAGIC;
+}
+
+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28)
+{
+	int rc;
+
+	if (mbox->magic != MBOX_MAGIC)
+		rc = -EINVAL;
+	else {
+		/* wait for the mailbox FIFO to have some space in it */
+		while (0 != (readl(mbox->status) & ARM_MS_FULL))
+			cpu_relax();
+
+		writel(MBOX_MSG(chan, data28), mbox->write);
+		rc = 0;
+	}
+	return rc;
+}
+
+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28)
+{
+	int rc;
+
+	if (mbox->magic != MBOX_MAGIC)
+		rc = -EINVAL;
+	else {
+		if (mbox->msg[chan] ||
+		    (down_interruptible(&mbox->sema[chan]) == 0)) {
+			*data28 = MBOX_DATA28(mbox->msg[chan]);
+			mbox->msg[chan] = 0;
+			rc = 0;
+		} else {
+			/* The wait was interrupted */
+			rc = -EINTR;
+		}
+	}
+	return rc;
+}
+
+static irqreturn_t mbox_irq(int irq, void *dev_id)
+{
+	/* wait for the mailbox FIFO to have some data in it */
+	struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id;
+	int status = readl(mbox->status);
+	int ret = IRQ_NONE;
+
+	while (!(status & ARM_MS_EMPTY)) {
+		uint32_t msg = readl(mbox->read);
+		int chan = MBOX_CHAN(msg);
+		if (chan < MBOX_CHAN_COUNT) {
+			if (mbox->msg[chan]) {
+				/* Overflow */
+				printk(KERN_ERR DRIVER_NAME
+				       ": mbox chan %d overflow - drop %08x\n",
+				       chan, msg);
+			} else {
+				mbox->msg[chan] = (msg | 0xf);
+				up(&mbox->sema[chan]);
+			}
+		} else {
+			printk(KERN_ERR DRIVER_NAME
+			       ": invalid channel selector (msg %08x)\n", msg);
+		}
+		ret = IRQ_HANDLED;
+		status = readl(mbox->status);
+	}
+	return ret;
+}
+
+static struct irqaction mbox_irqaction = {
+	.name = "ARM Mailbox IRQ",
+	.flags = IRQF_DISABLED | IRQF_IRQPOLL,
+	.handler = mbox_irq,
+};
+
+/* ----------------------------------------------------------------------
+ *	Mailbox Methods
+ * -------------------------------------------------------------------- */
+
+static struct device *mbox_dev;	/* we assume there's only one! */
+
+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28)
+{
+	int rc;
+
+	struct vc_mailbox *mailbox = dev_get_drvdata(dev);
+	device_lock(dev);
+	rc = mbox_write(mailbox, chan, data28);
+	device_unlock(dev);
+
+	return rc;
+}
+
+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28)
+{
+	int rc;
+
+	struct vc_mailbox *mailbox = dev_get_drvdata(dev);
+	device_lock(dev);
+	rc = mbox_read(mailbox, chan, data28);
+	device_unlock(dev);
+
+	return rc;
+}
+
+extern int bcm_mailbox_write(unsigned chan, uint32_t data28)
+{
+	if (mbox_dev)
+		return dev_mbox_write(mbox_dev, chan, data28);
+	else
+		return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(bcm_mailbox_write);
+
+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28)
+{
+	if (mbox_dev)
+		return dev_mbox_read(mbox_dev, chan, data28);
+	else
+		return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(bcm_mailbox_read);
+
+static void dev_mbox_register(const char *dev_name, struct device *dev)
+{
+	mbox_dev = dev;
+}
+
+/* ----------------------------------------------------------------------
+ *	Platform Device for Mailbox
+ * -------------------------------------------------------------------- */
+
+static int bcm_vcio_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct vc_mailbox *mailbox;
+
+	mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL);
+	if (NULL == mailbox) {
+		printk(KERN_ERR DRIVER_NAME ": failed to allocate "
+		       "mailbox memory\n");
+		ret = -ENOMEM;
+	} else {
+		struct resource *res;
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (res == NULL) {
+			printk(KERN_ERR DRIVER_NAME ": failed to obtain memory "
+			       "resource\n");
+			ret = -ENODEV;
+			kfree(mailbox);
+		} else {
+			/* should be based on the registers from res really */
+			mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD);
+
+			platform_set_drvdata(pdev, mailbox);
+			dev_mbox_register(DRIVER_NAME, &pdev->dev);
+
+			mbox_irqaction.dev_id = mailbox;
+			setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction);
+			printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n",
+			       __io_address(ARM_0_MAIL0_RD));
+		}
+	}
+	return ret;
+}
+
+static int bcm_vcio_remove(struct platform_device *pdev)
+{
+	struct vc_mailbox *mailbox = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(mailbox);
+
+	return 0;
+}
+
+static struct platform_driver bcm_mbox_driver = {
+	.probe = bcm_vcio_probe,
+	.remove = bcm_vcio_remove,
+
+	.driver = {
+		   .name = DRIVER_NAME,
+		   .owner = THIS_MODULE,
+		   },
+};
+
+static int __init bcm_mbox_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n");
+
+	ret = platform_driver_register(&bcm_mbox_driver);
+	if (ret != 0) {
+		printk(KERN_ERR DRIVER_NAME ": failed to register "
+		       "on platform\n");
+	} 
+
+	return ret;
+}
+
+static void __exit bcm_mbox_exit(void)
+{
+	platform_driver_unregister(&bcm_mbox_driver);
+}
+
+arch_initcall(bcm_mbox_init);	/* Initialize early */
+module_exit(bcm_mbox_exit);
+
+MODULE_AUTHOR("Gray Girling");
+MODULE_DESCRIPTION("ARM I/O to VideoCore processor");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bcm-mbox");
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -390,7 +390,7 @@ config CPU_PJ4
 
 # ARMv6
 config CPU_V6
-	bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
+	bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_PABRT_V6
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -855,9 +855,11 @@ do_alignment(unsigned long addr, unsigne
 	case 0x08000000:	/* ldm or stm, or thumb-2 32bit instruction */
 		if (thumb2_32b)
 			handler = do_alignment_t32_to_handler(&instr, regs, &offset);
-		else
+		else {
+                        offset.un = 0; /* to keep compiler happy */
 			handler = do_alignment_ldmstm;
-		break;
+		}
+                break;
 
 	default:
 		goto bad;
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset)
  *
  *	IRQs are already disabled.
  */
+
+/* See jira SW-5991 for details of this workaround */
 ENTRY(cpu_v6_do_idle)
-	mov	r1, #0
-	mcr	p15, 0, r1, c7, c10, 4		@ DWB - WFI may enter a low-power mode
-	mcr	p15, 0, r1, c7, c0, 4		@ wait for interrupt
+	.align 5
+	mov     r1, #2
+1:	subs	r1, #1
+	nop
+	mcreq	p15, 0, r1, c7, c10, 4		@ DWB - WFI may enter a low-power mode
+	mcreq	p15, 0, r1, c7, c0, 4		@ wait for interrupt
+	nop
+	nop
+	nop
+	bne 1b
 	mov	pc, lr
 
 ENTRY(cpu_v6_dcache_clean_area)
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -229,6 +229,27 @@ config MMC_SDHCI_S3C_DMA
 
 	  YMMV.
 
+config MMC_SDHCI_BCM2708
+	tristate "SDHCI support on BCM2708"
+	depends on MMC_SDHCI && MACH_BCM2708
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  often referrered to as the eMMC block.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
+config MMC_SDHCI_BCM2708_DMA
+	bool "DMA support on BCM2708 Arasan controller"
+	depends on MMC_SDHCI_BCM2708 && EXPERIMENTAL
+	help
+	  Enable DMA support on the Arasan SDHCI controller in Broadcom 2708
+          based chips.
+
+          If unsure, say N.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
@@ -296,6 +317,14 @@ config MMC_ATMELMCI
 	  If unsure, say N.
 
 endchoice
+config MMC_BCM2708
+	tristate "BCM2708 Multimedia Card Interface support"
+	help
+	  This selects the BCM2708 Multimedia Card Interface driver. If
+	  you have a BCM2708 platform with a Multimedia Card
+	  slot, say Y or M here.
+
+	  If unsure, say N.
 
 config MMC_ATMELMCI_DMA
 	bool "Atmel MCI DMA support"
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3)	+= sdhci-p
 obj-$(CONFIG_MMC_SDHCI_PXAV2)	+= sdhci-pxav2.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
 obj-$(CONFIG_MMC_SDHCI_SPEAR)	+= sdhci-spear.o
+obj-$(CONFIG_MMC_SDHCI_BCM2708)	+= sdhci-bcm2708.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
@@ -53,6 +54,8 @@ obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
 
+obj-$(CONFIG_MMC_BCM2708)       += bcm2708_mci.o
+
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
 endif
--- /dev/null
+++ b/drivers/mmc/host/bcm2708_mci.c
@@ -0,0 +1,889 @@
+/*
+ *  linux/drivers/mmc/host/bcm2708_mci.c - Broadcom BCM2708 MCI driver
+ *
+ *  Copyright (C) 2010 Broadcom, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/log2.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cacheflush.h>
+#include <asm/div64.h>
+#include <asm/io.h>
+#include <asm/sizes.h>
+//#include <asm/mach/mmc.h>
+
+#include <mach/gpio.h>
+
+#include "bcm2708_mci.h"
+
+#define DRIVER_NAME "bcm2708_mci"
+
+//#define PIO_DEBUG
+#ifdef PIO_DEBUG
+#define DBG(host,fmt,args...)	\
+	printk(KERN_ERR"%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
+#else
+#define DBG(host,fmt,args...)	\
+	pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
+#endif
+
+#define USE_DMA
+#define USE_DMA_IRQ
+
+#ifdef USE_DMA
+#define SDHOST_DMA_CHANNEL 5
+#endif
+
+#define BCM2708_DMA_ACTIVE	(1 << 0)
+#define BCM2708_DMA_INT		(1 << 2)
+
+#define BCM2708_DMA_INT_EN	(1 << 0)
+#define BCM2708_DMA_D_INC	(1 << 4)
+#define BCM2708_DMA_D_WIDTH	(1 << 5)
+#define BCM2708_DMA_D_DREQ	(1 << 6)
+#define BCM2708_DMA_S_INC	(1 << 8)
+#define BCM2708_DMA_S_WIDTH	(1 << 9)
+#define BCM2708_DMA_S_DREQ	(1 << 10)
+
+#define	BCM2708_DMA_PER_MAP(x)	((x) << 16)
+
+#define BCM2708_DMA_DREQ_SDHOST	13
+
+#define BCM2708_DMA_CS		0x00
+#define BCM2708_DMA_ADDR	0x04
+
+static void dump_sd_regs(void * mmc_base );
+static int bcm2708_mci_reset(struct bcm2708_mci_host *host);
+
+static void do_command(void __iomem *base, u32 c, u32 a)
+{
+	u32 cmdsts = 0;
+	writel(a, base + BCM2708_MCI_ARGUMENT);
+	writel(c | BCM2708_MCI_ENABLE, base + BCM2708_MCI_COMMAND);
+
+	/* check for error and command done */
+	cmdsts = readl(base + BCM2708_MCI_COMMAND);
+	while ((cmdsts & BCM2708_MCI_ENABLE) && (!(cmdsts & BCM2708_MCI_FAIL_FLAG)))
+		cmdsts = readl(base + BCM2708_MCI_COMMAND);
+	if (cmdsts & BCM2708_MCI_FAIL_FLAG) {
+		printk(KERN_DEBUG"%s: Command %d failed with arg %d\n", __func__, c, a);
+		dump_sd_regs(base);
+	}
+}
+
+//static void discard_words(void __iomem *base, int words)
+//{
+//	int i;
+//	for (i = 0; i < words; i++) {
+//		while (!(readl(base + BCM2708_MCI_STATUS) & BCM2708_MCI_DATAFLAG));
+//		readl(base + BCM2708_MCI_DATA);
+//	}
+//}
+
+#define CACHE_LINE_MASK 31
+
+static int suitable_for_dma(struct scatterlist *sg_ptr, int sg_len)
+{
+	int i;
+
+	for (i = 0; i < sg_len; i++) {
+		if (sg_ptr[i].offset & CACHE_LINE_MASK || sg_ptr[i].length & CACHE_LINE_MASK)
+			return 0;
+	}
+
+	return 1;
+}
+
+static void wait_for_complete(struct bcm2708_mci_host *host,
+			      void __iomem *mmc_base)
+{
+#ifdef USE_SDHOST_IRQ
+#error not implemented yet
+#else
+	while ((readl(mmc_base + BCM2708_MCI_STATUS) &
+		(BCM2708_MCI_HSTS_BUSY | BCM2708_MCI_HSTS_BLOCK)) == 0)
+		continue;
+
+	writel(BCM2708_MCI_HSTS_BUSY | BCM2708_MCI_HSTS_BLOCK,
+	       mmc_base + BCM2708_MCI_STATUS);
+#endif
+}
+
+static void dump_sd_regs(void * mmc_base )
+{
+	printk(KERN_DEBUG"Registers:\n");
+	printk(KERN_DEBUG"SDCMD:0x%x\n", readl(mmc_base + BCM2708_MCI_COMMAND));
+	printk(KERN_DEBUG"SDARG:0x%x\n", readl(mmc_base + BCM2708_MCI_ARGUMENT));
+	printk(KERN_DEBUG"SDTOUT:0x%x\n", readl(mmc_base + BCM2708_MCI_TIMEOUT));
+	printk(KERN_DEBUG"SDCDIV:0x%x\n", readl(mmc_base + BCM2708_MCI_CLKDIV));
+	printk(KERN_DEBUG"SDRSP0:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE0));
+	printk(KERN_DEBUG"SDRSP1:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE1));
+	printk(KERN_DEBUG"SDRSP2:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE2));
+	printk(KERN_DEBUG"SDRSP3:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE3));
+	printk(KERN_DEBUG"SDHSTS:0x%x\n", readl(mmc_base + BCM2708_MCI_STATUS));
+	printk(KERN_DEBUG"SDPO:0x%x\n", readl(mmc_base + BCM2708_MCI_VDD));
+	printk(KERN_DEBUG"SDEDM:0x%x\n", readl(mmc_base + BCM2708_MCI_EDM));
+	printk(KERN_DEBUG"SDHCFG:0x%x\n", readl(mmc_base + BCM2708_MCI_HOSTCONFIG));
+	printk(KERN_DEBUG"SDHBCT:0x%x\n", readl(mmc_base + BCM2708_MCI_HBCT));
+	//printk(KERN_ERR"SDDATA:0x%x\n", readl(mmc_base + BCM2708_MCI_DATA));
+	printk(KERN_DEBUG"SDHBLC:0x%x\n", readl(mmc_base + BCM2708_MCI_HBLC));
+}
+
+
+static void
+bcm2708_mci_start_command(struct bcm2708_mci_host *host, struct mmc_command *cmd, struct mmc_data *data)
+{
+	void __iomem *mmc_base = host->mmc_base;
+	void __iomem *dma_base = host->dma_base;
+	u32 status;
+	u32 c;
+	int redo = 0;
+
+	DBG(host, "op %02x arg %08x flags %08x\n",
+	    cmd->opcode, cmd->arg, cmd->flags);
+
+back:
+
+	/*
+	 * clear the controller status register
+	 */
+
+	writel(-1, mmc_base + BCM2708_MCI_STATUS);
+
+	/*
+	 * build the command register write, incorporating no
+         * response, long response, busy, read and write flags
+	 */
+
+	c = cmd->opcode;
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		if (cmd->flags & MMC_RSP_136)
+			c |= BCM2708_MCI_LONGRESP;
+	} else
+		c |= BCM2708_MCI_NORESP;
+	if (cmd->flags & MMC_RSP_BUSY)
+		c |= BCM2708_MCI_BUSY;
+
+	if (data) {
+		if (data->flags & MMC_DATA_READ)
+			c |= BCM2708_MCI_READ;
+		else
+			c |= BCM2708_MCI_WRITE;
+
+		DBG(host, "BYTECOUT %d BLOCKCOUNT %d .. ",readl(mmc_base + BCM2708_MCI_HBCT), readl(mmc_base + BCM2708_MCI_HBLC));
+		DBG(host, "set blocksize to %d\n", data->blksz);
+		DBG(host, "set blockcnt to %d\n", data->blocks);
+		writel( data->blksz, mmc_base + BCM2708_MCI_HBCT);
+		writel(data->blocks, mmc_base + BCM2708_MCI_HBLC);
+	}
+
+	/*
+         * run the command and wait for it to complete
+	 */
+
+	DBG(host, "executing command=%d\n", cmd->opcode);
+
+	do_command(mmc_base, c, cmd->arg);
+
+	DBG(host, "done cmd=%d\n", cmd->opcode);
+
+	if (c & BCM2708_MCI_BUSY) {
+
+		DBG(host, "waiting for command(%d) to complete\n", cmd->opcode);
+		wait_for_complete(host, mmc_base);
+		DBG(host, "done waiting for command(%d)\n", cmd->opcode);
+	}
+
+	/*
+	 * retrieve the response and error (if any)
+	 */
+
+	status = readl(mmc_base + BCM2708_MCI_STATUS);
+
+	if (cmd->flags & MMC_RSP_136) {
+		cmd->resp[3] = readl(mmc_base + BCM2708_MCI_RESPONSE0);
+		cmd->resp[2] = readl(mmc_base + BCM2708_MCI_RESPONSE1);
+		cmd->resp[1] = readl(mmc_base + BCM2708_MCI_RESPONSE2);
+		cmd->resp[0] = readl(mmc_base + BCM2708_MCI_RESPONSE3);
+	} else {
+		cmd->resp[0] = readl(mmc_base + BCM2708_MCI_RESPONSE0);
+	}
+
+	if (status & BCM2708_MCI_CMDTIMEOUT) {
+		printk(KERN_DEBUG "mmc driver saw timeout with opcode = %d, data = 0x%08x, timeout = %d", cmd->opcode, (unsigned int)data, readl(mmc_base + BCM2708_MCI_TIMEOUT));
+		if (data)
+			printk(KERN_DEBUG " data->sg_len = %d\n", data->sg_len);
+		else
+			printk(KERN_DEBUG "\n");
+		if (!redo) {
+			printk(KERN_DEBUG "redo\n");
+			redo = 1;
+			goto back;
+		} else
+			cmd->error = -ETIMEDOUT;
+	}
+
+	/*
+	 * pump data if necessary
+	 */
+
+	if (data) {
+		unsigned int sg_len = data->sg_len;
+		struct scatterlist *sg_ptr = data->sg;
+
+		data->bytes_xfered = 0;
+
+#ifdef USE_DMA
+		if (suitable_for_dma(sg_ptr, sg_len)) {
+			int i, count = dma_map_sg(&host->dev->dev, sg_ptr, sg_len, data->flags & MMC_DATA_READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+
+			for (i = 0; i < count; i++) {
+				BCM2708_DMA_CB_T *cb = &host->cb_base[i];
+
+				if (data->flags & MMC_DATA_READ) {
+					cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_SDHOST)|BCM2708_DMA_S_DREQ|BCM2708_DMA_D_WIDTH|BCM2708_DMA_D_INC;
+					cb->src = 0x7e202040;
+					cb->dst = sg_dma_address(&sg_ptr[i]);
+				} else {
+					cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_SDHOST)|BCM2708_DMA_S_WIDTH|BCM2708_DMA_S_INC|BCM2708_DMA_D_DREQ;
+					cb->src = sg_dma_address(&sg_ptr[i]);
+					cb->dst = 0x7e202040;
+				}
+ 
+				cb->length = sg_dma_len(&sg_ptr[i]);
+				cb->stride = 0;
+
+				if (i == count - 1) {
+#ifdef USE_DMA_IRQ
+					cb->info |= BCM2708_DMA_INT_EN;
+#endif
+					cb->next = 0;
+				} else 
+					cb->next = host->cb_handle + (i + 1) * sizeof(BCM2708_DMA_CB_T);
+
+				cb->pad[0] = 0;
+				cb->pad[1] = 0;
+
+				data->bytes_xfered += sg_ptr[i].length;
+			}
+
+			dsb();	// data barrier operation
+
+			writel(host->cb_handle, dma_base + BCM2708_DMA_ADDR);
+			writel(BCM2708_DMA_ACTIVE, dma_base + BCM2708_DMA_CS);
+
+#ifdef USE_DMA_IRQ
+			down(&host->sem);
+#else
+			while ((readl(dma_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE));
+#endif
+			dma_unmap_sg(&host->dev->dev, sg_ptr, sg_len, data->flags & MMC_DATA_READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+		} else
+#endif
+		while (sg_len) {
+			unsigned long flags;
+			char *buffer;
+			u32 *ptr, *lim;
+
+			DBG(host, "sg_len=%d sg_ptr=%p len=%d\n", sg_len, sg_ptr, sg_ptr->length);
+
+			/*
+			 * map the current scatter buffer
+			 */
+
+			buffer = bcm2708_mci_kmap_atomic(sg_ptr, &flags);
+
+			/*
+			 * pump the data
+			 */
+
+			ptr = (u32 *)(buffer);
+			lim = (u32 *)(buffer + sg_ptr->length);
+
+			while (ptr < lim)
+			{
+#ifdef PIO_DEBUG
+				unsigned int wait_count = 1;
+#endif
+				while (!(readl(mmc_base + BCM2708_MCI_STATUS) & BCM2708_MCI_DATAFLAG)) 
+				{
+#ifdef PIO_DEBUG
+					wait_count++;
+					if ( 0 == (wait_count % 20000) ) {
+
+						printk(KERN_ERR"Timeout waiting for data flag\n");
+						dump_sd_regs(mmc_base);
+					}
+#endif
+				}
+
+				if (data->flags & MMC_DATA_READ)
+					*ptr++ = readl(mmc_base + BCM2708_MCI_DATA);
+				else
+				{
+#ifdef PIO_DEBUG
+					uint32_t fifo_bytes, fifo_wait_count = 1;
+
+					fifo_bytes = readl(mmc_base + BCM2708_MCI_EDM);
+					fifo_bytes = (fifo_bytes >> 4)  & 0xf;
+
+					while(fifo_bytes > 3)
+					{
+						fifo_wait_count++;
+						if ( 0 == (fifo_wait_count % 20000) ) {
+							printk(KERN_ERR"waiting for fifo_bytes < 3\n");
+							dump_sd_regs(mmc_base);
+						}
+
+						fifo_bytes = readl(mmc_base + BCM2708_MCI_EDM);
+						fifo_bytes = (fifo_bytes >> 4)  & 0xf;
+					}
+
+					BUG_ON(fifo_bytes > 3);
+#endif
+					writel(*ptr++, mmc_base + BCM2708_MCI_DATA);
+				}
+			}
+
+			DBG(host, "done reading/writing %d bytes from mmc\n", sg_ptr->length);
+
+
+			/*
+			 * unmap the buffer
+			 */
+
+			bcm2708_mci_kunmap_atomic(buffer, &flags);
+
+			/*
+			 * if we were reading, and we have completed this
+			 * page, ensure that the data cache is coherent
+			 */
+
+			if (data->flags & MMC_DATA_READ)
+				flush_dcache_page(sg_page(sg_ptr));
+
+			data->bytes_xfered += sg_ptr->length;
+
+			sg_ptr++;
+			sg_len--; 
+		}
+
+//		if (host->is_acmd && cmd->opcode == SD_APP_SEND_SCR)
+//			discard_words(mmc_base, 126);
+//		if (host->is_acmd && cmd->opcode == SD_APP_SEND_NUM_WR_BLKS) 
+//			discard_words(mmc_base, 127);
+//		if (!host->is_acmd && cmd->opcode == SD_SWITCH)
+//			discard_words(mmc_base, 112);
+
+		if (data->stop) {
+
+			DBG(host, "sending stop command %p\n", data->stop);
+			bcm2708_mci_start_command(host, data->stop, 0);
+
+			while ((readl(mmc_base + BCM2708_MCI_STATUS) &
+					 BCM2708_MCI_DATAFLAG))
+			{
+				DBG(host, "error data flag still set read=%d bytes\n", sg_ptr->length);
+				printk(KERN_ERR"SDDATA:0x%x\n", readl(mmc_base + BCM2708_MCI_DATA));
+				dump_sd_regs(mmc_base);
+			}
+		}
+	}
+	/*
+	 * remember if we're an application command
+	 */
+	host->is_acmd = cmd->opcode == MMC_APP_CMD;
+}
+
+static void bcm2708_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct bcm2708_mci_host *host = mmc_priv(mmc);
+
+	if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
+		printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
+			mmc_hostname(mmc), mrq->data->blksz);
+		mrq->cmd->error = -EINVAL;
+		mmc_request_done(mmc, mrq);
+		return;
+	}
+
+	bcm2708_mci_start_command(host, mrq->cmd, mrq->data);
+
+	mmc_request_done(host->mmc, mrq);
+}
+
+static void bcm2708_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+
+	struct bcm2708_mci_host *host = mmc_priv(mmc);
+	void *mmc_base = host->mmc_base;
+
+
+	printk(KERN_DEBUG"%s: Want to set clock: %d width: %d\n", mmc_hostname(mmc),
+			ios->clock, ios->bus_width);
+
+	if (ios->clock == 25000000 || ios->clock == 26000000) {
+		printk(KERN_DEBUG"%s setting clock div to 10 (8+2)\n", mmc_hostname(mmc));
+		writel(0x8, mmc_base + BCM2708_MCI_CLKDIV);
+	} else if (ios->clock == 50000000 || ios->clock == 52000000) {
+		printk(KERN_DEBUG"%s setting clock div to 5 (3+2)\n", mmc_hostname(mmc));
+		writel(0x3, mmc_base + BCM2708_MCI_CLKDIV);
+	} else {
+		// On init or unknown clock, we set the clock really low
+		printk(KERN_DEBUG"%s Setting clock div to 0x4e0\n", mmc_hostname(mmc));
+		writel(0x4e0, mmc_base + BCM2708_MCI_CLKDIV);
+	}
+
+	if (ios->bus_width) {
+		uint32_t hcfg;
+		hcfg = readl(mmc_base + BCM2708_MCI_HOSTCONFIG);
+		printk(KERN_DEBUG"%s setting bus width to %d\n", mmc_hostname(mmc), ios->bus_width);
+
+		hcfg &= BCM2708_MCI_HOSTCONFIG_WIDEEXT_CLR;
+		hcfg |= (ios->bus_width == MMC_BUS_WIDTH_4) ? BCM2708_MCI_HOSTCONFIG_WIDEEXT_4BIT : 0;
+
+		writel(hcfg, mmc_base + BCM2708_MCI_HOSTCONFIG);
+	}
+}
+
+static int bcm2708_mci_get_cd(struct mmc_host *mmc)
+{
+	int present = -ENOSYS;
+
+	struct bcm2708_mci_host *host = mmc_priv(mmc);
+	void *gpio_base = host->gpio_base;
+
+	present = readl( (gpio_base + GP_LEV0) );
+	
+	if ((present & (1<<29))==(1<<29))
+		present = 0;
+	else
+		present = 1;
+
+	printk(KERN_DEBUG"***sdcard present***=%d\n", present);
+
+	// FIXME - For now force SD card present for 2835DK 
+	present = 1;
+	return present;
+}
+
+/*
+ * Handle completion of command and data transfers.
+ */
+
+//static irqreturn_t bcm2708_mci_command_irq(int irq, void *dev_id)
+//{
+//	struct bcm2708_mci_host *host = dev_id;
+//
+//	writel(BCM2708_DMA_INT, host->dma_base + BCM2708_DMA_CS);
+//
+//	printk(KERN_ERR "irq\n");
+//
+//	return IRQ_RETVAL(0);
+//}
+
+static irqreturn_t bcm2708_mci_sddet_irq(int irq, void *dev_id)
+{
+	struct bcm2708_mci_host *host = dev_id;
+	irqreturn_t handled = IRQ_NONE;
+	int present;
+
+	present = bcm2708_mci_get_cd(host->mmc);
+
+	if (present!=host->present)
+	{
+		host->present = present;
+		printk(KERN_DEBUG "SDDET IRQ: sdcard present: %d\n",present);
+		bcm2708_mci_reset(host);
+		mmc_detect_change(host->mmc, msecs_to_jiffies(500));
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+#ifdef USE_DMA_IRQ
+static irqreturn_t bcm2708_mci_data_irq(int irq, void *dev_id)
+{
+	struct bcm2708_mci_host *host = dev_id;
+        irqreturn_t handled = IRQ_NONE;
+
+	if (0 != (BCM2708_DMA_INT & readl(host->dma_base + BCM2708_DMA_CS))) {
+		writel(BCM2708_DMA_INT, host->dma_base + BCM2708_DMA_CS);
+		dsb();
+		handled = IRQ_HANDLED;
+		up(&host->sem);
+	} else {
+		printk(KERN_ERR"bcm2708_mci irq check failed !!\n");
+	}
+
+	return IRQ_RETVAL(handled);
+}
+#endif
+
+static const struct mmc_host_ops bcm2708_mci_ops = {
+	.request	= bcm2708_mci_request,
+	.set_ios	= bcm2708_mci_set_ios,
+	.get_cd		= bcm2708_mci_get_cd,
+};
+
+static int bcm2708_mci_reset(struct bcm2708_mci_host *host)
+{
+
+	void *mmc_base = host->mmc_base;
+
+	// pin muxing/gpios is done by vcloader
+
+	printk(KERN_DEBUG"%s:Resetting BCM2708 MCI Controller.\n", __func__ );
+
+	writel(0, mmc_base + BCM2708_MCI_COMMAND);
+	writel(0, mmc_base + BCM2708_MCI_ARGUMENT);
+	writel(0x00F00000, mmc_base + BCM2708_MCI_TIMEOUT);
+	writel(0, mmc_base + BCM2708_MCI_CLKDIV);
+	writel(0, mmc_base + BCM2708_MCI_STATUS);
+	writel(0, mmc_base + BCM2708_MCI_VDD);
+	writel(0, mmc_base + BCM2708_MCI_HOSTCONFIG);
+	writel(0, mmc_base + BCM2708_MCI_HBCT);
+	writel(0, mmc_base + BCM2708_MCI_HBLC);
+
+	writel( BCM2708_MCI_HOSTCONFIG_SLOW_CARD | BCM2708_MCI_HOSTCONFIG_BUSY_IRPT_EN |
+			BCM2708_MCI_HOSTCONFIG_BLOCK_IRPT_EN | BCM2708_MCI_HOSTCONFIG_WIDE_INT_BUS,
+			mmc_base + BCM2708_MCI_HOSTCONFIG);
+
+	// On A0 silicon it has been observed that the following must hold
+	// WRITE_THRESHOLD<=5 and READ_THRESHOLD<=WRITE_THRESHOLD+1
+	// with the chip running at 150MHz (with the interface running @ 150/22 = 6.8 MHz)
+	// the second requirement suggests that the verilog does not properly separate the read / write FIFOs
+	// On V3XDS Read=2 & Write=6
+
+#define READ_THRESHOLD  3
+#define WRITE_THRESHOLD 3
+#if 1 // !!! This is still required, without it we get CRC16 errors in data.
+	{
+		uint32_t temp;
+		temp = readl(mmc_base + BCM2708_MCI_EDM);
+		temp &= ~((0x1F<<14) | (0x1F<<9));
+		temp  |= (WRITE_THRESHOLD << 9) | (READ_THRESHOLD << 14);
+		writel(temp, mmc_base + BCM2708_MCI_EDM);
+	}
+#endif
+
+	// Power on delay
+	mdelay(10);
+	writel(BCM2708_MCI_VDD_ENABLE, mmc_base + BCM2708_MCI_VDD);
+	mdelay(10);
+
+	return 0;
+}
+
+
+static int __devinit bcm2708_mci_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct bcm2708_mci_host *host;
+	struct resource *mmc_res;
+	struct resource *dma_res;
+	struct resource *gpio_res;
+	struct resource *dat_res;
+	struct resource *sddet_res;
+	int ret;
+
+	mmc = mmc_alloc_host(sizeof(struct bcm2708_mci_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
+		goto fail0;
+	}
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+
+	host->dev = pdev;
+
+	sema_init(&host->sem, 0);
+
+#ifdef USE_DMA
+	host->cb_base = dma_alloc_writecombine(&pdev->dev, SZ_4K, &host->cb_handle, GFP_KERNEL);
+	if (!host->cb_base) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "couldn't allocate dma base\n");
+		goto fail1;
+	}
+#endif
+
+	mmc_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mmc_res) {
+		ret = -ENXIO;
+		dev_dbg(&pdev->dev, "couldn't allocate mmc memory resource 0\n");
+		goto fail2;
+	}
+
+	if (!request_mem_region(mmc_res->start, mmc_res->end - mmc_res->start + 1, DRIVER_NAME)) {
+		ret = -EBUSY;
+		goto fail2;
+	}
+
+	dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!dma_res) {
+		ret = -ENXIO;
+		dev_dbg(&pdev->dev, "couldn't allocate dma memory resource 1\n");
+		goto fail3;
+	}
+
+	/*
+	 * Map I/O regions
+	 */
+
+	host->mmc_base = ioremap(mmc_res->start, resource_size(mmc_res));
+	if (!host->mmc_base) {
+		ret = -ENOMEM;
+		goto fail3;
+	}
+
+	gpio_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	if (!gpio_res) {
+		ret = -ENXIO;
+		dev_dbg(&pdev->dev, "couldn't allocate gpio resource\n");
+		goto fail4;
+	}
+
+	/*
+	 * Map I/O regions
+	 */
+
+	host->gpio_base = ioremap(gpio_res->start, resource_size(gpio_res));
+	if (!host->gpio_base) {
+		ret = -ENOMEM;
+		goto fail4;
+	}
+
+#ifdef USE_DMA
+	host->dma_base = __io_address(dma_res->start);
+
+	if (!host->dma_base) {
+		ret = -ENOMEM;
+		goto fail5;
+	}
+
+	// USE DMA5 channel
+	host->dma_base = (void __iomem *)((char *) host->dma_base + (SDHOST_DMA_CHANNEL * 0x100));
+
+	dev_dbg(&pdev->dev, "%s: using dma channel %d for sdhost\n", __func__, SDHOST_DMA_CHANNEL);
+
+	/*
+	 * Grab interrupts.
+	 */
+#ifdef USE_DMA_IRQ
+	dat_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!dat_res) {
+		ret = -ENXIO;
+		dev_dbg(&pdev->dev, "couldn't allocate irq for dma\n");
+		goto fail5;
+	}
+
+	ret = request_irq(dat_res->start, bcm2708_mci_data_irq, 0, DRIVER_NAME " (dat)", host);
+	if (ret) {
+		goto fail5;
+	}
+	dev_dbg(&pdev->dev, "%s: using dma interrupt number %d for sdhost\n", __func__, dat_res->start);
+
+#endif
+#endif
+
+	host->present = bcm2708_mci_get_cd(host->mmc);
+
+	sddet_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+	if (!sddet_res) {
+		ret = -ENXIO;
+		dev_dbg(&pdev->dev, "couldn't allocate irq for sd detect\n");
+		goto fail6;
+	}
+
+	ret = request_irq(sddet_res->start, bcm2708_mci_sddet_irq, 0, DRIVER_NAME " (cmd)", host);
+	if (ret) {
+		goto fail6;
+	}
+
+	host->is_acmd = 0;
+
+	mmc->ops = &bcm2708_mci_ops;
+	mmc->f_min = 200000;
+	mmc->f_max = 52000000;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	/*
+	 * We can do SGIO
+	 */
+	mmc->max_segs = NR_SG;
+
+	/*
+	 * Since we only have a 16-bit data length register, we must
+	 * ensure that we don't exceed 2^16-1 bytes in a single request.
+	 */
+	mmc->max_req_size = 65535;
+
+	/*
+	 * Set the maximum segment size.  Since we aren't doing DMA
+	 * (yet) we are only limited by the data length register.
+	 */
+	mmc->max_seg_size = mmc->max_req_size;
+
+	/*
+	 * Block size can be up to 2048 bytes, but must be a power of two.
+	 */
+	mmc->max_blk_size = 2048;
+
+	/*
+	 * No limit on the number of blocks transferred.
+	 */
+	mmc->max_blk_count = mmc->max_req_size;
+
+	/*
+	 * We support 4-bit data (at least on the DB)
+	 */
+
+	mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED) ;
+
+	bcm2708_mci_reset(host);
+
+	mmc_add_host(mmc);
+
+	printk(KERN_INFO "%s: BCM2708 SD host at 0x%08llx 0x%08llx\n",
+		mmc_hostname(mmc),
+		(unsigned long long)mmc_res->start, (unsigned long long)dma_res->start);
+
+	return 0;
+
+fail6:
+#ifdef USE_DMA_IRQ
+	free_irq(dat_res->start, host);
+#endif
+fail5:
+	iounmap(host->gpio_base);
+fail4:
+	iounmap(host->mmc_base);
+fail3:
+	release_mem_region(mmc_res->start, mmc_res->end - mmc_res->start + 1);
+fail2:
+	dma_free_writecombine(&pdev->dev, SZ_4K, host->cb_base, host->cb_handle);
+fail1:
+	mmc_free_host(mmc);
+fail0:
+	dev_err(&pdev->dev, "probe failed, err %d\n", ret);
+	return ret;
+}
+
+static int __devexit bcm2708_mci_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+	if (mmc) {
+		struct bcm2708_mci_host *host = mmc_priv(mmc);
+		struct resource *res;
+		struct resource *res2;
+
+		mmc_remove_host(mmc);
+#ifdef USE_DMA
+#ifdef USE_DMA_IRQ
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+		free_irq(res->start, host);
+#endif
+#endif
+
+		res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+		free_irq(res2->start, host);
+
+		iounmap(host->mmc_base);
+		iounmap(host->gpio_base);
+		iounmap(host->dma_base);
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		release_mem_region(res->start, resource_size(res));
+#ifdef USE_DMA
+		dma_free_writecombine(&pdev->dev, SZ_4K, host->cb_base, host->cb_handle);
+#endif
+
+		mmc_free_host(mmc);
+		platform_set_drvdata(pdev, NULL);
+
+		return 0;
+	} else
+		return -1;
+}
+
+#ifdef CONFIG_PM
+static int bcm2708_mci_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc) {
+		ret = mmc_suspend_host(mmc);
+	}
+
+	return ret;
+}
+
+static int bcm2708_mci_resume(struct platform_device *dev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc) {
+		ret = mmc_resume_host(mmc);
+	}
+
+	return ret;
+}
+#else
+#define bcm2708_mci_suspend	NULL
+#define bcm2708_mci_resume	NULL
+#endif
+
+static struct platform_driver bcm2708_mci_driver = {
+	.probe		= bcm2708_mci_probe,
+	.remove		= bcm2708_mci_remove,
+	.suspend	= bcm2708_mci_suspend,
+	.resume		= bcm2708_mci_resume,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init bcm2708_mci_init(void)
+{
+	return platform_driver_register(&bcm2708_mci_driver);
+}
+
+static void __exit bcm2708_mci_exit(void)
+{
+	platform_driver_unregister(&bcm2708_mci_driver);
+}
+
+module_init(bcm2708_mci_init);
+module_exit(bcm2708_mci_exit);
+
+MODULE_DESCRIPTION("BCM2708 Multimedia Card Interface driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bcm2708_mci");
--- /dev/null
+++ b/drivers/mmc/host/bcm2708_mci.h
@@ -0,0 +1,101 @@
+/*
+ *  linux/drivers/mmc/host/bcm2708_mci.c - Broadcom BCM2708 MCI driver
+ *
+ *  Copyright (C) 2010 Broadcom, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+struct clk;
+
+#define BCM2708_MCI_COMMAND	0x00
+
+#define BCM2708_MCI_READ     	(1 << 6)
+#define BCM2708_MCI_WRITE    	(1 << 7)
+#define BCM2708_MCI_LONGRESP 	(1 << 9)
+#define BCM2708_MCI_NORESP   	(1 << 10)
+#define BCM2708_MCI_BUSY     	(1 << 11)
+#define BCM2708_MCI_FAIL_FLAG	(1 << 14)
+#define BCM2708_MCI_ENABLE   	(1 << 15)
+
+#define BCM2708_MCI_ARGUMENT	0x04
+
+#define BCM2708_MCI_TIMEOUT	0x08
+#define BCM2708_MCI_CLKDIV	0x0c
+
+
+#define BCM2708_MCI_RESPONSE0	0x10
+#define BCM2708_MCI_RESPONSE1	0x14
+#define BCM2708_MCI_RESPONSE2	0x18
+#define BCM2708_MCI_RESPONSE3	0x1c
+
+#define BCM2708_MCI_STATUS	0x20
+
+#define BCM2708_MCI_VDD	0x30
+#define BCM2708_MCI_VDD_ENABLE	(1 << 0)
+
+#define BCM2708_MCI_EDM	0x34
+
+#define BCM2708_MCI_HOSTCONFIG	0x38
+
+#define BCM2708_MCI_HOSTCONFIG_WIDE_INT_BUS 0x2
+#define BCM2708_MCI_HOSTCONFIG_WIDEEXT_4BIT 0x4
+#define BCM2708_MCI_HOSTCONFIG_SLOW_CARD 0x8
+#define BCM2708_MCI_HOSTCONFIG_BLOCK_IRPT_EN (1<<8)
+#define BCM2708_MCI_HOSTCONFIG_BUSY_IRPT_EN (1<<10)
+#define BCM2708_MCI_HOSTCONFIG_WIDEEXT_CLR 0xFFFFFFFB
+
+
+#define BCM2708_MCI_DATAFLAG	(1 << 0)
+#define BCM2708_MCI_CMDTIMEOUT	(1 << 6)
+#define BCM2708_MCI_HSTS_BLOCK	(1 << 9)	/**< block flag in status reg */
+#define BCM2708_MCI_HSTS_BUSY	(1 << 10)	/**< Busy flag in status reg */
+
+#define BCM2708_MCI_HBCT	0x3c
+#define BCM2708_MCI_DATA	0x40
+#define BCM2708_MCI_HBLC	0x50
+
+#define NR_SG		16
+
+typedef struct bulk_data_struct
+{
+   unsigned long info;
+   unsigned long src;
+   unsigned long dst;
+   unsigned long length;
+   unsigned long stride;
+   unsigned long next;
+   unsigned long pad[2];
+} BCM2708_DMA_CB_T;
+
+struct bcm2708_mci_host {
+	struct platform_device	*dev;
+
+	void __iomem		*mmc_base;
+	void __iomem		*dma_base;
+	void __iomem		*gpio_base;
+
+	BCM2708_DMA_CB_T	*cb_base;
+	dma_addr_t		cb_handle;
+
+	struct mmc_host		*mmc;
+
+	struct semaphore 	sem;
+
+	int is_acmd;
+	int present;
+};
+
+static inline char *bcm2708_mci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
+{
+//	local_irq_save(*flags);
+	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+}
+
+static inline void bcm2708_mci_kunmap_atomic(void *buffer, unsigned long *flags)
+{
+	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+//	local_irq_restore(*flags);
+}
--- /dev/null
+++ b/drivers/mmc/host/sdhci-bcm2708.c
@@ -0,0 +1,1461 @@
+/*
+ * sdhci-bcm2708.c Support for SDHCI device on BCM2708
+ * Copyright (c) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform device - Arasan SD controller in BCM2708
+ *
+ * Inspired by sdhci-pci.c, by Pierre Ossman
+ */
+
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/mmc/host.h>
+
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <mach/dma.h>
+#include <mach/power.h>
+
+#include "sdhci.h"
+
+/*****************************************************************************\
+ *									     *
+ * Configuration							     *
+ *									     *
+\*****************************************************************************/
+
+#define DRIVER_NAME "bcm2708_sdhci"
+
+/* for the time being insist on DMA mode - PIO seems not to work */
+#ifndef CONFIG_MMC_SDHCI_BCM2708_DMA
+#warning Non-DMA (PIO) version of this driver currently unavailable
+#endif
+#undef CONFIG_MMC_SDHCI_BCM2708_DMA
+#define CONFIG_MMC_SDHCI_BCM2708_DMA y
+
+#define USE_SYNC_AFTER_DMA
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+/* #define CHECK_DMA_USE */
+#endif
+//#define LOG_REGISTERS
+
+#define USE_SCHED_TIME
+
+#define SDHCI_BCM_DMA_CHAN 4   /* this default is normally overriden */
+#define SDHCI_BCM_DMA_WAITS 0  /* delays slowing DMA transfers: 0-31 */
+/* We are worried that SD card DMA use may be blocking the AXI bus for others */
+
+/*! TODO: obtain these from the physical address */
+#define DMA_SDHCI_BASE	 0x7e300000  /* EMMC register block on Videocore */
+#define DMA_SDHCI_BUFFER (DMA_SDHCI_BASE + SDHCI_BUFFER)
+
+#define BCM2708_SDHCI_SLEEP_TIMEOUT 1000   /* msecs */
+
+#define POWER_OFF 0
+#define POWER_LAZY_OFF 1
+#define POWER_ON  2
+
+
+/*****************************************************************************\
+ *									     *
+ * Debug								     *
+ *									     *
+\*****************************************************************************/
+
+
+
+#define DBG(f, x...) \
+	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
+//	printk(KERN_INFO DRIVER_NAME " [%s()]: " f, __func__,## x)//GRAYG
+
+
+/*****************************************************************************\
+ *									     *
+ * High Precision Time							     *
+ *									     *
+\*****************************************************************************/
+
+#ifdef USE_SCHED_TIME
+
+#include <mach/frc.h>
+
+typedef unsigned long hptime_t;
+
+#define FMT_HPT "lu"
+
+static inline hptime_t hptime(void)
+{
+	return frc_clock_ticks32();
+}
+
+#define HPTIME_CLK_NS 1000ul
+
+#else
+
+typedef unsigned long hptime_t;
+
+#define FMT_HPT "lu"
+
+static inline hptime_t hptime(void)
+{
+	return jiffies;
+}
+
+#define HPTIME_CLK_NS (1000000000ul/HZ)
+
+#endif
+
+static inline unsigned long int since_ns(hptime_t t)
+{
+	return (unsigned long)((hptime() - t) * HPTIME_CLK_NS);
+}
+
+#if 0
+static void hptime_test(void)
+{
+	hptime_t now;
+	hptime_t later;
+
+	now = hptime();
+	msleep(10);
+	later = hptime();
+
+	printk(KERN_INFO DRIVER_NAME": 10ms = %"FMT_HPT" clks "
+	       "(from %"FMT_HPT" to %"FMT_HPT") = %luns\n",
+	       later-now, now, later,
+	       (unsigned long)(HPTIME_CLK_NS * (later - now)));
+
+	now = hptime();
+	msleep(1000);
+	later = hptime();
+
+	printk(KERN_INFO DRIVER_NAME": 1s = %"FMT_HPT" clks "
+	       "(from %"FMT_HPT" to %"FMT_HPT") = %luns\n",
+	       later-now, now, later,
+	       (unsigned long)(HPTIME_CLK_NS * (later - now)));
+}
+#endif
+
+/*****************************************************************************\
+ *									     *
+ * SDHCI core callbacks							     *
+ *									     *
+\*****************************************************************************/
+
+
+#ifdef CHECK_DMA_USE
+/*#define CHECK_DMA_REG_USE*/
+#endif
+
+#ifdef CHECK_DMA_REG_USE
+/* we don't expect anything to be using these registers during a
+   DMA (except the IRQ status) - so check */
+static void check_dma_reg_use(struct sdhci_host *host, int reg);
+#else
+#define check_dma_reg_use(host, reg)
+#endif
+
+
+static inline u32 sdhci_bcm2708_raw_readl(struct sdhci_host *host, int reg)
+{
+	return readl(host->ioaddr + reg);
+}
+
+u32 sdhci_bcm2708_readl(struct sdhci_host *host, int reg)
+{
+	u32 l = sdhci_bcm2708_raw_readl(host, reg);
+
+#ifdef LOG_REGISTERS
+	printk(KERN_ERR "%s: readl from 0x%02x, value 0x%08x\n",
+	       mmc_hostname(host->mmc), reg, l);
+#endif
+	check_dma_reg_use(host, reg);
+
+	return l;
+}
+
+u16 sdhci_bcm2708_readw(struct sdhci_host *host, int reg)
+{
+	u32 l = sdhci_bcm2708_raw_readl(host, reg & ~3);
+	u32 w = l >> (reg << 3 & 0x18) & 0xffff;
+
+#ifdef LOG_REGISTERS
+	printk(KERN_ERR "%s: readw from 0x%02x, value 0x%04x\n",
+	       mmc_hostname(host->mmc), reg, w);
+#endif
+	check_dma_reg_use(host, reg);
+
+	return (u16)w;
+}
+
+u8 sdhci_bcm2708_readb(struct sdhci_host *host, int reg)
+{
+	u32 l = sdhci_bcm2708_raw_readl(host, reg & ~3);
+	u32 b = l >> (reg << 3 & 0x18) & 0xff;
+
+#ifdef LOG_REGISTERS
+	printk(KERN_ERR "%s: readb from 0x%02x, value 0x%02x\n",
+	       mmc_hostname(host->mmc), reg, b);
+#endif
+	check_dma_reg_use(host, reg);
+
+	return (u8)b;
+}
+
+
+static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	/* The Arasan has a bugette whereby it may lose the content of
+	 * successive writes to registers that are within two SD-card clock
+	 * cycles of each other (a clock domain crossing problem).
+	 * It seems, however, that the data register does not have this problem.
+	 * (Which is just as well - otherwise we'd have to nobble the DMA engine
+	 * too)
+	 */
+#if 1
+	if (reg != SDHCI_BUFFER && host->clock != 0) {
+		/* host->clock is the clock freq in Hz */
+		static hptime_t last_write_hpt;
+		hptime_t now = hptime();
+		unsigned int ns_2clk = 2000000000/host->clock;
+
+		if (now == last_write_hpt || now == last_write_hpt+1) {
+			 /* we can't guarantee any significant time has
+			  * passed - we'll have to wait anyway ! */
+			udelay((ns_2clk+1000-1)/1000);
+		} else
+		{
+			/* we must have waited at least this many ns: */
+			unsigned int ns_wait = HPTIME_CLK_NS *
+					       (last_write_hpt - now - 1);
+			if (ns_wait < ns_2clk)
+				udelay((ns_2clk-ns_wait+500)/1000);
+		}
+		last_write_hpt = now;
+	}
+	writel(val, host->ioaddr + reg);
+#else
+	void __iomem * regaddr = host->ioaddr + reg;
+
+	writel(val, regaddr);
+
+	if (reg != SDHCI_BUFFER && reg != SDHCI_INT_STATUS && host->clock != 0)
+	{
+		int timeout = 100000;
+		while (val != readl(regaddr) && --timeout > 0)
+		   continue;
+
+		if (timeout <= 0)
+			printk(KERN_ERR "%s: writing 0x%X to reg 0x%X "
+			       "always gives 0x%X\n",
+			       mmc_hostname(host->mmc),
+			       val, reg, readl(regaddr));
+		BUG_ON(timeout <= 0);
+	}
+#endif
+}
+
+
+void sdhci_bcm2708_writel(struct sdhci_host *host, u32 val, int reg)
+{
+#ifdef LOG_REGISTERS
+	printk(KERN_ERR "%s: writel to 0x%02x, value 0x%08x\n",
+	       mmc_hostname(host->mmc), reg, val);
+#endif
+	check_dma_reg_use(host, reg);
+
+	sdhci_bcm2708_raw_writel(host, val, reg);
+}
+
+void sdhci_bcm2708_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	static u32 shadow = 0;
+
+	u32 p = reg == SDHCI_COMMAND ? shadow :
+		       sdhci_bcm2708_raw_readl(host, reg & ~3);
+	u32 s = reg << 3 & 0x18;
+	u32 l = val << s;
+	u32 m = 0xffff << s;
+
+#ifdef LOG_REGISTERS
+	printk(KERN_ERR "%s: writew to 0x%02x, value 0x%04x\n",
+	       mmc_hostname(host->mmc), reg, val);
+#endif
+
+	if (reg == SDHCI_TRANSFER_MODE)
+		shadow = (p & ~m) | l;
+	else {
+		check_dma_reg_use(host, reg);
+		sdhci_bcm2708_raw_writel(host, (p & ~m) | l, reg & ~3);
+	}
+}
+
+void sdhci_bcm2708_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	u32 p = sdhci_bcm2708_raw_readl(host, reg & ~3);
+	u32 s = reg << 3 & 0x18;
+	u32 l = val << s;
+	u32 m = 0xff << s;
+
+#ifdef LOG_REGISTERS
+	printk(KERN_ERR "%s: writeb to 0x%02x, value 0x%02x\n",
+	       mmc_hostname(host->mmc), reg, val);
+#endif
+
+       check_dma_reg_use(host, reg);
+       sdhci_bcm2708_raw_writel(host, (p & ~m) | l, reg & ~3);
+}
+
+static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host)
+{
+	return 100000000;	// this value is in Hz (100MHz/4)
+}
+
+static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host)
+{
+	return 100000;		// this value is in kHz (100MHz/4)
+}
+
+/*****************************************************************************\
+ *									     *
+ * DMA Operation							     *
+ *									     *
+\*****************************************************************************/
+
+struct sdhci_bcm2708_priv {
+	int			dma_chan;
+	int			dma_irq;
+	void __iomem	       *dma_chan_base;
+	struct bcm2708_dma_cb  *cb_base;   /* DMA control blocks */
+	dma_addr_t		cb_handle;
+	/* tracking scatter gather progress */
+	unsigned		sg_ix;	   /* scatter gather list index */
+	unsigned		sg_done;   /* bytes in current sg_ix done */
+	/* power management */
+	BCM_POWER_HANDLE_T	power_handle;
+	unsigned char		power_state; /* enable/disable power state */
+	unsigned char		power_mode;  /* last set power mode */
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+	unsigned char		dma_wanted;  /* DMA transfer requested */
+	unsigned char		dma_waits;   /* wait states in DMAs */
+#ifdef CHECK_DMA_USE
+	unsigned char		dmas_pending; /* no of unfinished DMAs */
+	hptime_t		when_started;
+	hptime_t		when_reset;
+	hptime_t		when_stopped;
+#endif
+#endif
+	/* signalling the end of a transfer */
+	void		      (*complete)(struct sdhci_host *);
+};
+
+#define SDHCI_HOST_PRIV(host) \
+	(struct sdhci_bcm2708_priv *)((struct sdhci_host *)(host)+1)
+
+
+
+#ifdef CHECK_DMA_REG_USE
+static void check_dma_reg_use(struct sdhci_host *host, int reg)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	if (host_priv->dma_wanted && reg != SDHCI_INT_STATUS) {
+		printk(KERN_INFO"%s: accessing register 0x%x during DMA\n",
+		       mmc_hostname(host->mmc), reg);
+	}
+}
+#endif
+
+
+
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+
+static void sdhci_clear_set_irqgen(struct sdhci_host *host, u32 clear, u32 set)
+{
+	u32 ier;
+
+	ier = sdhci_bcm2708_raw_readl(host, SDHCI_SIGNAL_ENABLE);
+	ier &= ~clear;
+	ier |= set;
+	/* change which requests generate IRQs - makes no difference to
+	   the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */
+	sdhci_bcm2708_raw_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_signal_irqs(struct sdhci_host *host, u32 irqs)
+{
+	sdhci_clear_set_irqgen(host, 0, irqs);
+}
+
+static void sdhci_unsignal_irqs(struct sdhci_host *host, u32 irqs)
+{
+	sdhci_clear_set_irqgen(host, irqs, 0);
+}
+
+
+
+static void schci_bcm2708_cb_read(struct sdhci_bcm2708_priv *host,
+				  int ix,
+				  dma_addr_t dma_addr, unsigned len,
+				  int /*bool*/ is_last)
+{
+	struct bcm2708_dma_cb *cb = &host->cb_base[ix];
+        unsigned char dmawaits = host->dma_waits;
+
+	cb->info   = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) |
+		     BCM2708_DMA_WAITS(dmawaits) |
+		     BCM2708_DMA_S_DREQ	 |
+		     BCM2708_DMA_D_WIDTH |
+		     BCM2708_DMA_D_INC;
+	cb->src	   = DMA_SDHCI_BUFFER;	/* DATA register DMA address */
+	cb->dst	   = dma_addr;
+	cb->length = len;
+	cb->stride = 0;
+
+	if (is_last) {
+		cb->info |= BCM2708_DMA_INT_EN;
+		cb->next = 0;
+	} else
+		cb->next = host->cb_handle +
+			   (ix+1)*sizeof(struct bcm2708_dma_cb);
+
+	cb->pad[0] = 0;
+	cb->pad[1] = 0;
+}
+
+static void schci_bcm2708_cb_write(struct sdhci_bcm2708_priv *host,
+				   int ix,
+				   dma_addr_t dma_addr, unsigned len,
+				   int /*bool*/ is_last)
+{
+	struct bcm2708_dma_cb *cb = &host->cb_base[ix];
+        unsigned char dmawaits = host->dma_waits;
+
+	/* We can make arbitrarily large writes as long as we specify DREQ to
+	   pace the delivery of bytes to the Arasan hardware */
+	cb->info   = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) |
+		     BCM2708_DMA_WAITS(dmawaits) |
+		     BCM2708_DMA_D_DREQ	 |
+		     BCM2708_DMA_S_WIDTH |
+		     BCM2708_DMA_S_INC;
+	cb->src	   = dma_addr;
+	cb->dst	   = DMA_SDHCI_BUFFER;	/* DATA register DMA address */
+	cb->length = len;
+	cb->stride = 0;
+
+	if (is_last) {
+		cb->info |= BCM2708_DMA_INT_EN;
+		cb->next = 0;
+	} else
+		cb->next = host->cb_handle +
+			   (ix+1)*sizeof(struct bcm2708_dma_cb);
+
+	cb->pad[0] = 0;
+	cb->pad[1] = 0;
+}
+
+
+static void schci_bcm2708_dma_go(struct sdhci_host *host)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	void __iomem *dma_chan_base = host_priv->dma_chan_base;
+
+	BUG_ON(host_priv->dma_wanted);
+#ifdef CHECK_DMA_USE
+	if (host_priv->dma_wanted)
+		printk(KERN_ERR "%s: DMA already in progress - "
+		       "now %"FMT_HPT", last started %lu "
+		       "reset %lu stopped %lu\n",
+		       mmc_hostname(host->mmc),
+		       hptime(), since_ns(host_priv->when_started),
+		       since_ns(host_priv->when_reset),
+		       since_ns(host_priv->when_stopped));
+	else if (host_priv->dmas_pending > 0)
+		printk(KERN_INFO "%s: note - new DMA when %d reset DMAs "
+		       "already in progress - "
+		       "now %"FMT_HPT", started %lu reset %lu stopped %lu\n",
+		       mmc_hostname(host->mmc),
+		       host_priv->dmas_pending,
+		       hptime(), since_ns(host_priv->when_started),
+		       since_ns(host_priv->when_reset),
+		       since_ns(host_priv->when_stopped));
+	host_priv->dmas_pending += 1;
+	host_priv->when_started = hptime();
+#endif
+	host_priv->dma_wanted = 1;
+	DBG("PDMA go - base %p handle %08X\n", dma_chan_base,
+	    host_priv->cb_handle);
+	bcm_dma_start(dma_chan_base, host_priv->cb_handle);
+}
+
+
+static void
+sdhci_platdma_read(struct sdhci_host *host, dma_addr_t dma_addr, size_t len)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+
+	DBG("PDMA to read %d bytes\n", len);
+	host_priv->sg_done += len;
+	schci_bcm2708_cb_read(host_priv, 0, dma_addr, len, 1/*TRUE*/);
+	schci_bcm2708_dma_go(host);
+}
+
+
+static void
+sdhci_platdma_write(struct sdhci_host *host, dma_addr_t dma_addr, size_t len)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+
+	DBG("PDMA to write %d bytes\n", len);
+	//BUG_ON(0 != (len & 0x1ff));
+
+	host_priv->sg_done += len;
+	schci_bcm2708_cb_write(host_priv, 0, dma_addr, len, 1/*TRUE*/);
+	schci_bcm2708_dma_go(host);
+}
+
+/*! space is avaiable to receive into or data is available to write
+  Platform DMA exported function
+*/
+void
+sdhci_bcm2708_platdma_avail(struct sdhci_host *host, unsigned int *ref_intmask,
+			    void(*completion_callback)(struct sdhci_host *host))
+{
+	struct mmc_data *data = host->data;
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	int sg_ix;
+	size_t bytes;
+	dma_addr_t addr;
+
+	BUG_ON(NULL == data);
+	BUG_ON(0 == data->blksz);
+
+	host_priv->complete = completion_callback;
+
+	sg_ix = host_priv->sg_ix;
+	BUG_ON(sg_ix >= data->sg_len);
+
+	/* we can DMA blocks larger than blksz - it may hang the DMA
+	   channel but we are its only user */
+	bytes = sg_dma_len(&data->sg[sg_ix]) - host_priv->sg_done;
+	addr = sg_dma_address(&data->sg[sg_ix]) + host_priv->sg_done;
+
+	if (bytes > 0) {
+		/* We're going to poll for read/write available state until
+		   we finish this DMA
+		*/
+
+		if (data->flags & MMC_DATA_READ) {
+			if (*ref_intmask & SDHCI_INT_DATA_AVAIL)  {
+				sdhci_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL |
+						    SDHCI_INT_SPACE_AVAIL);
+				sdhci_platdma_read(host, addr, bytes);
+			}
+		} else {
+			if (*ref_intmask & SDHCI_INT_SPACE_AVAIL) {
+				sdhci_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL |
+						    SDHCI_INT_SPACE_AVAIL);
+				sdhci_platdma_write(host, addr, bytes);
+			}
+		}
+	}
+	/* else:
+	   we have run out of bytes that need transferring (e.g. we may be in
+	   the middle of the last DMA transfer), or
+	   it is also possible that we've been called when another IRQ is
+	   signalled, even though we've turned off signalling of our own IRQ */
+
+	*ref_intmask &= ~SDHCI_INT_DATA_END;
+	/* don't let the main sdhci driver act on this .. we'll deal with it
+	   when we respond to the DMA - if one is currently in progress */
+}
+
+/* is it possible to DMA the given mmc_data structure?
+   Platform DMA exported function
+*/
+int /*bool*/
+sdhci_bcm2708_platdma_dmaable(struct sdhci_host *host, struct mmc_data *data)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	int ok = bcm_sg_suitable_for_dma(data->sg, data->sg_len);
+
+	if (!ok)
+		DBG("Reverting to PIO - bad cache alignment\n");
+
+	else {
+		host_priv->sg_ix = 0;	 /* first SG index */
+		host_priv->sg_done = 0;	 /* no bytes done */
+	}
+
+	return ok;
+}
+
+#include <mach/arm_control.h> //GRAYG
+/*! the current SD transacton has been abandonned
+  We need to tidy up if we were in the middle of a DMA
+  Platform DMA exported function
+*/
+void
+sdhci_bcm2708_platdma_reset(struct sdhci_host *host, struct mmc_data *data)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	unsigned long flags;
+
+	BUG_ON(NULL == host);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host_priv->dma_wanted) {
+		if (NULL == data) {
+			printk(KERN_ERR "%s: ongoing DMA reset - no data!\n",
+			       mmc_hostname(host->mmc));
+			BUG_ON(NULL == data);
+		} else {
+			struct scatterlist *sg;
+			int sg_len;
+			int sg_todo;
+			int rc;
+			unsigned long cs;
+
+			sg = data->sg;
+			sg_len = data->sg_len;
+			sg_todo = sg_dma_len(&sg[host_priv->sg_ix]);
+
+			cs = readl(host_priv->dma_chan_base + BCM2708_DMA_CS);
+
+			if (!(BCM2708_DMA_ACTIVE & cs))
+				printk(KERN_INFO "%s: missed completion of "
+				       "cmd %d DMA (%d/%d [%d]/[%d]) - "
+				       "ignoring it\n",
+				       mmc_hostname(host->mmc),
+				       host->last_cmdop,
+				       host_priv->sg_done, sg_todo,
+				       host_priv->sg_ix+1, sg_len);
+			else
+				printk(KERN_INFO "%s: resetting ongoing cmd %d"
+				       "DMA before %d/%d [%d]/[%d] complete\n",
+				       mmc_hostname(host->mmc),
+				       host->last_cmdop,
+				       host_priv->sg_done, sg_todo,
+				       host_priv->sg_ix+1, sg_len);
+#ifdef CHECK_DMA_USE
+			printk(KERN_INFO "%s: now %"FMT_HPT" started %lu "
+			       "last reset %lu last stopped %lu\n",
+			       mmc_hostname(host->mmc),
+			       hptime(), since_ns(host_priv->when_started),
+			       since_ns(host_priv->when_reset),
+			       since_ns(host_priv->when_stopped));
+			{	unsigned long info, debug;
+				void __iomem *base;
+				unsigned long pend0, pend1, pend2;
+				   
+				base = host_priv->dma_chan_base;
+				cs = readl(base + BCM2708_DMA_CS);
+				info = readl(base + BCM2708_DMA_INFO);
+				debug = readl(base + BCM2708_DMA_DEBUG);
+				printk(KERN_INFO "%s: DMA%d CS=%08lX TI=%08lX "
+				       "DEBUG=%08lX\n",
+				       mmc_hostname(host->mmc),
+                                       host_priv->dma_chan,
+				       cs, info, debug);
+				pend0 = readl(__io_address(ARM_IRQ_PEND0));
+				pend1 = readl(__io_address(ARM_IRQ_PEND1));
+				pend2 = readl(__io_address(ARM_IRQ_PEND2));
+				
+				printk(KERN_INFO "%s: PEND0=%08lX "
+				       "PEND1=%08lX PEND2=%08lX\n",
+				       mmc_hostname(host->mmc),
+				       pend0, pend1, pend2);
+				
+				//gintsts = readl(__io_address(GINTSTS));
+				//gintmsk = readl(__io_address(GINTMSK));
+				//printk(KERN_INFO "%s: USB GINTSTS=%08lX"
+				//	 "GINTMSK=%08lX\n",
+				//	 mmc_hostname(host->mmc), gintsts, gintmsk);
+			}
+#endif
+			rc = bcm_dma_abort(host_priv->dma_chan_base);
+			BUG_ON(rc != 0);
+		}
+		host_priv->dma_wanted = 0;
+#ifdef CHECK_DMA_USE
+		host_priv->when_reset = hptime();
+#endif
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+
+static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+					   u32 dma_cs)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	struct mmc_data *data;
+	struct scatterlist *sg;
+	int sg_len;
+	int sg_ix;
+	int sg_todo;
+	unsigned long flags;
+
+	BUG_ON(NULL == host);
+
+	spin_lock_irqsave(&host->lock, flags);
+	data = host->data;
+
+#ifdef CHECK_DMA_USE
+	if (host_priv->dmas_pending <= 0)
+		DBG("on completion no DMA in progress - "
+		    "now %"FMT_HPT" started %lu reset %lu stopped %lu\n",
+		    hptime(), since_ns(host_priv->when_started),
+		    since_ns(host_priv->when_reset),
+		    since_ns(host_priv->when_stopped));
+	else if (host_priv->dmas_pending > 1)
+		DBG("still %d DMA in progress after completion - "
+		    "now %"FMT_HPT" started %lu reset %lu stopped %lu\n",
+		    host_priv->dmas_pending - 1,
+		    hptime(), since_ns(host_priv->when_started),
+		    since_ns(host_priv->when_reset),
+		    since_ns(host_priv->when_stopped));
+	BUG_ON(host_priv->dmas_pending <= 0);
+	host_priv->dmas_pending -= 1;
+	host_priv->when_stopped = hptime();
+#endif
+	host_priv->dma_wanted = 0;
+
+	if (NULL == data) {
+		DBG("PDMA unused completion - status 0x%X\n", dma_cs);
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+	sg = data->sg;
+	sg_len = data->sg_len;
+	sg_todo = sg_dma_len(&sg[host_priv->sg_ix]);
+
+	DBG("PDMA complete %d/%d [%d]/[%d]..\n",
+	    host_priv->sg_done, sg_todo,
+	    host_priv->sg_ix+1, sg_len);
+
+	BUG_ON(host_priv->sg_done > sg_todo);
+
+	if (host_priv->sg_done >= sg_todo) {
+		host_priv->sg_ix++;
+		host_priv->sg_done = 0;
+	}
+
+	sg_ix = host_priv->sg_ix;
+	if (sg_ix < sg_len) {
+		u32 irq_mask;
+		/* Set off next DMA if we've got the capacity */
+
+		if (data->flags & MMC_DATA_READ)
+			irq_mask = SDHCI_INT_DATA_AVAIL;
+		else
+			irq_mask = SDHCI_INT_SPACE_AVAIL;
+
+		/* We have to use the interrupt status register on the BCM2708
+		   rather than the SDHCI_PRESENT_STATE register because latency
+		   in the glue logic means that the information retrieved from
+		   the latter is not always up-to-date w.r.t the DMA engine -
+		   it may not indicate that a read or a write is ready yet */
+		if (sdhci_bcm2708_raw_readl(host, SDHCI_INT_STATUS) &
+		    irq_mask) {
+			size_t bytes = sg_dma_len(&sg[sg_ix]) -
+				       host_priv->sg_done;
+			dma_addr_t addr = sg_dma_address(&data->sg[sg_ix]) +
+					  host_priv->sg_done;
+
+			/* acknowledge interrupt */
+			sdhci_bcm2708_raw_writel(host, irq_mask,
+						 SDHCI_INT_STATUS);
+
+			BUG_ON(0 == bytes);
+
+			if (data->flags & MMC_DATA_READ)
+				sdhci_platdma_read(host, addr, bytes);
+			else
+				sdhci_platdma_write(host, addr, bytes);
+		} else {
+			DBG("PDMA - wait avail\n");
+			/* may generate an IRQ if already present */
+			sdhci_signal_irqs(host, SDHCI_INT_DATA_AVAIL |
+						SDHCI_INT_SPACE_AVAIL);
+		}
+	} else {
+#ifdef USE_SYNC_AFTER_DMA
+		/* On the Arasan controller the stop command (which will be
+		   scheduled after this completes) does not seem to work
+		   properly if we allow it to be issued when we are
+		   transferring data to/from the SD card.
+		   We get CRC and DEND errors unless we wait for
+		   the SD controller to finish reading/writing to the card. */
+		u32 state_mask;
+		int timeout=1000000;
+		hptime_t now = hptime();
+
+		DBG("PDMA over - sync card\n");
+		if (data->flags & MMC_DATA_READ)
+			state_mask = SDHCI_DOING_READ;
+		else
+			state_mask = SDHCI_DOING_WRITE;
+
+		while (0 != (sdhci_bcm2708_raw_readl(host,
+						     SDHCI_PRESENT_STATE) &
+			     state_mask) && --timeout > 0)
+			continue;
+
+		if (1000000-timeout > 4000) /*ave. is about 3250*/
+			printk(KERN_INFO "%s: note - long %s sync %luns - "
+			       "%d its.\n",
+			       mmc_hostname(host->mmc),
+			       data->flags & MMC_DATA_READ? "read": "write",
+			       since_ns(now), 1000000-timeout);
+		if (timeout <= 0)
+			printk(KERN_ERR"%s: final %s to SD card still "
+			       "running\n",
+			       mmc_hostname(host->mmc),
+			       data->flags & MMC_DATA_READ? "read": "write");
+#endif
+		if (host_priv->complete) {
+			(*host_priv->complete)(host);
+			DBG("PDMA %s complete\n",
+			    data->flags & MMC_DATA_READ?"read":"write");
+			sdhci_signal_irqs(host, SDHCI_INT_DATA_AVAIL |
+						SDHCI_INT_SPACE_AVAIL);
+		}
+	}
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static irqreturn_t sdhci_bcm2708_dma_irq(int irq, void *dev_id)
+{
+	irqreturn_t result = IRQ_NONE;
+	struct sdhci_host *host = dev_id;
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	u32 dma_cs; /* control and status register */
+	unsigned long flags;
+
+	BUG_ON(NULL == dev_id);
+	BUG_ON(NULL == host_priv->dma_chan_base);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	dma_cs = readl(host_priv->dma_chan_base + BCM2708_DMA_CS);
+
+	if (dma_cs & BCM2708_DMA_ERR) {
+		unsigned long debug;
+		debug = readl(host_priv->dma_chan_base +
+			      BCM2708_DMA_DEBUG);
+		printk(KERN_ERR "%s: DMA error - CS %lX DEBUG %lX\n",
+		       mmc_hostname(host->mmc), (unsigned long)dma_cs,
+		       (unsigned long)debug);
+		/* reset error */
+		writel(debug, host_priv->dma_chan_base +
+		       BCM2708_DMA_DEBUG);
+	}
+	if (dma_cs & BCM2708_DMA_INT) {
+		/* acknowledge interrupt */
+		writel(BCM2708_DMA_INT,
+		       host_priv->dma_chan_base + BCM2708_DMA_CS);
+
+		dsb(); /* ARM data synchronization (push) operation */
+
+		if (!host_priv->dma_wanted) {
+			/* ignore this interrupt - it was reset */
+			printk(KERN_INFO "%s: DMA IRQ %X ignored - "
+			       "results were reset\n",
+			       mmc_hostname(host->mmc), dma_cs);
+#ifdef CHECK_DMA_USE
+			printk(KERN_INFO "%s: now %"FMT_HPT
+			       " started %lu reset %lu stopped %lu\n",
+			       mmc_hostname(host->mmc), hptime(),
+			       since_ns(host_priv->when_started),
+			       since_ns(host_priv->when_reset),
+			       since_ns(host_priv->when_stopped));
+			host_priv->dmas_pending--;
+#endif
+		} else
+			sdhci_bcm2708_dma_complete_irq(host, dma_cs);
+
+		result = IRQ_HANDLED;
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return result;
+}
+#endif /* CONFIG_MMC_SDHCI_BCM2708_DMA */
+
+
+/***************************************************************************** \
+ *									     *
+ * Device Attributes							     *
+ *									     *
+\*****************************************************************************/
+
+
+/**
+ * Show the DMA-using status
+ */
+static ssize_t attr_dma_show(struct device *_dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev);
+
+	if (host) {
+		int use_dma = (host->flags & SDHCI_USE_PLATDMA? 1:0);
+		return sprintf(buf, "%d\n", use_dma);
+	} else
+		return -EINVAL;
+}
+
+/**
+ * Set the DMA-using status
+ */
+static ssize_t attr_dma_store(struct device *_dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev);
+
+	if (host) {
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+		int on = simple_strtol(buf, NULL, 0);
+		if (on) {
+			host->flags |= SDHCI_USE_PLATDMA;
+			printk(KERN_INFO "%s: DMA enabled\n",
+			       mmc_hostname(host->mmc));
+		} else {
+			host->flags &= ~(SDHCI_USE_PLATDMA | SDHCI_REQ_USE_DMA);
+			printk(KERN_INFO "%s: DMA disabled\n",
+			       mmc_hostname(host->mmc));
+		}
+#endif
+		return count;
+	} else
+		return -EINVAL;
+}
+
+static DEVICE_ATTR(use_dma, S_IRUGO | S_IWUGO, attr_dma_show, attr_dma_store);
+
+
+/**
+ * Show the DMA wait states used
+ */
+static ssize_t attr_dmawait_show(struct device *_dev,
+			         struct device_attribute *attr, char *buf)
+{
+	struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev);
+
+	if (host) {
+		struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+		int dmawait = host_priv->dma_waits;
+		return sprintf(buf, "%d\n", dmawait);
+	} else
+		return -EINVAL;
+}
+
+/**
+ * Set the DMA wait state used
+ */
+static ssize_t attr_dmawait_store(struct device *_dev,
+			          struct device_attribute *attr,
+    			          const char *buf, size_t count)
+{
+	struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev);
+
+	if (host) {
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+		struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+		int dma_waits = simple_strtol(buf, NULL, 0);
+		if (dma_waits >= 0 && dma_waits < 32) 
+                        host_priv->dma_waits = dma_waits;
+		else
+			printk(KERN_ERR "%s: illegal dma_waits value - %d",
+			       mmc_hostname(host->mmc), dma_waits);
+#endif
+		return count;
+	} else
+		return -EINVAL;
+}
+
+static DEVICE_ATTR(dma_wait, S_IRUGO | S_IWUGO,
+                   attr_dmawait_show, attr_dmawait_store);
+
+
+/**
+ * Show the DMA-using status
+ */
+static ssize_t attr_status_show(struct device *_dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct sdhci_host *host = (struct sdhci_host *)dev_get_drvdata(_dev);
+
+	if (host) {
+		struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+		int power_state = host_priv->power_state;
+		return sprintf(buf,
+			       "present: yes\n"
+			       "power: %s\n"
+			       "clock: %u Hz\n"
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+			       "dma: %s (%d waits)\n",
+#else
+			       "dma: unconfigured\n",
+#endif
+			       power_state == POWER_ON? "on":
+			       power_state == POWER_OFF? "off":
+			       power_state == POWER_LAZY_OFF? "lazy-off":
+			       "<unknown>",
+			       host->clock
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+			       , (host->flags & SDHCI_USE_PLATDMA)? "on": "off"
+                               , host_priv->dma_waits
+#endif
+			       );
+	} else
+		return -EINVAL;
+}
+
+static DEVICE_ATTR(status, S_IRUGO, attr_status_show, NULL);
+
+/***************************************************************************** \
+ *									     *
+ * Power Management							     *
+ *									     *
+\*****************************************************************************/
+
+
+#ifdef CONFIG_PM
+static int sdhci_bcm2708_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct sdhci_host *host = (struct sdhci_host *)
+				  platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (host->mmc) {
+		ret = mmc_suspend_host(host->mmc);
+	}
+
+	return ret;
+}
+
+static int sdhci_bcm2708_resume(struct platform_device *dev)
+{
+	struct sdhci_host *host = (struct sdhci_host *)
+				  platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (host->mmc) {
+		ret = mmc_resume_host(host->mmc);
+	}
+
+	return ret;
+}
+#endif
+
+
+/* Click forwards one step towards fully on */
+static int sdhci_bcm2708_enable(struct sdhci_host *host)
+{
+	int rc;
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+
+	if (host_priv->power_state == POWER_OFF) {
+		/* warning: may schedule - don't call in irq mode */
+		rc = bcm_power_request(host_priv->power_handle,
+				       BCM_POWER_SDCARD);
+
+		if (rc == 0) {
+			mmc_power_restore_host(host->mmc);
+			host_priv->power_state = POWER_ON;
+		} else if (rc != -EINTR)
+			printk(KERN_ERR "%s: mmc power up request failed - "
+			       "rc %d\n",
+			       mmc_hostname(host->mmc), rc);
+	} else {
+		host_priv->power_state = POWER_ON;
+		rc = 0;
+	}
+
+	return rc;
+}
+
+/* Click backwards one step towards fully off */
+static int sdhci_bcm2708_disable(struct sdhci_host *host, int lazy)
+{
+	int rc;
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+
+	if ((host_priv->power_state == POWER_ON) && lazy) {
+		host_priv->power_state = POWER_LAZY_OFF;
+		return BCM2708_SDHCI_SLEEP_TIMEOUT;
+	}
+
+	/* warning: may schedule - don't call in irq mode */
+	rc = bcm_power_request(host_priv->power_handle, BCM_POWER_NONE);
+
+	if (rc == 0)
+		host_priv->power_state = POWER_OFF;
+	else if (rc != -EINTR)
+		printk(KERN_ERR "%s: mmc power down request failed - rc %d\n",
+		       mmc_hostname(host->mmc), rc);
+
+	return rc;
+}
+
+static int sdhci_bcm2708_set_plat_power(struct sdhci_host *host,
+					int power_mode)
+{
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	int rc;
+
+	do {
+		rc = mmc_host_enable(host->mmc);
+	} while (-EINTR == rc);
+
+	if (rc == 0) do {
+		if (rc == 0 && power_mode != host_priv->power_mode)
+		{
+			switch (power_mode)
+			{
+			case MMC_POWER_OFF:
+				rc = bcm_power_request(host_priv->power_handle,
+						       BCM_POWER_NONE);
+				break;
+
+			case MMC_POWER_UP:
+				rc = bcm_power_request(host_priv->power_handle,
+						       BCM_POWER_SDCARD);
+				/*
+				 * We need an extra 10ms delay of 10ms before we
+				 * can apply clock after applying power
+				 */
+				if (rc == 0)
+				    mdelay(10);
+				break;
+
+			case MMC_POWER_ON:
+				mdelay(10);
+				/* do_send_init_stream = 1; */
+				break;
+			}
+
+			if (rc == 0)
+			    host_priv->power_mode = power_mode;
+		}
+	} while (-EINTR == rc);
+
+	if (rc == 0) do {
+		if (rc == 0) {
+			if (power_mode == MMC_POWER_OFF)
+				rc = mmc_host_disable(host->mmc);
+			else
+				rc = mmc_host_lazy_disable(host->mmc);
+		}
+
+	} while (-EINTR == rc);
+
+	return rc;
+}
+
+/*****************************************************************************\
+ *                                                                           *
+ * Device quirk functions. Implemented as local ops because the flags        *
+ * field is out of space with newer kernels. This implementation can be      *
+ * back ported to older kernels as well.                                     *
+\****************************************************************************/
+static unsigned int sdhci_bcm2708_quirk_extra_ints(struct sdhci_host *host)
+{
+        return 1;
+}
+
+static unsigned int sdhci_bcm2708_quirk_spurious_crc(struct sdhci_host *host)
+{
+        return 1;
+}
+
+static unsigned int sdhci_bcm2708_quirk_voltage_broken(struct sdhci_host *host)
+{
+        return 1;
+}
+
+static unsigned int sdhci_bcm2708_uhs_broken(struct sdhci_host *host)
+{
+        return 1;
+}
+
+/***************************************************************************** \
+ *									     *
+ * Device ops								     *
+ *									     *
+\*****************************************************************************/
+
+static struct sdhci_ops sdhci_bcm2708_ops = {
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+	.read_l = sdhci_bcm2708_readl,
+	.read_w = sdhci_bcm2708_readw,
+	.read_b = sdhci_bcm2708_readb,
+	.write_l = sdhci_bcm2708_writel,
+	.write_w = sdhci_bcm2708_writew,
+	.write_b = sdhci_bcm2708_writeb,
+#else
+#error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set
+#endif
+	//.enable_dma = NULL,
+	//.set_clock = NULL,
+	.get_max_clock = sdhci_bcm2708_get_max_clock,
+	//.get_min_clock = NULL,
+	.get_timeout_clock = sdhci_bcm2708_get_timeout_clock,
+
+	.enable = sdhci_bcm2708_enable,
+	.disable = sdhci_bcm2708_disable,
+	.set_plat_power = sdhci_bcm2708_set_plat_power,
+
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+	// Platform DMA operations
+	.pdma_able  = sdhci_bcm2708_platdma_dmaable,
+	.pdma_avail = sdhci_bcm2708_platdma_avail,
+	.pdma_reset = sdhci_bcm2708_platdma_reset,
+#endif
+	.extra_ints = sdhci_bcm2708_quirk_extra_ints,
+	.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
+	.voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
+	.uhs_broken = sdhci_bcm2708_uhs_broken,
+};
+
+/*****************************************************************************\
+ *									     *
+ * Device probing/removal						     *
+ *									     *
+\*****************************************************************************/
+
+static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct resource *iomem;
+	struct sdhci_bcm2708_priv *host_priv;
+	int ret;
+
+	BUG_ON(pdev == NULL);
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	if (resource_size(iomem) != 0x100)
+		dev_err(&pdev->dev, "Invalid iomem size. You may "
+			"experience problems.\n");
+
+	if (pdev->dev.parent)
+		host = sdhci_alloc_host(pdev->dev.parent,
+					sizeof(struct sdhci_bcm2708_priv));
+	else
+		host = sdhci_alloc_host(&pdev->dev,
+					sizeof(struct sdhci_bcm2708_priv));
+
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
+		goto err;
+	}
+
+	host->hw_name = "BCM2708_Arasan";
+	host->ops = &sdhci_bcm2708_ops;
+	host->irq = platform_get_irq(pdev, 0);
+
+	host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		       SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+	host->flags = SDHCI_USE_PLATDMA;
+#endif
+
+	if (!request_mem_region(iomem->start, resource_size(iomem),
+				mmc_hostname(host->mmc))) {
+		dev_err(&pdev->dev, "cannot request region\n");
+		ret = -EBUSY;
+		goto err_request;
+	}
+
+	host->ioaddr = ioremap(iomem->start, resource_size(iomem));
+	if (!host->ioaddr) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
+		goto err_remap;
+	}
+
+	host_priv = SDHCI_HOST_PRIV(host);
+
+	host_priv->power_state = POWER_ON;
+	ret = bcm_power_open(&host_priv->power_handle);
+	if (ret != 0)
+		goto err_power;
+
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+	host_priv->dma_wanted = 0;
+#ifdef CHECK_DMA_USE
+	host_priv->dmas_pending = 0;
+	host_priv->when_started = 0;
+	host_priv->when_reset = 0;
+	host_priv->when_stopped = 0;
+#endif
+	host_priv->sg_ix = 0;
+	host_priv->sg_done = 0;
+	host_priv->complete = NULL;
+	host_priv->dma_waits = SDHCI_BCM_DMA_WAITS;
+
+	host_priv->cb_base = dma_alloc_writecombine(&pdev->dev, SZ_4K,
+						    &host_priv->cb_handle,
+						    GFP_KERNEL);
+	if (!host_priv->cb_base) {
+		dev_err(&pdev->dev, "cannot allocate DMA CBs\n");
+		ret = -ENOMEM;
+		goto err_alloc_cb;
+	}
+
+	ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_FAST,
+				 &host_priv->dma_chan_base,
+				 &host_priv->dma_irq);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "couldn't allocate a DMA channel\n");
+		goto err_add_dma;
+	}
+	host_priv->dma_chan = ret;
+
+	ret = request_irq(host_priv->dma_irq, sdhci_bcm2708_dma_irq,
+			  IRQF_SHARED, DRIVER_NAME " (dma)", host);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot set DMA IRQ\n");
+		goto err_add_dma_irq;
+	}
+	DBG("DMA CBs %p handle %08X DMA%d %p DMA IRQ %d\n",
+	    host_priv->cb_base, (unsigned)host_priv->cb_handle,
+	    host_priv->dma_chan, host_priv->dma_chan_base,
+	    host_priv->dma_irq);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_add_host;
+
+	platform_set_drvdata(pdev, host);
+	ret = device_create_file(&pdev->dev, &dev_attr_use_dma);
+	ret = device_create_file(&pdev->dev, &dev_attr_dma_wait);
+	ret = device_create_file(&pdev->dev, &dev_attr_status);
+
+	printk(KERN_INFO "%s: BCM2708 SDHC host at 0x%08llx DMA %d IRQ %d\n",
+	       mmc_hostname(host->mmc), (unsigned long long)iomem->start,
+	       host_priv->dma_chan, host_priv->dma_irq);
+
+	return 0;
+
+err_add_host:
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+	free_irq(host_priv->dma_irq, host);
+err_add_dma_irq:
+	bcm_dma_chan_free(host_priv->dma_chan);
+err_add_dma:
+	dma_free_writecombine(&pdev->dev, SZ_4K, host_priv->cb_base,
+			      host_priv->cb_handle);
+err_alloc_cb:
+#endif
+	bcm_power_close(host_priv->power_handle);
+err_power:
+	iounmap(host->ioaddr);
+err_remap:
+	release_mem_region(iomem->start, resource_size(iomem));
+err_request:
+	sdhci_free_host(host);
+err:
+	dev_err(&pdev->dev, "probe failed, err %d\n", ret);
+	return ret;
+}
+
+static int __devexit sdhci_bcm2708_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = sdhci_bcm2708_readl(host, SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+
+	device_remove_file(&pdev->dev, &dev_attr_status);
+	device_remove_file(&pdev->dev, &dev_attr_dma_wait);
+	device_remove_file(&pdev->dev, &dev_attr_use_dma);
+
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+	free_irq(host_priv->dma_irq, host);
+	dma_free_writecombine(&pdev->dev, SZ_4K, host_priv->cb_base,
+			      host_priv->cb_handle);
+#endif
+	bcm_power_close(host_priv->power_handle);
+	sdhci_remove_host(host, dead);
+	iounmap(host->ioaddr);
+	release_mem_region(iomem->start, resource_size(iomem));
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_bcm2708_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sdhci_bcm2708_probe,
+	.remove		= __devexit_p(sdhci_bcm2708_remove),
+
+#ifdef CONFIG_PM
+	.suspend = sdhci_bcm2708_suspend,
+	.resume = sdhci_bcm2708_resume,
+#endif
+
+};
+
+/*****************************************************************************\
+ *									     *
+ * Driver init/exit							     *
+ *									     *
+\*****************************************************************************/
+
+static int __init sdhci_drv_init(void)
+{
+	return platform_driver_register(&sdhci_bcm2708_driver);
+}
+
+static void __exit sdhci_drv_exit(void)
+{
+	platform_driver_unregister(&sdhci_bcm2708_driver);
+}
+
+module_init(sdhci_drv_init);
+module_exit(sdhci_drv_exit);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+MODULE_AUTHOR("Broadcom <info@broadcom.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRIVER_NAME);
+
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -27,6 +27,7 @@
 
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/sd.h>
 
 #include "sdhci.h"
 
@@ -66,6 +67,7 @@ static inline int sdhci_runtime_pm_put(s
 }
 #endif
 
+
 static void sdhci_dumpregs(struct sdhci_host *host)
 {
 	pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
@@ -150,6 +152,9 @@ static void sdhci_set_card_detection(str
 	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		return;
 
+	if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION)
+		return;
+
 	present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
 			      SDHCI_CARD_PRESENT;
 	irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
@@ -299,7 +304,7 @@ static void sdhci_read_block_pio(struct
 	u32 uninitialized_var(scratch);
 	u8 *buf;
 
-	DBG("PIO reading\n");
+	DBG("PIO reading %db\n", host->data->blksz);
 
 	blksize = host->data->blksz;
 	chunk = 0;
@@ -344,7 +349,7 @@ static void sdhci_write_block_pio(struct
 	u32 scratch;
 	u8 *buf;
 
-	DBG("PIO writing\n");
+	DBG("PIO writing %db\n", host->data->blksz);
 
 	blksize = host->data->blksz;
 	chunk = 0;
@@ -383,19 +388,28 @@ static void sdhci_write_block_pio(struct
 	local_irq_restore(flags);
 }
 
-static void sdhci_transfer_pio(struct sdhci_host *host)
+static void sdhci_transfer_pio(struct sdhci_host *host, u32 intstate)
 {
 	u32 mask;
+	u32 state = 0;
+	u32 intmask;
+	int available;
 
 	BUG_ON(!host->data);
 
 	if (host->blocks == 0)
 		return;
 
-	if (host->data->flags & MMC_DATA_READ)
+	if (host->data->flags & MMC_DATA_READ) {
 		mask = SDHCI_DATA_AVAILABLE;
-	else
+		intmask = SDHCI_INT_DATA_AVAIL;
+	} else {
 		mask = SDHCI_SPACE_AVAILABLE;
+		intmask = SDHCI_INT_SPACE_AVAIL;
+	}
+
+	/* initially we can see whether we can procede using intstate */
+	available = (intstate & intmask);
 
 	/*
 	 * Some controllers (JMicron JMB38x) mess up the buffer bits
@@ -406,7 +420,7 @@ static void sdhci_transfer_pio(struct sd
 		(host->data->blocks == 1))
 		mask = ~0;
 
-	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+	while (available) {
 		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
 			udelay(100);
 
@@ -418,9 +432,11 @@ static void sdhci_transfer_pio(struct sd
 		host->blocks--;
 		if (host->blocks == 0)
 			break;
+		state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+		available = state & mask;
 	}
 
-	DBG("PIO transfer complete.\n");
+	DBG("PIO transfer complete - %d blocks left.\n", host->blocks);
 }
 
 static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
@@ -693,7 +709,9 @@ static void sdhci_set_transfer_irqs(stru
 	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
 	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
 
-	if (host->flags & SDHCI_REQ_USE_DMA)
+	/* platform DMA will begin on receipt of PIO irqs */
+	if ((host->flags & SDHCI_REQ_USE_DMA) &&
+	    !(host->flags & SDHCI_USE_PLATDMA))
 		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
 	else
 		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
@@ -725,44 +743,25 @@ static void sdhci_prepare_data(struct sd
 	host->data_early = 0;
 	host->data->bytes_xfered = 0;
 
-	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
+	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA | SDHCI_USE_PLATDMA))
 		host->flags |= SDHCI_REQ_USE_DMA;
 
 	/*
 	 * FIXME: This doesn't account for merging when mapping the
 	 * scatterlist.
 	 */
-	if (host->flags & SDHCI_REQ_USE_DMA) {
-		int broken, i;
-		struct scatterlist *sg;
-
-		broken = 0;
-		if (host->flags & SDHCI_USE_ADMA) {
-			if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
-				broken = 1;
-		} else {
-			if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
-				broken = 1;
-		}
-
-		if (unlikely(broken)) {
-			for_each_sg(data->sg, sg, data->sg_len, i) {
-				if (sg->length & 0x3) {
-					DBG("Reverting to PIO because of "
-						"transfer size (%d)\n",
-						sg->length);
-					host->flags &= ~SDHCI_REQ_USE_DMA;
-					break;
-				}
-			}
-		}
-	}
 
 	/*
 	 * The assumption here being that alignment is the same after
 	 * translation to device address space.
 	 */
-	if (host->flags & SDHCI_REQ_USE_DMA) {
+	if ((host->flags & (SDHCI_REQ_USE_DMA | SDHCI_USE_PLATDMA)) ==
+	    (SDHCI_REQ_USE_DMA | SDHCI_USE_PLATDMA)) {
+		
+		if (! sdhci_platdma_dmaable(host, data))
+			host->flags &= ~SDHCI_REQ_USE_DMA;
+
+	} else if (host->flags & SDHCI_REQ_USE_DMA) {
 		int broken, i;
 		struct scatterlist *sg;
 
@@ -821,7 +820,8 @@ static void sdhci_prepare_data(struct sd
 				 */
 				WARN_ON(1);
 				host->flags &= ~SDHCI_REQ_USE_DMA;
-			} else {
+			} else 
+			if (!(host->flags & SDHCI_USE_PLATDMA)) {
 				WARN_ON(sg_cnt != 1);
 				sdhci_writel(host, sg_dma_address(data->sg),
 					SDHCI_DMA_ADDRESS);
@@ -837,11 +837,13 @@ static void sdhci_prepare_data(struct sd
 	if (host->version >= SDHCI_SPEC_200) {
 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
-		if ((host->flags & SDHCI_REQ_USE_DMA) &&
-			(host->flags & SDHCI_USE_ADMA))
-			ctrl |= SDHCI_CTRL_ADMA32;
-		else
-			ctrl |= SDHCI_CTRL_SDMA;
+		if (! (host->flags & SDHCI_USE_PLATDMA)) {
+			if ((host->flags & SDHCI_REQ_USE_DMA) &&
+				(host->flags & SDHCI_USE_ADMA))
+				ctrl |= SDHCI_CTRL_ADMA32;
+			else
+				ctrl |= SDHCI_CTRL_SDMA;
+		}
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 	}
 
@@ -893,7 +895,8 @@ static void sdhci_set_transfer_mode(stru
 
 	if (data->flags & MMC_DATA_READ)
 		mode |= SDHCI_TRNS_READ;
-	if (host->flags & SDHCI_REQ_USE_DMA)
+	if ((host->flags & SDHCI_REQ_USE_DMA) &&
+	    !(host->flags & SDHCI_USE_PLATDMA))
 		mode |= SDHCI_TRNS_DMA;
 
 	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
@@ -909,13 +912,16 @@ static void sdhci_finish_data(struct sdh
 	host->data = NULL;
 
 	if (host->flags & SDHCI_REQ_USE_DMA) {
-		if (host->flags & SDHCI_USE_ADMA)
-			sdhci_adma_table_post(host, data);
-		else {
+		/* we may have to abandon an ongoing platform DMA */
+		if (host->flags & SDHCI_USE_PLATDMA)
+			sdhci_platdma_reset(host, data);
+
+		if (host->flags & (SDHCI_USE_PLATDMA | SDHCI_USE_SDMA)) {
 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
 				data->sg_len, (data->flags & MMC_DATA_READ) ?
 					DMA_FROM_DEVICE : DMA_TO_DEVICE);
-		}
+		} else if (host->flags & SDHCI_USE_ADMA)
+                        sdhci_adma_table_post(host, data);
 	}
 
 	/*
@@ -985,10 +991,16 @@ static void sdhci_send_command(struct sd
 		timeout--;
 		mdelay(1);
 	}
+	DBG("send cmd %d - wait 0x%X irq 0x%x\n", cmd->opcode, mask,
+	    sdhci_readl(host, SDHCI_INT_STATUS));
 
 	mod_timer(&host->timer, jiffies + 10 * HZ);
 
 	host->cmd = cmd;
+	if (host->last_cmdop == MMC_APP_CMD)
+		host->last_cmdop = -cmd->opcode;
+	else
+		host->last_cmdop = cmd->opcode;
 
 	sdhci_prepare_data(host, cmd);
 
@@ -1234,6 +1246,35 @@ static int sdhci_set_power(struct sdhci_
 	return power;
 }
 
+/* Power on or off the circuitary supporting the register set */
+static int sdhci_set_plat_power(struct sdhci_host *host, int power_mode)
+{
+	if (host->ops->set_plat_power)
+		return host->ops->set_plat_power(host, power_mode);
+	else
+		return 0;
+}
+
+/* Click forwards one step towards fully on */
+static int sdhci_enable(struct mmc_host *mmc)
+{
+	struct sdhci_host *host;
+
+	host = mmc_priv(mmc);
+
+	return host->ops->enable? host->ops->enable(host): 0;
+}
+
+/* Click backwards one step towards fully off */
+static int sdhci_disable(struct mmc_host *mmc, int lazy)
+{
+	struct sdhci_host *host;
+
+	host = mmc_priv(mmc);
+
+	return host->ops->disable? host->ops->disable(host, lazy): 0;
+}
+
 /*****************************************************************************\
  *                                                                           *
  * MMC callbacks                                                             *
@@ -1250,6 +1291,8 @@ static void sdhci_request(struct mmc_hos
 
 	sdhci_runtime_pm_get(host);
 
+	sdhci_runtime_pm_get(host);
+
 	spin_lock_irqsave(&host->lock, flags);
 
 	WARN_ON(host->mrq != NULL);
@@ -1314,6 +1357,7 @@ static void sdhci_do_set_ios(struct sdhc
 {
 	unsigned long flags;
 	int vdd_bit = -1;
+	int rc;
 	u8 ctrl;
 
 	spin_lock_irqsave(&host->lock, flags);
@@ -1383,7 +1427,7 @@ static void sdhci_do_set_ios(struct sdhc
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	if (host->version >= SDHCI_SPEC_300) {
+	if (host->version >= SDHCI_SPEC_300 && !(host->ops->uhs_broken)) {
 		u16 clk, ctrl_2;
 		unsigned int clock;
 
@@ -1474,6 +1518,12 @@ static void sdhci_do_set_ios(struct sdhc
 
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (ios->power_mode == MMC_POWER_OFF) {
+		do 
+			rc = sdhci_set_plat_power(host, ios->power_mode);
+		while (rc == -EINTR);
+	}
 }
 
 static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -1934,6 +1984,8 @@ static const struct mmc_host_ops sdhci_o
 	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,
 	.execute_tuning			= sdhci_execute_tuning,
 	.enable_preset_value		= sdhci_enable_preset_value,
+	.enable		= sdhci_enable,
+	.disable	= sdhci_disable,
 };
 
 /*****************************************************************************\
@@ -2091,10 +2143,13 @@ static void sdhci_cmd_irq(struct sdhci_h
 	BUG_ON(intmask == 0);
 
 	if (!host->cmd) {
-		pr_err("%s: Got command interrupt 0x%08x even "
-			"though no command operation was in progress.\n",
-			mmc_hostname(host->mmc), (unsigned)intmask);
-		sdhci_dumpregs(host);
+		if (!(host->ops->extra_ints)) {
+			pr_err("%s: Got command interrupt 0x%08x even "
+				"though no command operation was in progress.\n",
+				mmc_hostname(host->mmc), (unsigned)intmask);
+			sdhci_dumpregs(host);
+		} else
+			DBG("cmd irq 0x%08x cmd complete\n", (unsigned)intmask);
 		return;
 	}
 
@@ -2164,6 +2219,19 @@ static void sdhci_show_adma_error(struct
 static void sdhci_show_adma_error(struct sdhci_host *host) { }
 #endif
 
+static void sdhci_data_end(struct sdhci_host *host)
+{
+	if (host->cmd) {
+		/*
+		 * Data managed to finish before the
+		 * command completed. Make sure we do
+		 * things in the proper order.
+		 */
+		host->data_early = 1;
+	} else 
+		sdhci_finish_data(host);
+}
+
 static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 {
 	u32 command;
@@ -2192,35 +2260,57 @@ static void sdhci_data_irq(struct sdhci_
 				return;
 			}
 		}
-
-		pr_err("%s: Got data interrupt 0x%08x even "
-			"though no data operation was in progress.\n",
-			mmc_hostname(host->mmc), (unsigned)intmask);
-		sdhci_dumpregs(host);
-
-		return;
-	}
-
-	if (intmask & SDHCI_INT_DATA_TIMEOUT)
-		host->data->error = -ETIMEDOUT;
-	else if (intmask & SDHCI_INT_DATA_END_BIT)
-		host->data->error = -EILSEQ;
-	else if ((intmask & SDHCI_INT_DATA_CRC) &&
-		SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
-			!= MMC_BUS_TEST_R)
-		host->data->error = -EILSEQ;
-	else if (intmask & SDHCI_INT_ADMA_ERROR) {
+		
+		if (!(host->ops->extra_ints)) {
+			pr_err("%s: Got data interrupt 0x%08x even "
+				"though no data operation was in progress.\n",
+				mmc_hostname(host->mmc), (unsigned)intmask);
+			sdhci_dumpregs(host);
+		} else
+			DBG("data irq 0x%08x but no data\n", (unsigned)intmask);
+ 
+ 		return;
+ 	}
+ 
+ 	if (intmask & SDHCI_INT_DATA_TIMEOUT)
+ 		host->data->error = -ETIMEDOUT;
+	else if (intmask & SDHCI_INT_DATA_END_BIT) {
+		DBG("end error in cmd %d\n", host->last_cmdop);
+		if (host->ops->spurious_crc_acmd51 &&
+		    host->last_cmdop == -SD_APP_SEND_SCR) {
+			DBG("ignoring spurious data_end_bit error\n");
+			intmask = SDHCI_INT_DATA_AVAIL|SDHCI_INT_DATA_END;
+		} else
+			host->data->error = -EILSEQ;
+	} else if ((intmask & SDHCI_INT_DATA_CRC) &&
+ 		SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
+			!= MMC_BUS_TEST_R) {
+		DBG("crc error in cmd %d\n", host->last_cmdop);
+		if (host->ops->spurious_crc_acmd51 &&
+		    host->last_cmdop == -SD_APP_SEND_SCR) {
+			DBG("ignoring spurious data_crc_bit error\n");
+			intmask = SDHCI_INT_DATA_AVAIL|SDHCI_INT_DATA_END;
+		} else
+			host->data->error = -EILSEQ;
+	} else if (intmask & SDHCI_INT_ADMA_ERROR) {
 		pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
-		sdhci_show_adma_error(host);
-		host->data->error = -EIO;
-	}
-
-	if (host->data->error)
-		sdhci_finish_data(host);
-	else {
-		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
-			sdhci_transfer_pio(host);
-
+ 		sdhci_show_adma_error(host);
+ 		host->data->error = -EIO;
+ 	}
+ 
+	if (host->data->error) {
+		DBG("finish request early on error %d\n", host->data->error);
+ 		sdhci_finish_data(host);
+	} else {
+		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) {
+			if (host->flags & SDHCI_REQ_USE_DMA) {
+				/* possible only in PLATDMA mode */
+				sdhci_platdma_avail(host, &intmask,
+						&sdhci_data_end);
+			} else
+				sdhci_transfer_pio(host, intmask);
+		}
+ 
 		/*
 		 * We currently don't do anything fancy with DMA
 		 * boundaries, but as we can't disable the feature
@@ -2249,16 +2339,7 @@ static void sdhci_data_irq(struct sdhci_
 		}
 
 		if (intmask & SDHCI_INT_DATA_END) {
-			if (host->cmd) {
-				/*
-				 * Data managed to finish before the
-				 * command completed. Make sure we do
-				 * things in the proper order.
-				 */
-				host->data_early = 1;
-			} else {
-				sdhci_finish_data(host);
-			}
+			sdhci_data_end(host);	
 		}
 	}
 }
@@ -2314,6 +2395,22 @@ static irqreturn_t sdhci_irq(int irq, vo
 		tasklet_schedule(&host->card_tasklet);
 	}
 
+	if (intmask & SDHCI_INT_ERROR_MASK & ~SDHCI_INT_ERROR)
+		DBG("controller reports error 0x%x -"
+				"%s%s%s%s%s%s%s%s%s%s",
+				intmask,
+				intmask & SDHCI_INT_TIMEOUT? " timeout": "",
+				intmask & SDHCI_INT_CRC     ? " crc": "",
+				intmask & SDHCI_INT_END_BIT? " endbit": "",
+				intmask & SDHCI_INT_INDEX? " index": "",
+				intmask & SDHCI_INT_DATA_TIMEOUT? " data_timeout": "",
+				intmask & SDHCI_INT_DATA_CRC? " data_crc": "",
+				intmask & SDHCI_INT_DATA_END_BIT? " data_endbit": "",
+				intmask & SDHCI_INT_BUS_POWER? " buspower": "",
+				intmask & SDHCI_INT_ACMD12ERR? " acmd12": "",
+				intmask & SDHCI_INT_ADMA_ERROR? " adma": ""
+		   );
+
 	if (intmask & SDHCI_INT_CMD_MASK) {
 		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
 			SDHCI_INT_STATUS);
@@ -2535,6 +2632,90 @@ EXPORT_SYMBOL_GPL(sdhci_runtime_resume_h
 
 #endif
 
+#ifdef CONFIG_PM_RUNTIME
+
+static int sdhci_runtime_pm_get(struct sdhci_host *host)
+{
+	return pm_runtime_get_sync(host->mmc->parent);
+}
+
+static int sdhci_runtime_pm_put(struct sdhci_host *host)
+{
+	pm_runtime_mark_last_busy(host->mmc->parent);
+	return pm_runtime_put_autosuspend(host->mmc->parent);
+}
+
+int sdhci_runtime_suspend_host(struct sdhci_host *host)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	/* Disable tuning since we are suspending */
+	if (host->version >= SDHCI_SPEC_300 &&
+	    host->tuning_mode == SDHCI_TUNING_MODE_1) {
+		del_timer_sync(&host->tuning_timer);
+		host->flags &= ~SDHCI_NEEDS_RETUNING;
+	}
+
+	spin_lock_irqsave(&host->lock, flags);
+	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	synchronize_irq(host->irq);
+
+	spin_lock_irqsave(&host->lock, flags);
+	host->runtime_suspended = true;
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host);
+
+int sdhci_runtime_resume_host(struct sdhci_host *host)
+{
+	unsigned long flags;
+	int ret = 0, host_flags = host->flags;
+
+	if (host_flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
+		if (host->ops->enable_dma)
+			host->ops->enable_dma(host);
+	}
+
+	sdhci_init(host, 0);
+
+	/* Force clock and power re-program */
+	host->pwr = 0;
+	host->clock = 0;
+	sdhci_do_set_ios(host, &host->mmc->ios);
+
+	sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios);
+	if (host_flags & SDHCI_PV_ENABLED)
+		sdhci_do_enable_preset_value(host, true);
+
+	/* Set the re-tuning expiration flag */
+	if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
+	    (host->tuning_mode == SDHCI_TUNING_MODE_1))
+		host->flags |= SDHCI_NEEDS_RETUNING;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->runtime_suspended = false;
+
+	/* Enable SDIO IRQ */
+	if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
+		sdhci_enable_sdio_irq_nolock(host, true);
+
+	/* Enable Card Detection */
+	sdhci_enable_card_detection(host);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sdhci_runtime_resume_host);
+
+#endif
+
 /*****************************************************************************\
  *                                                                           *
  * Device allocation/registration                                            *
@@ -2738,7 +2919,7 @@ int sdhci_add_host(struct sdhci_host *ho
 	/* Auto-CMD23 stuff only works in ADMA or PIO. */
 	if ((host->version >= SDHCI_SPEC_300) &&
 	    ((host->flags & SDHCI_USE_ADMA) ||
-	     !(host->flags & SDHCI_USE_SDMA))) {
+	     !(host->flags & SDHCI_USE_SDMA) )) {
 		host->flags |= SDHCI_AUTO_CMD23;
 		DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc));
 	} else {
@@ -2800,6 +2981,15 @@ int sdhci_add_host(struct sdhci_host *ho
 	else
 		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
 
+	/*
+	 * If Power Off Notify capability is enabled by the host,
+	 * set notify to short power off notify timeout value.
+	 */
+	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
+		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
+	else
+		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
+
 	/* Initial value for re-tuning timer count */
 	host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
 			      SDHCI_RETUNING_TIMER_COUNT_SHIFT;
@@ -2875,6 +3065,9 @@ int sdhci_add_host(struct sdhci_host *ho
 			mmc->caps |= MMC_CAP_MAX_CURRENT_200;
 	}
 
+	if(host->ops->voltage_broken)
+		ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
+
 	mmc->ocr_avail = ocr_avail;
 	mmc->ocr_avail_sdio = ocr_avail;
 	if (host->ocr_avail_sdio)
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -274,6 +274,24 @@ struct sdhci_ops {
 	void	(*platform_reset_enter)(struct sdhci_host *host, u8 mask);
 	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
 	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
+
+	int             (*enable)(struct sdhci_host *mmc);
+	int             (*disable)(struct sdhci_host *mmc, int lazy);
+	int             (*set_plat_power)(struct sdhci_host *mmc,
+					  int power_mode);
+
+	int             (*pdma_able)(struct sdhci_host *host,
+				     struct mmc_data *data);
+	void            (*pdma_avail)(struct sdhci_host *host,
+				      unsigned int *ref_intmask,
+				      void(*complete)(struct sdhci_host *));
+	void            (*pdma_reset)(struct sdhci_host *host,
+				      struct mmc_data *data);
+	unsigned int 	(*extra_ints)(struct sdhci_host *host);
+	unsigned int	(*spurious_crc_acmd51)(struct sdhci_host *host);
+	unsigned int	(*voltage_broken)(struct sdhci_host *host);
+	unsigned int	(*uhs_broken)(struct sdhci_host *host);
+
 	void	(*hw_reset)(struct sdhci_host *host);
 };
 
@@ -383,6 +401,34 @@ extern void sdhci_enable_irq_wakeups(str
 #ifdef CONFIG_PM_RUNTIME
 extern int sdhci_runtime_suspend_host(struct sdhci_host *host);
 extern int sdhci_runtime_resume_host(struct sdhci_host *host);
+#endif
+
+static inline int /*bool*/
+sdhci_platdma_dmaable(struct sdhci_host *host, struct mmc_data *data)
+{
+	if (host->ops->pdma_able)
+		return host->ops->pdma_able(host, data);
+	else
+		return 1;
+}
+static inline void
+sdhci_platdma_avail(struct sdhci_host *host, unsigned int *ref_intmask,
+		void(*completion_callback)(struct sdhci_host *))
+{
+	if (host->ops->pdma_avail)
+		host->ops->pdma_avail(host, ref_intmask, completion_callback);
+}
+
+static inline void
+sdhci_platdma_reset(struct sdhci_host *host, struct mmc_data *data)
+{
+	if (host->ops->pdma_reset)
+		host->ops->pdma_reset(host, data);
+}
+   
+#ifdef CONFIG_PM_RUNTIME
+extern int sdhci_runtime_suspend_host(struct sdhci_host *host);
+extern int sdhci_runtime_resume_host(struct sdhci_host *host);
 #endif
 
 #endif /* __SDHCI_HW_H */
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -90,6 +90,8 @@ struct sdhci_host {
 
 	unsigned int quirks2;	/* More deviations from spec. */
 
+#define SDHCI_QUIRK2_OWN_CARD_DETECTION			(1<<0)
+
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
 
@@ -120,6 +122,7 @@ struct sdhci_host {
 #define SDHCI_PV_ENABLED	(1<<8)	/* Preset value enabled */
 #define SDHCI_SDIO_IRQ_ENABLED	(1<<9)	/* SDIO irq enabled */
 #define SDHCI_HS200_NEEDS_TUNING (1<<10)	/* HS200 needs tuning */
+#define SDHCI_USE_PLATDMA	(1<<11) /* Host uses 3rd party DMA */
 
 	unsigned int version;	/* SDHCI spec. version */
 
@@ -131,9 +134,9 @@ struct sdhci_host {
 	u8 pwr;			/* Current voltage */
 
 	bool runtime_suspended;	/* Host is runtime suspended */
-
 	struct mmc_request *mrq;	/* Current request */
 	struct mmc_command *cmd;	/* Current command */
+	int	last_cmdop;	/* Opcode of last cmd sent */
 	struct mmc_data *data;	/* Current data request */
 	unsigned int data_early:1;	/* Data finished before cmd */
 
