From 9e94c1b6b0dbb1377986bc2915382b9b2d74f052 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 10 Jul 2013 19:43:11 +0000 Subject: brcm2708: drop support for 3.3 kernel Signed-off-by: Florian Fainelli git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37236 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../patches-3.3/0002-Main-bcm2708-linux-port.patch | 11023 ------------------- 1 file changed, 11023 deletions(-) delete mode 100644 target/linux/brcm2708/patches-3.3/0002-Main-bcm2708-linux-port.patch (limited to 'target/linux/brcm2708/patches-3.3/0002-Main-bcm2708-linux-port.patch') diff --git a/target/linux/brcm2708/patches-3.3/0002-Main-bcm2708-linux-port.patch b/target/linux/brcm2708/patches-3.3/0002-Main-bcm2708-linux-port.patch deleted file mode 100644 index 78de767b1e..0000000000 --- a/target/linux/brcm2708/patches-3.3/0002-Main-bcm2708-linux-port.patch +++ /dev/null @@ -1,11023 +0,0 @@ -From d5ef856b4628a4531c1627dec100eeff15e8b31e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 17 Jan 2012 19:20:11 +0000 -Subject: [PATCH 2/7] Main bcm2708 linux port - -Signed-off-by: popcornmix ---- - 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 -+#include -+#include -+#include -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) -+#include -+#else -+#include -+#endif -+#include -+ -+#include -+#include -+#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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#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 -+ -+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 -+ -+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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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<base + GPIOSET(gpio_bank)); -+ else -+ writel(1<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<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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/*****************************************************************************\ -+ * * -+ * 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 "); -+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 ---- /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< -+ -+ .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 -+ -+ -+#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 -+#include -+ -+#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 -+ -+/* -+ * 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 -+ -+/* -+ * 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 -+#include -+ -+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 -+#include -+#include -+ -+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 -+#include -+ -+#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 -+ -+#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 -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_ARCH_KONA -+#include -+#elif CONFIG_ARCH_BCM2708 -+#else -+#include -+#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 -+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 -+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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+//#include -+ -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#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 -+ -+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 //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": -+ "", -+ 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 "); -+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 - #include -+#include - - #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 */ - -- cgit v1.2.3