--- /dev/null	2013-04-25 23:48:55.724000051 +0200
+++ b/target/linux/brcm2708/patches-3.3/0600-rpi-patches-999b9c7a-4cdeb7b0.patch	2013-04-25 08:18:49.000000000 +0200
@@ -0,0 +1,7644 @@
+--- linux-3.3.8/arch/arm/mach-bcm2708/bcm2708.c.orig	2012-08-15 14:57:56.940560493 -0400
++++ linux-3.3.8/arch/arm/mach-bcm2708/bcm2708.c	2012-08-15 14:58:13.392818827 -0400
+@@ -23,6 +23,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
++#include <linux/sysdev.h>
+ #include <linux/interrupt.h>
+ #include <linux/amba/bus.h>
+ #include <linux/amba/clcd.h>
+From d0735c7d129d35bd91ba1c2c5b5a5201ed4a6c37 Mon Sep 17 00:00:00 2001
+From: Arne Fitzenreiter <arne.fitzenreiter@ipfire.org>
+Date: Wed, 6 Jun 2012 08:02:10 +0200
+Subject: [PATCH 1/2] bcm2835-ctl: fix alsamixer control.
+
+alsamixer read the volume for the screen controller so we had to
+scale the chipvol back to db for reading.
+---
+ sound/arm/bcm2835-ctl.c |   22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c
+index c0546e35..828a820 100755
+--- a/sound/arm/bcm2835-ctl.c
++++ b/sound/arm/bcm2835-ctl.c
+@@ -33,6 +33,19 @@
+ 
+ #include "bcm2835.h"
+ 
++
++/* functions to convert alsa to chip volume and back. */
++int alsa2chip(int vol)
++{
++	return -((vol << 8) / 100);
++}
++
++int chip2alsa(int vol)
++{
++	return -((vol * 100) >> 8);
++}
++
++
+ static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
+ 				struct snd_ctl_elem_info *uinfo)
+ {
+@@ -64,7 +77,7 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol,
+ 	BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK));
+ 
+ 	if (kcontrol->private_value == PCM_PLAYBACK_VOLUME)
+-		ucontrol->value.integer.value[0] = chip->volume;
++		ucontrol->value.integer.value[0] = chip2alsa(chip->volume);
+ 	else if (kcontrol->private_value == PCM_PLAYBACK_MUTE)
+ 		ucontrol->value.integer.value[0] = chip->mute;
+ 	else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE)
+@@ -85,13 +98,10 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
+ 			changed = 1;
+ 		}
+ 		if (changed
+-		    || (ucontrol->value.integer.value[0] != chip->volume)) {
+-			int atten;
++		    || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) {
+ 
+-			chip->volume = ucontrol->value.integer.value[0];
++			chip->volume = alsa2chip(ucontrol->value.integer.value[0]);
+ 			changed = 1;
+-			atten = -((chip->volume << 8) / 100);
+-			chip->volume = atten;
+ 		}
+ 
+ 	} else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
+-- 
+1.7.10
+
+
+From 829da61c0229c0734a109339f5de308bf8205bf6 Mon Sep 17 00:00:00 2001
+From: Arne Fitzenreiter <arne.fitzenreiter@ipfire.org>
+Date: Wed, 6 Jun 2012 08:06:15 +0200
+Subject: [PATCH 2/2] bcm2835-ctl: limit maximal volume to 4db.
+
+it makes no sense to set 23.04db as maximum volume since around 3db it start to cliping. So with 4db the alsamixer is much better to control. (86% is 0db)
+---
+ sound/arm/bcm2835-ctl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c
+index 828a820..f901ddd 100755
+--- a/sound/arm/bcm2835-ctl.c
++++ b/sound/arm/bcm2835-ctl.c
+@@ -53,7 +53,7 @@ static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ 		uinfo->count = 1;
+ 		uinfo->value.integer.min = -10240;
+-		uinfo->value.integer.max = 2303;
++		uinfo->value.integer.max = 400;      /* 2303 */
+ 	} else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ 		uinfo->count = 1;
+-- 
+1.7.10
+
+From d64b84ca8c171596b68bf125d266c84306ac421c Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Mon, 4 Jun 2012 04:27:48 +0200
+Subject: [PATCH 1/5] sdhci-bcm2708: speed up DMA sync
+
+Experiments show that it doesn't really take that long to sync, so we
+can reduce the poll interval slightly. Might improve performance a bit.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 7136998..9aebdfb 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -907,7 +907,7 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+ 		while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE) 
+ 			& state_mask) && --timeout > 0)
+ 		{
+-			udelay(100);
++			udelay(30);
+ 			continue;
+ 		}
+ 		if (timeout <= 0)
+-- 
+1.7.10
+
+
+From 9f144964006fb10db9436c5982c26d0ee9d8ec32 Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Mon, 11 Jun 2012 18:52:04 +0200
+Subject: [PATCH 2/5] sdhci-bcm2708: remove custom clock handling
+
+The custom clock handling code is redundant and buggy. The MMC/SDHCI
+subsystem does a better job than it, so remove it for good.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |   65 +-------------------------------------
+ 1 file changed, 1 insertion(+), 64 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 9aebdfb..c964911 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -359,68 +359,9 @@ void sdhci_bcm2708_writeb(struct sdhci_host *host, u8 val, int reg)
+ 
+ static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host)
+ {
+-	return 20000000;	// this value is in Hz (20MHz)
++	return BCM2708_EMMC_CLOCK_FREQ;
+ }
+ 
+-static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host)
+-{
+-	if(host->clock)
+-		return (host->clock / 1000);		// this value is in kHz (100MHz)
+-	else
+-		return (sdhci_bcm2708_get_max_clock(host) / 1000);
+-}
+-
+-static void sdhci_bcm2708_set_clock(struct sdhci_host *host, unsigned int clock)
+-{
+-	int div = 0;
+-	u16 clk = 0;
+-	unsigned long timeout;
+-
+-        if (clock == host->clock)
+-                return;
+-
+-        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+-
+-        if (clock == 0)
+-                goto out;
+-
+-	if (BCM2708_EMMC_CLOCK_FREQ <= clock)
+-		div = 1;
+-	else {
+-		for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
+-			if ((BCM2708_EMMC_CLOCK_FREQ / div) <= clock)
+-				break;
+-		}
+-	}
+-
+-        DBG( "desired SD clock: %d, actual: %d\n",
+-                clock, BCM2708_EMMC_CLOCK_FREQ / div);
+-
+-	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
+-	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
+-		<< SDHCI_DIVIDER_HI_SHIFT;
+-	clk |= SDHCI_CLOCK_INT_EN;
+-
+-	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+-
+-        timeout = 20;
+-        while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+-                        & SDHCI_CLOCK_INT_STABLE)) {
+-                if (timeout == 0) {
+-			printk(KERN_ERR "%s: Internal clock never "
+-				"stabilised.\n", mmc_hostname(host->mmc));
+-                        return;
+-                }
+-                timeout--;
+-                mdelay(1);
+-        }
+-
+-        clk |= SDHCI_CLOCK_CARD_EN;
+-        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+-out:
+-        host->clock = clock;
+- }
+-
+ /*****************************************************************************\
+  *									     *
+  * DMA Operation							     *
+@@ -1307,11 +1248,7 @@ static unsigned int sdhci_bcm2708_missing_status(struct sdhci_host *host)
+ #else
+ #error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set
+ #endif
+-	//.enable_dma = NULL,
+-	.set_clock = sdhci_bcm2708_set_clock,
+ 	.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,
+-- 
+1.7.10
+
+
+From 7a6fba9809c8d3a7fb1b2d0c40e0eae335127a6a Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Mon, 11 Jun 2012 18:53:59 +0200
+Subject: [PATCH 3/5] sdhci-bcm2708: add additional quirks
+
+Some additional quirks are needed for correct operation.
+There's no SDHCI capabilities register documented, and it always reads
+zero, so add SDHCI_QUIRK_MISSING_CAPS. Apparently
+SDHCI_QUIRK_NO_HISPD_BIT is needed for many cards to work correctly in
+high-speed mode, so add it as well.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index c964911..16c918b 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -1311,7 +1311,9 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+ 	host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+ 		       SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+ 		       SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+-		       SDHCI_QUIRK_NONSTANDARD_CLOCK;
++               SDHCI_QUIRK_MISSING_CAPS |
++               SDHCI_QUIRK_NO_HISPD_BIT;
++
+ #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+ 	host->flags = SDHCI_USE_PLATDMA;
+ #endif
+-- 
+1.7.10
+
+
+From 420806e5adabd8343b362b4a1d7f64f22b394dbf Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Mon, 11 Jun 2012 18:57:13 +0200
+Subject: [PATCH 4/5] sdhci-bcm2708: add allow_highspeed parameter
+
+Add a parameter to disable high-speed mode for the few cards that
+still might have problems. High-speed mode is enabled by default.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 16c918b..a8aae16 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -135,6 +135,8 @@ static inline unsigned long int since_ns(hptime_t t)
+ 	return (unsigned long)((hptime() - t) * HPTIME_CLK_NS);
+ }
+ 
++static bool allow_highspeed = 1;
++
+ #if 0
+ static void hptime_test(void)
+ {
+@@ -1381,7 +1383,8 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+ 	    host_priv->dma_chan, host_priv->dma_chan_base,
+ 	    host_priv->dma_irq);
+ 
+-	host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
++    if (allow_highspeed)
++        host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+ #endif
+ 
+ 	ret = sdhci_add_host(host);
+@@ -1487,8 +1490,12 @@ static void __exit sdhci_drv_exit(void)
+ module_init(sdhci_drv_init);
+ module_exit(sdhci_drv_exit);
+ 
++module_param(allow_highspeed, bool, 0444);
++
+ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+ MODULE_AUTHOR("Broadcom <info@broadcom.com>");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("platform:"DRIVER_NAME);
+ 
++MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
++
+-- 
+1.7.10
+
+
+From f1a14aea8494dc019eb145a08f2f26022efd7731 Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Mon, 11 Jun 2012 18:58:40 +0200
+Subject: [PATCH 5/5] sdhci-bcm2708: assume 50 MHz eMMC clock
+
+80 MHz clock isnt't suited well to be dividable to get SD clocks of 25
+MHz (default mode) or 50 MHz (high speed mode). 50 MHz are perfect to
+drive the SD interface at ideal frequencies.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index a8aae16..64b956b 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -74,7 +74,7 @@
+ #define BCM2708_SDHCI_SLEEP_TIMEOUT 1000   /* msecs */
+ 
+ /* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */
+-#define BCM2708_EMMC_CLOCK_FREQ 80000000
++#define BCM2708_EMMC_CLOCK_FREQ 50000000
+ 
+ #define POWER_OFF 0
+ #define POWER_LAZY_OFF 1
+-- 
+1.7.10
+
+From 598d87246fde30287f0c423cc761e26600dd7c17 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 16 Jun 2012 22:31:55 +0100
+Subject: [PATCH 1/4] Allow emmc clock to be specified as command line
+ parameter
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 64b956b..3beb323 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -136,6 +136,7 @@ static inline unsigned long int since_ns(hptime_t t)
+ }
+ 
+ static bool allow_highspeed = 1;
++static bool emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
+ 
+ #if 0
+ static void hptime_test(void)
+@@ -361,7 +362,7 @@ void sdhci_bcm2708_writeb(struct sdhci_host *host, u8 val, int reg)
+ 
+ static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host)
+ {
+-	return BCM2708_EMMC_CLOCK_FREQ;
++	return emmc_clock_freq;
+ }
+ 
+ /*****************************************************************************\
+@@ -1491,6 +1492,7 @@ static void __exit sdhci_drv_exit(void)
+ module_exit(sdhci_drv_exit);
+ 
+ module_param(allow_highspeed, bool, 0444);
++module_param(emmc_clock_freq, bool, 0444);
+ 
+ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+ MODULE_AUTHOR("Broadcom <info@broadcom.com>");
+@@ -1498,4 +1500,6 @@ static void __exit sdhci_drv_exit(void)
+ MODULE_ALIAS("platform:"DRIVER_NAME);
+ 
+ MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
++MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
++
+ 
+-- 
+1.7.10
+
+
+From 682bc2a568462089005c32aed2a0d7a2faa59cf8 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 16 Jun 2012 22:35:38 +0100
+Subject: [PATCH 2/4] sdhci-bcm2708: raise DMA sync timeout
+
+Commit d64b84c by accident reduced the maximum overall DMA sync
+timeout. The maximum overall timeout was reduced from 100ms to 30ms,
+which isn't enough for many cards. Increase it to 150ms, just to be
+extra safe. According to commit 872a8ff in the MMC subsystem, some
+cards require crazy long timeouts (3s), but as we're busy-waiting,
+and shouldn't delay for such a long time, let's hope 150ms will be
+enough for most cards.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 3beb323..85bf3ce 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -840,7 +840,7 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+ 		   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=1000;
++		int timeout=5000;
+ 
+ 		DBG("PDMA over - sync card\n");
+ 		if (data->flags & MMC_DATA_READ)
+-- 
+1.7.10
+
+
+From 1ccd0107253e1dd14ee78a1e3eb0ed723d8fa595 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 16 Jun 2012 23:26:28 +0100
+Subject: [PATCH 3/4] Fix bool/int error
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 85bf3ce..eedd724 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -1492,7 +1492,7 @@ static void __exit sdhci_drv_exit(void)
+ module_exit(sdhci_drv_exit);
+ 
+ module_param(allow_highspeed, bool, 0444);
+-module_param(emmc_clock_freq, bool, 0444);
++module_param(emmc_clock_freq, int, 0444);
+ 
+ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+ MODULE_AUTHOR("Broadcom <info@broadcom.com>");
+-- 
+1.7.10
+
+
+From 6273fcbf72461c2bd3757a8b6c9ed175955b25c1 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 16 Jun 2012 23:46:08 +0100
+Subject: [PATCH 4/4] Fix bool/int error, part 2
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index eedd724..13abbc9 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -136,7 +136,7 @@ static inline unsigned long int since_ns(hptime_t t)
+ }
+ 
+ static bool allow_highspeed = 1;
+-static bool emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
++static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
+ 
+ #if 0
+ static void hptime_test(void)
+-- 
+1.7.10
+
+From 3fc65f9f291fb19cad434968a4a0f66ab749e637 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sun, 17 Jun 2012 00:14:54 +0100
+Subject: [PATCH] Explicitly set usb host channels to 8, as in the spec
+
+---
+ drivers/usb/host/dwc_otg/dwc_otg_core_if.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_core_if.h b/drivers/usb/host/dwc_otg/dwc_otg_core_if.h
+index 4a78b03..25aae5e 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_core_if.h
++++ b/drivers/usb/host/dwc_otg/dwc_otg_core_if.h
+@@ -267,7 +267,8 @@ extern int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if,
+ extern int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if,
+ 					   int32_t val);
+ extern int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if);
+-#define dwc_param_host_channels_default 12
++//#define dwc_param_host_channels_default 12
++#define dwc_param_host_channels_default 8// Broadcom BCM2708
+ 
+ /** The number of endpoints in addition to EP0 available for device
+  * mode operations.
+-- 
+1.7.10
+
+From d2743760a691469cebfa3bc23cedb62c38388380 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 21 Jun 2012 01:31:08 +0100
+Subject: [PATCH 1/3] Remove silence method, and use atomic flags for kmalloc
+
+---
+ sound/arm/bcm2835-pcm.c   |   24 ------------------------
+ sound/arm/bcm2835-vchiq.c |    4 ++--
+ 2 files changed, 2 insertions(+), 26 deletions(-)
+
+diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c
+index 40a9fb5..ff3eb4e 100755
+--- a/sound/arm/bcm2835-pcm.c
++++ b/sound/arm/bcm2835-pcm.c
+@@ -345,29 +345,6 @@ static int snd_bcm2835_pcm_copy(struct snd_pcm_substream *substream,
+ 	return ret;
+ }
+ 
+-static int snd_bcm2835_pcm_silence(struct snd_pcm_substream *substream,
+-				   int channel, snd_pcm_uframes_t post,
+-				   snd_pcm_uframes_t count)
+-{
+-	int ret;
+-	struct snd_pcm_runtime *runtime = substream->runtime;
+-	bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
+-
+-	audio_info(" .. IN\n");
+-	audio_debug("silence....... (%d) hwptr=%d appl=%d pos=%d\n",
+-		      frames_to_bytes(runtime, count), frames_to_bytes(runtime,
+-								       runtime->
+-								       status->
+-								       hw_ptr),
+-		      frames_to_bytes(runtime, runtime->control->appl_ptr),
+-		      alsa_stream->pos);
+-	ret =
+-	    bcm2835_audio_write(alsa_stream, frames_to_bytes(runtime, count),
+-				NULL);
+-	audio_info(" .. OUT\n");
+-	return ret;
+-}
+-
+ static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
+ 				     unsigned int cmd, void *arg)
+ {
+@@ -388,7 +365,6 @@ static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
+ 	.trigger = snd_bcm2835_pcm_trigger,
+ 	.pointer = snd_bcm2835_pcm_pointer,
+ 	.copy = snd_bcm2835_pcm_copy,
+-	.silence = snd_bcm2835_pcm_silence,
+ };
+ 
+ /* create a pcm device */
+diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c
+index 820063a..23c0aa3 100755
+--- a/sound/arm/bcm2835-vchiq.c
++++ b/sound/arm/bcm2835-vchiq.c
+@@ -102,7 +102,7 @@ int bcm2835_audio_start(bcm2835_alsa_stream_t * alsa_stream)
+ 	int ret = -1;
+ 	LOG_DBG(" .. IN\n");
+ 	if (alsa_stream->my_wq) {
+-		my_work_t *work = kmalloc(sizeof(my_work_t), GFP_KERNEL);
++		my_work_t *work = kmalloc(sizeof(my_work_t), GFP_ATOMIC);
+ 		/* Queue some work (item 1) */
+ 		if (work) {
+ 			INIT_WORK((struct work_struct *)work, my_wq_function);
+@@ -123,7 +123,7 @@ int bcm2835_audio_stop(bcm2835_alsa_stream_t * alsa_stream)
+ 	int ret = -1;
+ 	LOG_DBG(" .. IN\n");
+ 	if (alsa_stream->my_wq) {
+-		my_work_t *work = kmalloc(sizeof(my_work_t), GFP_KERNEL);
++		my_work_t *work = kmalloc(sizeof(my_work_t), GFP_ATOMIC);
+ 		/* Queue some work (item 1) */
+ 		if (work) {
+ 			INIT_WORK((struct work_struct *)work, my_wq_function);
+-- 
+1.7.10
+
+
+From 4cf265f1432ae31c8c2ceb95c6a41321c3ee2604 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 22 Jun 2012 12:55:39 +0100
+Subject: [PATCH 2/3] Fix unintended line swap that cause cause memory leak in
+ USB driver
+
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+index 2a3b689..970b065 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+@@ -764,8 +764,8 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ 	if(urb->hcpriv != NULL) {
+ 		dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, (dwc_otg_hcd_urb_t *)urb->hcpriv);
+ 
+-		urb->hcpriv = NULL;
+ 		dwc_free(urb->hcpriv);
++		urb->hcpriv = NULL;
+ 	}
+ 
+ 	/* Higher layer software sets URB status. */
+-- 
+1.7.10
+
+
+From e8b8f8db6d6bbe0784c7d5719259c57c9d6608f5 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 22 Jun 2012 12:57:42 +0100
+Subject: [PATCH 3/3] Use ndelay rather than udelay. Thanks lb
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 13abbc9..1d8751c 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -255,14 +255,14 @@ static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg)
+ 		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);
++			ndelay(ns_2clk);
+ 		} 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);
++				ndelay(ns_2clk - ns_wait);
+ 		}
+ 		last_write_hpt = now;
+ 	}
+@@ -278,13 +278,13 @@ static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg)
+ 		ier &= ~SDHCI_INT_DATA_TIMEOUT;
+ 		writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+ 		timeout_disabled = true;
+-		udelay((ns_2clk+1000-1)/1000);
++		ndelay(ns_2clk);
+ 	} else if (timeout_disabled) {
+ 		ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE);
+ 		ier |= SDHCI_INT_DATA_TIMEOUT;
+ 		writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+ 		timeout_disabled = false;
+-		udelay((ns_2clk+1000-1)/1000);
++		ndelay(ns_2clk);
+ 	}
+ #endif
+ 	writel(val, host->ioaddr + reg);
+-- 
+1.7.10
+
+From f679f0534867d64a3672108d73bed5d349728f73 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 26 Jun 2012 15:54:11 +0100
+Subject: [PATCH] Fixed issue with some keyboards giving too much data 
+ resulting in overrun of the input buffer and memory 
+ corruption causing an OOPS. We should be checking for the 
+ fact that we might get more data than we want. Thanks
+ Naren.
+
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c  |    4 ++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c  |    6 +++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c |   13 ++++++++++---
+ 3 files changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
+index 21d1ab1..01c4780 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
+@@ -886,7 +886,7 @@ uint8_t update_non_isoc_urb_state_ddma(dwc_otg_hcd_t * hcd,
+ 	if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL) {
+ 	    if (qtd->control_phase == DWC_OTG_CONTROL_DATA) {
+ 		urb->actual_length += n_bytes - remain;
+-		if (remain || urb->actual_length == urb->length) {
++		if (remain || urb->actual_length >= urb->length) {
+ 			/* 
+ 			 * For Control Data stage do not set urb->status=0 to prevent
+ 			 * URB callback. Set it when Status phase done. See below.
+@@ -905,7 +905,7 @@ uint8_t update_non_isoc_urb_state_ddma(dwc_otg_hcd_t * hcd,
+ 	else { 
+ 	    /* BULK and INTR */
+ 	    urb->actual_length += n_bytes - remain;
+-	    if (remain || urb->actual_length == urb->length) {
++	    if (remain || urb->actual_length >= urb->length) {
+ 		urb->status = 0;
+ 		*xfer_done = 1;
+ 	    }
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+index 6e4bc60..86fee99 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+@@ -567,7 +567,7 @@ static int update_urb_state_xfer_comp(dwc_hc_t * hc,
+ 	   (urb->flags & URB_SEND_ZERO_PACKET) && (urb->actual_length == urb->length) &&
+ 	   !(urb->length % hc->max_packet)) {
+ 		xfer_done = 0;
+-	} else if (short_read || urb->actual_length == urb->length) {
++	} else if (short_read || urb->actual_length >= urb->length) {
+ 		xfer_done = 1;
+ 		urb->status = 0;
+ 	}
+@@ -1876,10 +1876,10 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t * hcd,
+ 	} else if (hcint.b.xacterr && !hcd->core_if->dma_desc_enable) {
+ 		if (out_nak_enh) {
+ 			if (hcint.b.nyet || hcint.b.nak || hcint.b.ack) {
+-				DWC_DEBUG("XactErr with NYET/NAK/ACK\n");
++				DWC_DEBUGPL(DBG_HCD, "XactErr with NYET/NAK/ACK\n");
+ 				qtd->error_count = 0;
+ 			} else {
+-				DWC_DEBUG("XactErr without NYET/NAK/ACK\n");
++				DWC_DEBUGPL(DBG_HCD, "XactErr without NYET/NAK/ACK\n");
+ 			}
+ 		}
+ 
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+index 970b065..05fd421 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+@@ -190,6 +190,7 @@ static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
+ 		     uint32_t * port_addr)
+ {
+    struct urb *urb = (struct urb *)urb_handle;
++   struct usb_bus *bus;
+ #if 1 //GRAYG - temporary
+    if (NULL == urb_handle)
+       DWC_ERROR("**** %s - NULL URB handle\n", __func__);//GRAYG
+@@ -206,12 +207,18 @@ static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
+                 *hub_addr = 0; //GRAYG
+                 // we probably shouldn't have a transaction translator if
+                 // there's no associated hub?
+-        } else
+-                *hub_addr = urb->dev->tt->hub->devnum;
++        } else {
++		bus = hcd_to_bus(dwc_otg_hcd_to_hcd(hcd));
++		if (urb->dev->tt->hub == bus->root_hub)
++			*hub_addr = 0;
++		else
++			*hub_addr = urb->dev->tt->hub->devnum;
++	}
++	*port_addr = urb->dev->tt->multi ? urb->dev->ttport : 1;
+    } else {
+         *hub_addr = 0;
++	*port_addr = urb->dev->ttport;
+    }
+-   *port_addr = urb->dev->ttport;
+    return 0;
+ }
+ 
+-- 
+1.7.10
+
+From f3b653ec9e4961fd983fa1efe833c203c1701f15 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 30 Jun 2012 11:47:45 +0100
+Subject: [PATCH 1/4] Add interrupt support to gpio driver. Thanks Mrkva
+
+---
+ arch/arm/mach-bcm2708/bcm2708_gpio.c      |  264 +++++++++++++++--------------
+ arch/arm/mach-bcm2708/include/mach/gpio.h |   17 +-
+ arch/arm/mach-bcm2708/include/mach/irqs.h |    8 +-
+ 3 files changed, 154 insertions(+), 135 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c
+index 59df912..7f8a6db 100644
+--- a/arch/arm/mach-bcm2708/bcm2708_gpio.c
++++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c
+@@ -14,6 +14,7 @@
+ #include <linux/list.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
++#include <linux/interrupt.h>
+ #include <linux/slab.h>
+ #include <linux/gpio.h>
+ #include <linux/platform_device.h>
+@@ -22,7 +23,7 @@
+ 
+ #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
+ #define DRIVER_NAME BCM_GPIO_DRIVER_NAME
+-#define BCM_GPIO_USE_IRQ 0
++#define BCM_GPIO_USE_IRQ 1
+ 
+ #define GPIOFSEL(x)  (0x00+(x)*4)
+ #define GPIOSET(x)   (0x1c+(x)*4)
+@@ -38,40 +39,35 @@
+ #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, };
++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 */
+-
++static DEFINE_SPINLOCK(lock);	/* GPIO 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;
++	struct list_head list;
++	void __iomem *base;
++	struct gpio_chip gc;
++	unsigned long rising;
++	unsigned long falling;
+ };
+ 
+-static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, int function)
++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;
++	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)
+@@ -81,7 +77,7 @@ static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, int funct
+ 
+ 	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
+ 	gpiodir &= ~(7 << gpio_field_offset);
+-        gpiodir |= function << 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));
+@@ -89,157 +85,177 @@ static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, int funct
+ 	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)
++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);
++	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;
++	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));
++	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);
++	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);
++	unsigned gpio_bank = offset / 32;
++	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
+ //printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value);
+ 	if (offset >= ARCH_NR_GPIOS)
+ 		return;
+ 	if (value)
+-	        writel(1<<gpio_field_offset, gpio->base + GPIOSET(gpio_bank));
++		writel(1 << gpio_field_offset, gpio->base + GPIOSET(gpio_bank));
+ 	else
+-	        writel(1<<gpio_field_offset, gpio->base + GPIOCLR(gpio_bank));
++		writel(1 << gpio_field_offset, gpio->base + GPIOCLR(gpio_bank));
+ }
+ 
+-/*
++/*************************************************************************************************************************
+  * bcm2708 GPIO IRQ
+  */
+ 
+ #if BCM_GPIO_USE_IRQ
+-static void bcm2708_irq_disable(unsigned irq)
+-{
+-	struct bcm2708_gpio *chip = get_irq_chip_data(irq);
+-	//int offset = irq - gpio->irq_base;
+-	unsigned long flags;
+ 
+-	spin_lock_irqsave(&chip->irq_lock, flags);
+-        // disable gpio interrupts here
+-	spin_unlock_irqrestore(&chip->irq_lock, flags);
+-}
++#define IRQ_TO_GPIO(x)	irq_to_gpio(x)
+ 
+-static void bcm2708_irq_enable(unsigned irq)
++static int bcm2708_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+ {
+-	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);
++	return gpio_to_irq(gpio);
+ }
+ 
+-static int bcm2708_irq_type(unsigned irq, unsigned trigger)
++static int bcm2708_gpio_irq_set_type(struct irq_data *d, unsigned type)
+ {
+-	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;
++	unsigned irq = d->irq;
++	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
+ 
+-	if (offset < 0 || offset >= ARCH_NR_GPIOS)
++	if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ 		return -EINVAL;
+ 
+-	spin_lock_irqsave(&chip->irq_lock, flags);
++	if (type & IRQ_TYPE_EDGE_RISING) {
++		gpio->rising |= (1 << IRQ_TO_GPIO(irq));
++	} else {
++		gpio->rising &= ~(1 << IRQ_TO_GPIO(irq));
++	}
+ 
+-	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 (type & IRQ_TYPE_EDGE_FALLING) {
++		gpio->falling |= (1 << IRQ_TO_GPIO(irq));
++	} else {
++		gpio->falling &= ~(1 << IRQ_TO_GPIO(irq));
++	}
++	return 0;
++}
+ 
+-	if (trigger & (IRQ_TYPE_EDGE_RISING))
+-		gpioren |=  (1<<gpio_field_offset);
+-	else
+-		gpioren &= ~(1<<gpio_field_offset);
+-	if (trigger & (IRQ_TYPE_EDGE_FALLING))
+-		gpiofen |=  (1<<gpio_field_offset);
+-	else
+-		gpiofen &= ~(1<<gpio_field_offset);
+-	if (trigger & (IRQ_TYPE_LEVEL_HIGH))
+-		gpiohen |=  (1<<gpio_field_offset);
+-	else
+-		gpiohen &= ~(1<<gpio_field_offset);
+-	if (trigger & (IRQ_TYPE_LEVEL_LOW))
+-		gpiolen |=  (1<<gpio_field_offset);
+-	else
+-		gpiolen &= ~(1<<gpio_field_offset);
++static void bcm2708_gpio_irq_mask(struct irq_data *d)
++{
++	unsigned irq = d->irq;
++	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
++	unsigned gn = IRQ_TO_GPIO(irq);
++	unsigned gb = gn / 32;
++	unsigned long rising = readl(gpio->base + GPIOREN(gb));
++	unsigned long falling = readl(gpio->base + GPIOFEN(gb));
++
++	writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb));
++	writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
++}
+ 
+-	writel(gpioren, chip->base + GPIOREN(gpio_bank));
+-	writel(gpiofen, chip->base + GPIOFEN(gpio_bank));
+-	writel(gpiohen, chip->base + GPIOHEN(gpio_bank));
+-	writel(gpiolen, chip->base + GPIOLEN(gpio_bank));
++static void bcm2708_gpio_irq_unmask(struct irq_data *d)
++{
++	unsigned irq = d->irq;
++	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
++	unsigned gn = IRQ_TO_GPIO(irq);
++	unsigned gb = gn / 32;
++	unsigned long rising = readl(gpio->base + GPIOREN(gb));
++	unsigned long falling = readl(gpio->base + GPIOFEN(gb));
+ 
+-	spin_unlock_irqrestore(&chip->irq_lock, flags);
++	gn = gn % 32;
+ 
+-	return 0;
++	writel(1 << gn, gpio->base + GPIOEDS(gb));
++
++	if (gpio->rising & (1 << gn)) {
++		writel(rising | (1 << gn), gpio->base + GPIOREN(gb));
++	} else {
++		writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb));
++	}
++
++	if (gpio->falling & (1 << gn)) {
++		writel(falling | (1 << gn), gpio->base + GPIOFEN(gb));
++	} else {
++		writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
++	}
+ }
+ 
+ static struct irq_chip bcm2708_irqchip = {
+-	.name		= "GPIO",
+-	.enable		= bcm2708_irq_enable,
+-	.disable	= bcm2708_irq_disable,
+-	.set_type	= bcm2708_irq_type,
++	.name = "GPIO",
++	.irq_enable = bcm2708_gpio_irq_unmask,
++	.irq_disable = bcm2708_gpio_irq_mask,
++	.irq_unmask = bcm2708_gpio_irq_unmask,
++	.irq_mask = bcm2708_gpio_irq_mask,
++	.irq_set_type = bcm2708_gpio_irq_set_type,
+ };
+ 
+-static void bcm2708_irq_handler(unsigned irq, struct irq_desc *desc)
++static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id)
+ {
+-	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));
++	unsigned long edsr;
++	unsigned bank;
++	int i;
++	unsigned gpio;
++	for (bank = 0; bank <= 1; bank++) {
++		edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank));
++		for_each_set_bit(i, &edsr, 32) {
++			gpio = i + bank * 32;
++			generic_handle_irq(gpio_to_irq(gpio));
+ 		}
++		writel(0xffffffff, __io_address(GPIO_BASE) + GPIOEDS(bank));
+ 	}
+-	desc->chip->unmask(irq);
++	return IRQ_HANDLED;
+ }
+-#endif /* #if BCM_GPIO_USE_IRQ */
++
++static struct irqaction bcm2708_gpio_irq = {
++	.name = "BCM2708 GPIO catchall handler",
++	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
++	.handler = bcm2708_gpio_interrupt,
++};
++
++static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
++{
++	unsigned irq;
++
++	ucb->gc.to_irq = bcm2708_gpio_to_irq;
++
++	for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) {
++		irq_set_chip_data(irq, ucb);
++		irq_set_chip(irq, &bcm2708_irqchip);
++		set_irq_flags(irq, IRQF_VALID);
++	}
++	setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq);
++}
++
++#else
++
++static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
++{
++}
++
++#endif /* #if BCM_GPIO_USE_IRQ ***************************************************************************************************************** */
+ 
+ static int bcm2708_gpio_probe(struct platform_device *dev)
+ {
+@@ -247,7 +263,7 @@ static int bcm2708_gpio_probe(struct platform_device *dev)
+ 	struct resource *res;
+ 	int err = 0;
+ 
+-        printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev);
++	printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev);
+ 
+ 	ucb = kzalloc(sizeof(*ucb), GFP_KERNEL);
+ 	if (NULL == ucb) {
+@@ -260,7 +276,7 @@ static int bcm2708_gpio_probe(struct platform_device *dev)
+ 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ 
+ 	platform_set_drvdata(dev, ucb);
+-        ucb->base = __io_address(GPIO_BASE);
++	ucb->base = __io_address(GPIO_BASE);
+ 
+ 	ucb->gc.label = "bcm2708_gpio";
+ 	ucb->gc.base = 0;
+@@ -273,6 +289,8 @@ static int bcm2708_gpio_probe(struct platform_device *dev)
+ 	ucb->gc.set = bcm2708_gpio_set;
+ 	ucb->gc.can_sleep = 0;
+ 
++	bcm2708_gpio_irq_init(ucb);
++
+ 	err = gpiochip_add(&ucb->gc);
+ 	if (err)
+ 		goto err;
+@@ -298,11 +316,10 @@ static int bcm2708_gpio_remove(struct platform_device *dev)
+ }
+ 
+ static struct platform_driver bcm2708_gpio_driver = {
+-	.probe	= bcm2708_gpio_probe,
+-	.remove	= bcm2708_gpio_remove,
+-	.driver	= {
+-		.name	= "bcm2708_gpio"
+-	},
++	.probe = bcm2708_gpio_probe,
++	.remove = bcm2708_gpio_remove,
++	.driver = {
++		   .name = "bcm2708_gpio"},
+ };
+ 
+ static int __init bcm2708_gpio_init(void)
+@@ -320,4 +337,3 @@ static void __exit bcm2708_gpio_exit(void)
+ 
+ MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver");
+ MODULE_LICENSE("GPL");
+-
+diff --git a/arch/arm/mach-bcm2708/include/mach/gpio.h b/arch/arm/mach-bcm2708/include/mach/gpio.h
+index 526004f..90a7ba2 100644
+--- a/arch/arm/mach-bcm2708/include/mach/gpio.h
++++ b/arch/arm/mach-bcm2708/include/mach/gpio.h
+@@ -12,7 +12,8 @@
+ #define ARCH_NR_GPIOS 54 // number of gpio lines
+ 
+ #include <asm-generic/gpio.h>
+-
++#include <mach/platform.h>
++#include <mach/irqs.h>
+ 
+ #ifdef CONFIG_GPIOLIB
+ 
+@@ -31,18 +32,14 @@ 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;
++static inline unsigned irq_to_gpio(unsigned irq) {
++	return (irq-GPIO_IRQ_START);
+ }
+ 
++static inline unsigned gpio_to_irq(unsigned gpio) {
++	return GPIO_IRQ_START+gpio;
++}
+ #endif /* CONFIG_GPIOLIB */
+ 
+ #endif
+diff --git a/arch/arm/mach-bcm2708/include/mach/irqs.h b/arch/arm/mach-bcm2708/include/mach/irqs.h
+index f59d474..e8bb068 100644
+--- a/arch/arm/mach-bcm2708/include/mach/irqs.h
++++ b/arch/arm/mach-bcm2708/include/mach/irqs.h
+@@ -185,6 +185,12 @@
+ #define FIQ_PENDING1          INT_PENDING1
+ #define FIQ_PENDING2          INT_PENDING2
+ 
+-#define NR_IRQS			      (64 + 21)
++#define HARD_IRQS	      (64 + 21)
++#define GPIO_IRQ_START	      HARD_IRQS
++
++#define GPIO_IRQS	      32*5
++
++#define NR_IRQS		      HARD_IRQS+GPIO_IRQS
++
+ 
+ #endif /* _BCM2708_IRQS_H_ */
+-- 
+1.7.10
+
+
+From 4f574f96955a5f918be460b1b9afe60ad405ba00 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 30 Jun 2012 16:07:18 +0100
+Subject: [PATCH 2/4] Add a pm_power_off function that resets us, and
+ indicates to bootcode.bin not to reboot us. Should
+ allow a lower power 'off' state
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c               |   14 ++++++++++++++
+ arch/arm/mach-bcm2708/include/mach/platform.h |   16 +++++++++++++---
+ 2 files changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index fa02a1a..17c6dbd 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -53,6 +53,7 @@
+ #include <mach/timex.h>
+ #include <mach/dma.h>
+ #include <mach/vcio.h>
++#include <mach/system.h>
+ 
+ #include "bcm2708.h"
+ #include "armctrl.h"
+@@ -472,10 +473,23 @@ int __init bcm_register_device(struct platform_device *pdev)
+ 	return ret;
+ }
+ 
++/* We can't really power off, but if we do the normal reset scheme, and indicate to bootcode.bin not to reboot, then most of the chip will be powered off */
++static void bcm2708_power_off(void)
++{
++	/* we set the watchdog hard reset bit here to distinguish this reset from the normal (full) reset. bootcode.bin will not reboot after a hard reset */
++	uint32_t pm_rsts = readl(IO_ADDRESS(PM_RSTS));
++	pm_rsts = PM_PASSWORD | (pm_rsts & PM_RSTC_WRCFG_CLR) | PM_RSTS_HADWRH_SET;
++	writel(pm_rsts, IO_ADDRESS(PM_RSTS));
++	/* continue with normal reset mechanism */
++	arch_reset(0, "");
++}
++
+ void __init bcm2708_init(void)
+ {
+ 	int i;
+ 
++	pm_power_off = bcm2708_power_off;
++
+ 	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ 		clkdev_add(&lookups[i]);
+ 
+diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h
+index 5cb1caa..5afa0a7 100644
+--- a/arch/arm/mach-bcm2708/include/mach/platform.h
++++ b/arch/arm/mach-bcm2708/include/mach/platform.h
+@@ -191,6 +191,7 @@
+  * Watchdog
+  */
+ #define PM_RSTC			       (PM_BASE+0x1c)
++#define PM_RSTS			       (PM_BASE+0x20)
+ #define PM_WDOG			       (PM_BASE+0x24)
+ 
+ #define PM_WDOG_RESET                                         0000000000
+@@ -199,9 +200,18 @@
+ #define PM_RSTC_WRCFG_CLR              0xffffffcf
+ #define PM_RSTC_WRCFG_SET              0x00000030
+ #define PM_RSTC_WRCFG_FULL_RESET       0x00000020
+-#define PM_RSTC_RESET			0x00000102
+-
+-
++#define PM_RSTC_RESET                  0x00000102
++
++#define PM_RSTS_HADPOR_SET                                 0x00001000
++#define PM_RSTS_HADSRH_SET                                 0x00000400
++#define PM_RSTS_HADSRF_SET                                 0x00000200
++#define PM_RSTS_HADSRQ_SET                                 0x00000100
++#define PM_RSTS_HADWRH_SET                                 0x00000040
++#define PM_RSTS_HADWRF_SET                                 0x00000020
++#define PM_RSTS_HADWRQ_SET                                 0x00000010
++#define PM_RSTS_HADDRH_SET                                 0x00000004
++#define PM_RSTS_HADDRF_SET                                 0x00000002
++#define PM_RSTS_HADDRQ_SET                                 0x00000001
+ 
+ 
+ 
+-- 
+1.7.10
+
+
+From 14ad68cf4afc7acf14076f895b539d81cd9f32ab Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sun, 1 Jul 2012 12:09:52 +0100
+Subject: [PATCH 3/4] Store palette info where GPU can see it, so 8bpp modes
+ can work. Requires updated start.elf to work properly
+
+---
+ drivers/video/bcm2708_fb.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
+index 8d67e86..ec01655 100644
+--- a/drivers/video/bcm2708_fb.c
++++ b/drivers/video/bcm2708_fb.c
+@@ -48,6 +48,7 @@ struct fbinfo_s {
+ 	u32 xoffset, yoffset;
+ 	u32 base;
+ 	u32 screen_size;
++	u16 cmap[256];
+ };
+ 
+ struct bcm2708_fb {
+@@ -266,18 +267,31 @@ static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
+ 	return (val >> (16 - bf->length) & mask) << bf->offset;
+ }
+ 
++
+ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red,
+ 				unsigned int green, unsigned int blue,
+ 				unsigned int transp, struct fb_info *info)
+ {
+ 	struct bcm2708_fb *fb = to_bcm2708(info);
+ 
++	/*pr_info("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/
+ 	if (regno < 16)
+ 		fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
+ 		    convert_bitfield(blue, &fb->fb.var.blue) |
+ 		    convert_bitfield(green, &fb->fb.var.green) |
+ 		    convert_bitfield(red, &fb->fb.var.red);
+ 
++	if (regno < 256) {
++		/* blue [0:4], green [5:10], red [11:15] */
++		fb->info->cmap[regno] = ((red   >> (16-5)) & 0x1f) << 11 |
++					((green >> (16-6)) & 0x3f) << 5 |
++					((blue  >> (16-5)) & 0x1f) << 0;
++	}
++	/* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */
++        /* So just call it for what looks like the last colour in a list for now. */
++	if (regno == 15 || regno == 255)
++		bcm2708_fb_set_par(info);
++
+ 	return regno > 255;
+ }
+ 
+-- 
+1.7.10
+
+
+From c47ee9d4a48c1f3cc53a54e096ca0f7a3961ed9f Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 2 Jul 2012 20:34:38 +0100
+Subject: [PATCH 4/4] Avoid blanking console when not in palettised mode
+
+---
+ drivers/video/bcm2708_fb.c |   24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
+index ec01655..2b23be6 100644
+--- a/drivers/video/bcm2708_fb.c
++++ b/drivers/video/bcm2708_fb.c
+@@ -275,23 +275,23 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red,
+ 	struct bcm2708_fb *fb = to_bcm2708(info);
+ 
+ 	/*pr_info("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/
+-	if (regno < 16)
++	if (fb->fb.var.bits_per_pixel <= 8) {
++		if (regno < 256) {
++			/* blue [0:4], green [5:10], red [11:15] */
++			fb->info->cmap[regno] = ((red   >> (16-5)) & 0x1f) << 11 |
++						((green >> (16-6)) & 0x3f) << 5 |
++						((blue  >> (16-5)) & 0x1f) << 0;
++		}
++		/* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */
++		/* So just call it for what looks like the last colour in a list for now. */
++		if (regno == 15 || regno == 255)
++			bcm2708_fb_set_par(info);
++        } else if (regno < 16) {
+ 		fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
+ 		    convert_bitfield(blue, &fb->fb.var.blue) |
+ 		    convert_bitfield(green, &fb->fb.var.green) |
+ 		    convert_bitfield(red, &fb->fb.var.red);
+-
+-	if (regno < 256) {
+-		/* blue [0:4], green [5:10], red [11:15] */
+-		fb->info->cmap[regno] = ((red   >> (16-5)) & 0x1f) << 11 |
+-					((green >> (16-6)) & 0x3f) << 5 |
+-					((blue  >> (16-5)) & 0x1f) << 0;
+ 	}
+-	/* Hack: we need to tell GPU the palette has changed, but currently bcm2708_fb_set_par takes noticable time when called for every (256) colour */
+-        /* So just call it for what looks like the last colour in a list for now. */
+-	if (regno == 15 || regno == 255)
+-		bcm2708_fb_set_par(info);
+-
+ 	return regno > 255;
+ }
+ 
+-- 
+1.7.10
+
+From 68b4a993dc006f80b7d19e461fcecd8191c5b9a3 Mon Sep 17 00:00:00 2001
+From: Bryan Kemp <bryan@kempville.com>
+Date: Sat, 7 Jul 2012 16:24:07 -0500
+Subject: [PATCH 1/3] Updating dwc_otg driver to fix issue releasing pcm
+ stream see:
+ https://github.com/raspberrypi/firmware/issues/51
+
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c |   20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+index 6a89b1e..68664e5 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+@@ -70,6 +70,7 @@
+ #include "dwc_otg_hcd_if.h"
+ #include "dwc_otg_dbg.h"
+ #include "dwc_otg_driver.h"
++#include "dwc_otg_hcd.h"
+ 
+ /**
+  * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
+@@ -267,6 +268,7 @@ static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
+ static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
+ 		     dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
+ {
++	uint64_t flags;
+ 	struct urb *urb = (struct urb *)urb_handle;
+ 
+ #ifdef DEBUG_SOF_FIX
+@@ -356,7 +358,9 @@ static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+ 	usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
+ #else
++	DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
+ 	usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
++	DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
+ 	usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
+ #endif
+ 	return 0;
+@@ -767,6 +771,8 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
+ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ #endif
+ {
++	int rc;
++	uint64_t flags;
+ 	dwc_otg_hcd_t *dwc_otg_hcd;
+ 	DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
+ 
+@@ -788,8 +794,18 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+ 	usb_hcd_giveback_urb(hcd, urb);
+ #else
+-	usb_hcd_unlink_urb_from_ep(hcd, urb);
+-	usb_hcd_giveback_urb(hcd, urb, status);
++	DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
++	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
++	if(!rc)
++	{
++		usb_hcd_unlink_urb_from_ep(hcd, urb);
++	}
++
++	DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
++	if (!rc)
++	{
++		usb_hcd_giveback_urb(hcd, urb, status);
++	}
+ #endif
+ 	if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
+ 		DWC_PRINTF("Called usb_hcd_giveback_urb()\n");
+-- 
+1.7.10
+
+
+From 6d0f2d3c8bd430edcbb5058ed4fd6fa535cb7496 Mon Sep 17 00:00:00 2001
+From: Number 27 <chris@bham>
+Date: Sun, 8 Jul 2012 20:57:25 +0100
+Subject: [PATCH 2/3] Backport of Chris Boot's i2c and spi drivers.
+
+---
+ arch/arm/configs/bcmrpi_cutdown_defconfig     |    9 +++
+ arch/arm/mach-bcm2708/bcm2708.c               |   95 ++++++++++++++++++++++++-
+ arch/arm/mach-bcm2708/include/mach/platform.h |    3 +
+ drivers/i2c/busses/Kconfig                    |    8 +++
+ drivers/i2c/busses/Makefile                   |    1 +
+ drivers/spi/Kconfig                           |    8 +++
+ drivers/spi/Makefile                          |    1 +
+ 7 files changed, 123 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
+index bb8cafe..cc9e1df 100644
+--- a/arch/arm/configs/bcmrpi_cutdown_defconfig
++++ b/arch/arm/configs/bcmrpi_cutdown_defconfig
+@@ -550,3 +550,12 @@ CONFIG_CRYPTO_DEFLATE=m
+ # CONFIG_CRYPTO_HW is not set
+ CONFIG_CRC_ITU_T=y
+ CONFIG_LIBCRC32C=y
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
++CONFIG_I2C_CHARDEV=m
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_BCM2708=m
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++CONFIG_SPI_BCM2708=m
+\ No newline at end of file
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index 17c6dbd..a466f44 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -31,6 +31,7 @@
+ #include <linux/cnt32_to_63.h>
+ #include <linux/io.h>
+ #include <linux/module.h>
++#include <linux/spi/spi.h>
+ 
+ #include <linux/version.h>
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+@@ -195,7 +196,6 @@ unsigned long long sched_clock(void)
+ 
+ /* warning - the USB needs a clock > 34MHz */
+ 
+-#ifdef CONFIG_MMC_BCM2708
+ static struct clk sdhost_clk = {
+ #ifdef CONFIG_ARCH_BCM2708_CHIPIT
+ 	.rate = 4000000,	/* 4MHz */
+@@ -203,7 +203,6 @@ unsigned long long sched_clock(void)
+ 	.rate = 250000000,	/* 250MHz */
+ #endif
+ };
+-#endif
+ 
+ static struct clk_lookup lookups[] = {
+ 	{			/* UART0 */
+@@ -219,6 +218,15 @@ unsigned long long sched_clock(void)
+ 	 .dev_id = "bcm2708_mci.0",
+ 	 .clk = &sdhost_clk,
+ #endif
++	 }, {	/* SPI */
++		 .dev_id = "bcm2708_spi.0",
++		 .clk = &sdhost_clk,
++	 }, {	/* BSC0 */
++		 .dev_id = "bcm2708_i2c.0",
++		 .clk = &sdhost_clk,
++	 }, {	/* BSC1 */
++		 .dev_id = "bcm2708_i2c.1",
++		 .clk = &sdhost_clk,
+ 	 }
+ };
+ 
+@@ -461,6 +469,80 @@ struct platform_device bcm2708_powerman_device = {
+ 	       },
+ };
+ 
++static struct resource bcm2708_spi_resources[] = {
++	{
++		.start = SPI0_BASE,
++		.end = SPI0_BASE + SZ_256 - 1,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = IRQ_SPI,
++		.end = IRQ_SPI,
++		.flags = IORESOURCE_IRQ,
++	}
++};
++
++static struct platform_device bcm2708_spi_device = {
++	.name = "bcm2708_spi",
++	.id = 0,
++	.num_resources = ARRAY_SIZE(bcm2708_spi_resources),
++	.resource = bcm2708_spi_resources,
++};
++
++static struct spi_board_info bcm2708_spi_devices[] = {
++	{
++		.modalias = "spidev",
++		.max_speed_hz = 500000,
++		.bus_num = 0,
++		.chip_select = 0,
++		.mode = SPI_MODE_0,
++	}, {
++		.modalias = "spidev",
++		.max_speed_hz = 500000,
++		.bus_num = 0,
++		.chip_select = 1,
++		.mode = SPI_MODE_0,
++	}
++};
++
++static struct resource bcm2708_bsc0_resources[] = {
++	{
++		.start = BSC0_BASE,
++		.end = BSC0_BASE + SZ_256 - 1,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = INTERRUPT_I2C,
++		.end = INTERRUPT_I2C,
++		.flags = IORESOURCE_IRQ,
++	}
++};
++
++static struct platform_device bcm2708_bsc0_device = {
++	.name = "bcm2708_i2c",
++	.id = 0,
++	.num_resources = ARRAY_SIZE(bcm2708_bsc0_resources),
++	.resource = bcm2708_bsc0_resources,
++};
++
++
++static struct resource bcm2708_bsc1_resources[] = {
++	{
++		.start = BSC1_BASE,
++		.end = BSC1_BASE + SZ_256 - 1,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = INTERRUPT_I2C,
++		.end = INTERRUPT_I2C,
++		.flags = IORESOURCE_IRQ,
++	}
++};
++
++static struct platform_device bcm2708_bsc1_device = {
++	.name = "bcm2708_i2c",
++	.id = 1,
++	.num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
++	.resource = bcm2708_bsc1_resources,
++};
++
+ int __init bcm_register_device(struct platform_device *pdev)
+ {
+ 	int ret;
+@@ -513,6 +595,10 @@ void __init bcm2708_init(void)
+ 	for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
+ 		bcm_register_device(&bcm2708_alsa_devices[i]);
+ 
++	bcm_register_device(&bcm2708_spi_device);
++	bcm_register_device(&bcm2708_bsc0_device);
++	bcm_register_device(&bcm2708_bsc1_device);
++
+ #ifdef CONFIG_BCM2708_VCMEM
+ 	{
+ 		extern void vc_mem_connected_init(void);
+@@ -525,6 +611,11 @@ void __init bcm2708_init(void)
+ 	}
+ 	system_rev = boardrev;
+ 	system_serial_low = serial;
++
++#ifdef CONFIG_SPI
++	spi_register_board_info(bcm2708_spi_devices,
++			ARRAY_SIZE(bcm2708_spi_devices));
++#endif
+ }
+ 
+ #define TIMER_PERIOD 10000	/* HZ in microsecs */
+diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h
+index 5afa0a7..3085af1 100644
+--- a/arch/arm/mach-bcm2708/include/mach/platform.h
++++ b/arch/arm/mach-bcm2708/include/mach/platform.h
+@@ -63,9 +63,12 @@
+ #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 SPI0_BASE		 (BCM2708_PERI_BASE + 0x204000) /* SPI0 */
++#define BSC0_BASE		 (BCM2708_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */
+ #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 BSC1_BASE		 (BCM2708_PERI_BASE + 0x804000) /* BSC1 I2C/TWI */
+ #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*/
+ 
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index 646068e..42c792b 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -309,6 +309,14 @@ config I2C_AU1550
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called i2c-au1550.
+ 
++config I2C_BCM2708
++	tristate "BCM2708 BSC"
++	depends on MACH_BCM2708
++	help
++	  Enabling this option will add BSC (Broadcom Serial Controller)
++	  support for the BCM2708. BSC is a Broadcom proprietary bus compatible
++	  with I2C/TWI/SMBus.
++
+ config I2C_BLACKFIN_TWI
+ 	tristate "Blackfin TWI I2C support"
+ 	depends on BLACKFIN
+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
+index e6cf294..3922593 100644
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_POWERMAC)	+= i2c-powermac.o
+ # Embedded system I2C/SMBus host controller drivers
+ obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
+ obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
++obj-$(CONFIG_I2C_BCM2708)	+= i2c-bcm2708.o
+ obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o
+ obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o
+ obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 52e2900..28df0a9 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -74,6 +74,14 @@ config SPI_ATMEL
+ 	  This selects a driver for the Atmel SPI Controller, present on
+ 	  many AT32 (AVR32) and AT91 (ARM) chips.
+ 
++config SPI_BCM2708
++	tristate "BCM2708 SPI controller driver (SPI0)"
++	depends on MACH_BCM2708
++	help
++	  This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This
++	  driver is not compatible with the "Universal SPI Master" or the SPI slave
++	  device.
++
+ config SPI_BFIN
+ 	tristate "SPI controller driver for ADI Blackfin5xx"
+ 	depends on BLACKFIN
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 61c3261..2ff2985 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_ALTERA)		+= spi-altera.o
+ obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o
+ obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
+ obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
++obj-$(CONFIG_SPI_BCM2708)		+= spi-bcm2708.o
+ obj-$(CONFIG_SPI_BFIN)			+= spi-bfin5xx.o
+ obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o
+ obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o
+-- 
+1.7.10
+
+
+From dc9424fa359d244aab37bb59268faaf1300f8eb4 Mon Sep 17 00:00:00 2001
+From: Number 27 <chris@bham>
+Date: Sun, 8 Jul 2012 21:39:42 +0100
+Subject: [PATCH 3/3] forgotten files....
+
+---
+ drivers/i2c/busses/i2c-bcm2708.c |  396 +++++++++++++++++++++++++
+ drivers/spi/spi-bcm2708.c        |  594 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 990 insertions(+)
+ create mode 100644 drivers/i2c/busses/i2c-bcm2708.c
+ create mode 100644 drivers/spi/spi-bcm2708.c
+
+diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c
+new file mode 100644
+index 0000000..70e8d29
+--- /dev/null
++++ b/drivers/i2c/busses/i2c-bcm2708.c
+@@ -0,0 +1,396 @@
++/*
++ * Driver for Broadcom BCM2708 BSC Controllers
++ *
++ * Copyright (C) 2012 Chris Boot & Frank Buss
++ *
++ * This driver is inspired by:
++ * i2c-ocores.c, by Peter Korsgaard <jacmet@sunsite.dk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++
++/* BSC register offsets */
++#define BSC_C			0x00
++#define BSC_S			0x04
++#define BSC_DLEN		0x08
++#define BSC_A			0x0c
++#define BSC_FIFO		0x10
++#define BSC_DIV			0x14
++#define BSC_DEL			0x18
++#define BSC_CLKT		0x1c
++
++/* Bitfields in BSC_C */
++#define BSC_C_I2CEN		0x00008000
++#define BSC_C_INTR		0x00000400
++#define BSC_C_INTT		0x00000200
++#define BSC_C_INTD		0x00000100
++#define BSC_C_ST		0x00000080
++#define BSC_C_CLEAR_1		0x00000020
++#define BSC_C_CLEAR_2		0x00000010
++#define BSC_C_READ		0x00000001
++
++/* Bitfields in BSC_S */
++#define BSC_S_CLKT		0x00000200
++#define BSC_S_ERR		0x00000100
++#define BSC_S_RXF		0x00000080
++#define BSC_S_TXE		0x00000040
++#define BSC_S_RXD		0x00000020
++#define BSC_S_TXD		0x00000010
++#define BSC_S_RXR		0x00000008
++#define BSC_S_TXW		0x00000004
++#define BSC_S_DONE		0x00000002
++#define BSC_S_TA		0x00000001
++
++#define I2C_CLOCK_HZ	100000 /* FIXME: get from DT */
++#define I2C_TIMEOUT_MS	150
++
++#define DRV_NAME	"bcm2708_i2c"
++
++struct bcm2708_i2c {
++	struct i2c_adapter adapter;
++
++	spinlock_t lock;
++	void __iomem *base;
++	int irq;
++	struct clk *clk;
++
++	struct completion done;
++
++	struct i2c_msg *msg;
++	int pos;
++	int nmsgs;
++	bool error;
++};
++
++/*
++ * This function sets the ALT mode on the I2C pins so that we can use them with
++ * the BSC hardware.
++ *
++ * FIXME: This is a hack. Use pinmux / pinctrl.
++ */
++static void bcm2708_i2c_init_pinmode(void)
++{
++#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
++#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
++
++	int pin;
++	u32 *gpio = ioremap(0x20200000, SZ_16K);
++
++	/* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */
++	for (pin = 0; pin <= 3; pin++) {
++		INP_GPIO(pin);		/* set mode to GPIO input first */
++		SET_GPIO_ALT(pin, 0);	/* set mode to ALT 0 */
++	}
++
++	iounmap(gpio);
++
++#undef INP_GPIO
++#undef SET_GPIO_ALT
++}
++
++static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg)
++{
++	return readl(bi->base + reg);
++}
++
++static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val)
++{
++	writel(val, bi->base + reg);
++}
++
++static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi)
++{
++	bcm2708_wr(bi, BSC_C, 0);
++	bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE);	
++}
++
++static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi)
++{
++	while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len))
++		bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO);
++}
++
++static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
++{
++	while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len))
++		bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
++}
++
++static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
++{
++	unsigned long bus_hz;
++	u32 cdiv;
++	u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
++
++	bus_hz = clk_get_rate(bi->clk);
++	cdiv = bus_hz / I2C_CLOCK_HZ;
++
++	if (bi->msg->flags & I2C_M_RD)
++		c |= BSC_C_INTR | BSC_C_READ;
++	else
++		c |= BSC_C_INTT;
++
++	bcm2708_wr(bi, BSC_DIV, cdiv);
++	bcm2708_wr(bi, BSC_A, bi->msg->addr);
++	bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
++	bcm2708_wr(bi, BSC_C, c);
++}
++
++static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id)
++{
++	struct bcm2708_i2c *bi = dev_id;
++	bool handled = true;
++	u32 s;
++
++	spin_lock(&bi->lock);
++
++	s = bcm2708_rd(bi, BSC_S);
++
++	if (s & (BSC_S_CLKT | BSC_S_ERR)) {
++		bcm2708_bsc_reset(bi);
++		bi->error = true;
++
++		/* wake up our bh */
++		complete(&bi->done);
++	} else if (s & BSC_S_DONE) {
++		bi->nmsgs--;
++
++		if (bi->msg->flags & I2C_M_RD)
++			bcm2708_bsc_fifo_drain(bi);
++
++		bcm2708_bsc_reset(bi);
++
++		if (bi->nmsgs) {
++			/* advance to next message */
++			bi->msg++;
++			bi->pos = 0;
++			bcm2708_bsc_setup(bi);
++		} else {
++			/* wake up our bh */
++			complete(&bi->done);
++		}
++	} else if (s & BSC_S_TXW) {
++		bcm2708_bsc_fifo_fill(bi);
++	} else if (s & BSC_S_RXR) {
++		bcm2708_bsc_fifo_drain(bi);
++	} else {
++		handled = false;
++	}
++
++	spin_unlock(&bi->lock);
++
++	return handled ? IRQ_HANDLED : IRQ_NONE;
++}
++
++static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap,
++	struct i2c_msg *msgs, int num)
++{
++	struct bcm2708_i2c *bi = adap->algo_data;
++	unsigned long flags;
++	int ret;
++
++	spin_lock_irqsave(&bi->lock, flags);
++
++	INIT_COMPLETION(bi->done);
++	bi->msg = msgs;
++	bi->pos = 0;
++	bi->nmsgs = num;
++	bi->error = false;
++
++	spin_unlock_irqrestore(&bi->lock, flags);
++
++	bcm2708_bsc_setup(bi);
++
++	ret = wait_for_completion_timeout(&bi->done,
++			msecs_to_jiffies(I2C_TIMEOUT_MS));
++	if (ret == 0) {
++		dev_err(&adap->dev, "transfer timed out\n");
++		spin_lock_irqsave(&bi->lock, flags);
++		bcm2708_bsc_reset(bi);
++		spin_unlock_irqrestore(&bi->lock, flags);
++		return -ETIMEDOUT;
++	}
++
++	return bi->error ? -EIO : num;
++}
++
++static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap)
++{
++	return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL;
++}
++
++static struct i2c_algorithm bcm2708_i2c_algorithm = {
++	.master_xfer = bcm2708_i2c_master_xfer,
++	.functionality = bcm2708_i2c_functionality,
++};
++
++static int __devinit bcm2708_i2c_probe(struct platform_device *pdev)
++{
++	struct resource *regs;
++	int irq, err = -ENOMEM;
++	struct clk *clk;
++	struct bcm2708_i2c *bi;
++	struct i2c_adapter *adap;
++
++	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!regs) {
++		dev_err(&pdev->dev, "could not get IO memory\n");
++		return -ENXIO;
++	}
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "could not get IRQ\n");
++		return irq;
++	}
++
++	clk = clk_get(&pdev->dev, NULL);
++	if (IS_ERR(clk)) {
++		dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
++		return PTR_ERR(clk);
++	}
++
++	bcm2708_i2c_init_pinmode();
++
++	bi = kzalloc(sizeof(*bi), GFP_KERNEL);
++	if (!bi)
++		goto out_clk_put;
++
++	platform_set_drvdata(pdev, bi);
++
++	adap = &bi->adapter;
++	adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC;
++	adap->algo = &bcm2708_i2c_algorithm;
++	adap->algo_data = bi;
++	adap->dev.parent = &pdev->dev;
++	adap->nr = pdev->id;
++	strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
++
++	switch (pdev->id) {
++	case 0:
++		adap->class = I2C_CLASS_HWMON;
++		break;
++	case 1:
++		adap->class = I2C_CLASS_DDC;
++		break;
++	default:
++		dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n");
++		err = -ENXIO;
++		goto out_free_bi;
++	}
++
++	spin_lock_init(&bi->lock);
++	init_completion(&bi->done);
++
++	bi->base = ioremap(regs->start, resource_size(regs));
++	if (!bi->base) {
++		dev_err(&pdev->dev, "could not remap memory\n");
++		goto out_free_bi;
++	}
++
++	bi->irq = irq;
++	bi->clk = clk;
++
++	err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED,
++			dev_name(&pdev->dev), bi);
++	if (err) {
++		dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
++		goto out_iounmap;
++	}
++
++	bcm2708_bsc_reset(bi);
++
++	err = i2c_add_numbered_adapter(adap);
++	if (err < 0) {
++		dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err);
++		goto out_free_irq;
++	}
++
++	dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d)\n",
++		pdev->id, (unsigned long)regs->start, irq);
++
++	return 0;
++
++out_free_irq:
++	free_irq(bi->irq, bi);
++out_iounmap:
++	iounmap(bi->base);
++out_free_bi:
++	kfree(bi);
++out_clk_put:
++	clk_put(clk);
++	return err;
++}
++
++static int __devexit bcm2708_i2c_remove(struct platform_device *pdev)
++{
++	struct bcm2708_i2c *bi = platform_get_drvdata(pdev);
++
++	platform_set_drvdata(pdev, NULL);
++
++	i2c_del_adapter(&bi->adapter);
++	free_irq(bi->irq, bi);
++	iounmap(bi->base);
++	clk_disable(bi->clk);
++	clk_put(bi->clk);
++	kfree(bi);
++
++	return 0;
++}
++
++static struct platform_driver bcm2708_i2c_driver = {
++	.driver		= {
++		.name	= DRV_NAME,
++		.owner	= THIS_MODULE,
++	},
++	.probe		= bcm2708_i2c_probe,
++	.remove		= __devexit_p(bcm2708_i2c_remove),
++};
++
++// module_platform_driver(bcm2708_i2c_driver);
++
++
++static int __init bcm2708_i2c_init(void)
++{
++	return platform_driver_register(&bcm2708_i2c_driver);
++}
++
++static void __exit bcm2708_i2c_exit(void)
++{
++	platform_driver_unregister(&bcm2708_i2c_driver);
++}
++
++module_init(bcm2708_i2c_init);
++module_exit(bcm2708_i2c_exit);
++
++
++
++MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708");
++MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:" DRV_NAME);
+diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c
+new file mode 100644
+index 0000000..ef8fef0
+--- /dev/null
++++ b/drivers/spi/spi-bcm2708.c
+@@ -0,0 +1,594 @@
++/*
++ * Driver for Broadcom BCM2708 SPI Controllers
++ *
++ * Copyright (C) 2012 Chris Boot
++ *
++ * This driver is inspired by:
++ * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
++ * spi-atmel.c, Copyright (C) 2006 Atmel Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++#include <linux/spi/spi.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/log2.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++
++/* SPI register offsets */
++#define SPI_CS			0x00
++#define SPI_FIFO		0x04
++#define SPI_CLK			0x08
++#define SPI_DLEN		0x0c
++#define SPI_LTOH		0x10
++#define SPI_DC			0x14
++
++/* Bitfields in CS */
++#define SPI_CS_LEN_LONG		0x02000000
++#define SPI_CS_DMA_LEN		0x01000000
++#define SPI_CS_CSPOL2		0x00800000
++#define SPI_CS_CSPOL1		0x00400000
++#define SPI_CS_CSPOL0		0x00200000
++#define SPI_CS_RXF		0x00100000
++#define SPI_CS_RXR		0x00080000
++#define SPI_CS_TXD		0x00040000
++#define SPI_CS_RXD		0x00020000
++#define SPI_CS_DONE		0x00010000
++#define SPI_CS_LEN		0x00002000
++#define SPI_CS_REN		0x00001000
++#define SPI_CS_ADCS		0x00000800
++#define SPI_CS_INTR		0x00000400
++#define SPI_CS_INTD		0x00000200
++#define SPI_CS_DMAEN		0x00000100
++#define SPI_CS_TA		0x00000080
++#define SPI_CS_CSPOL		0x00000040
++#define SPI_CS_CLEAR_RX		0x00000020
++#define SPI_CS_CLEAR_TX		0x00000010
++#define SPI_CS_CPOL		0x00000008
++#define SPI_CS_CPHA		0x00000004
++#define SPI_CS_CS_10		0x00000002
++#define SPI_CS_CS_01		0x00000001
++
++#define SPI_TIMEOUT_MS	150
++
++#define DRV_NAME	"bcm2708_spi"
++
++struct bcm2708_spi {
++	spinlock_t lock;
++	void __iomem *base;
++	int irq;
++	struct clk *clk;
++	bool stopping;
++
++	struct list_head queue;
++	struct workqueue_struct *workq;
++	struct work_struct work;
++	struct completion done;
++
++	const u8 *tx_buf;
++	u8 *rx_buf;
++	int len;
++};
++
++struct bcm2708_spi_state {
++	u32 cs;
++	u16 cdiv;
++};
++
++/*
++ * This function sets the ALT mode on the SPI pins so that we can use them with
++ * the SPI hardware.
++ *
++ * FIXME: This is a hack. Use pinmux / pinctrl.
++ */
++static void bcm2708_init_pinmode(void)
++{
++#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
++#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
++
++	int pin;
++	u32 *gpio = ioremap(0x20200000, SZ_16K);
++
++	/* SPI is on GPIO 7..11 */
++	for (pin = 7; pin <= 11; pin++) {
++		INP_GPIO(pin);		/* set mode to GPIO input first */
++		SET_GPIO_ALT(pin, 0);	/* set mode to ALT 0 */
++	}
++
++	iounmap(gpio);
++
++#undef INP_GPIO
++#undef SET_GPIO_ALT
++}
++
++static inline u32 bcm2708_rd(struct bcm2708_spi *bs, unsigned reg)
++{
++	return readl(bs->base + reg);
++}
++
++static inline void bcm2708_wr(struct bcm2708_spi *bs, unsigned reg, u32 val)
++{
++	writel(val, bs->base + reg);
++}
++
++static inline void bcm2708_rd_fifo(struct bcm2708_spi *bs, int len)
++{
++	u8 byte;
++
++	while (len--) {
++		byte = bcm2708_rd(bs, SPI_FIFO);
++		if (bs->rx_buf)
++			*bs->rx_buf++ = byte;
++	}
++}
++
++static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len)
++{
++	u8 byte;
++
++	if (len > bs->len)
++		len = bs->len;
++
++	while (len--) {
++		byte = bs->tx_buf ? *bs->tx_buf++ : 0;
++		bcm2708_wr(bs, SPI_FIFO, byte);
++		bs->len--;
++	}
++}
++
++static irqreturn_t bcm2708_spi_interrupt(int irq, void *dev_id)
++{
++	struct spi_master *master = dev_id;
++	struct bcm2708_spi *bs = spi_master_get_devdata(master);
++	u32 cs;
++
++	spin_lock(&bs->lock);
++
++	cs = bcm2708_rd(bs, SPI_CS);
++
++	if (cs & SPI_CS_DONE) {
++		if (bs->len) { /* first interrupt in a transfer */
++			/* fill the TX fifo with up to 16 bytes */
++			bcm2708_wr_fifo(bs, 16);
++		} else { /* transfer complete */
++			/* disable interrupts */
++			cs &= ~(SPI_CS_INTR | SPI_CS_INTD);
++			bcm2708_wr(bs, SPI_CS, cs);
++
++			/* drain RX FIFO */
++			while (cs & SPI_CS_RXD) {
++				bcm2708_rd_fifo(bs, 1);
++				cs = bcm2708_rd(bs, SPI_CS);
++			}
++
++			/* wake up our bh */
++			complete(&bs->done);
++		}
++	} else if (cs & SPI_CS_RXR) {
++		/* read 12 bytes of data */
++		bcm2708_rd_fifo(bs, 12);
++
++		/* write up to 12 bytes */
++		bcm2708_wr_fifo(bs, 12);
++	}
++
++	spin_unlock(&bs->lock);
++
++	return IRQ_HANDLED;
++}
++
++static int bcm2708_setup_state(struct spi_master *master,
++		struct device *dev, struct bcm2708_spi_state *state,
++		u32 hz, u8 csel, u8 mode, u8 bpw)
++{
++	struct bcm2708_spi *bs = spi_master_get_devdata(master);
++	int cdiv;
++	unsigned long bus_hz;
++	u32 cs = 0;
++
++	bus_hz = clk_get_rate(bs->clk);
++
++	if (hz >= bus_hz) {
++		cdiv = 2; /* bus_hz / 2 is as fast as we can go */
++	} else if (hz) {
++		cdiv = DIV_ROUND_UP(bus_hz, hz);
++
++		/* CDIV must be a power of 2, so round up */
++		cdiv = roundup_pow_of_two(cdiv);
++
++		if (cdiv > 65536) {
++			dev_dbg(dev,
++				"setup: %d Hz too slow, cdiv %u; min %ld Hz\n",
++				hz, cdiv, bus_hz / 65536);
++			return -EINVAL;
++		} else if (cdiv == 65536) {
++			cdiv = 0;
++		} else if (cdiv == 1) {
++			cdiv = 2; /* 1 gets rounded down to 0; == 65536 */
++		}
++	} else {
++		cdiv = 0;
++	}
++
++	switch (bpw) {
++	case 8:
++		break;
++	default:
++		dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8)\n",
++			bpw);
++		return -EINVAL;
++	}
++
++	if (mode & SPI_CPOL)
++		cs |= SPI_CS_CPOL;
++	if (mode & SPI_CPHA)
++		cs |= SPI_CS_CPHA;
++
++	if (!(mode & SPI_NO_CS)) {
++		if (mode & SPI_CS_HIGH) {
++			cs |= SPI_CS_CSPOL;
++			cs |= SPI_CS_CSPOL0 << csel;
++		}
++
++		cs |= csel;
++	} else {
++		cs |= SPI_CS_CS_10 | SPI_CS_CS_01;
++	}
++
++	if (state) {
++		state->cs = cs;
++		state->cdiv = cdiv;
++	}
++
++	return 0;
++}
++
++static int bcm2708_process_transfer(struct bcm2708_spi *bs,
++		struct spi_message *msg, struct spi_transfer *xfer)
++{
++	struct spi_device *spi = msg->spi;
++	struct bcm2708_spi_state state, *stp;
++	int ret;
++	u32 cs;
++
++	if (bs->stopping)
++		return -ESHUTDOWN;
++
++	if (xfer->bits_per_word || xfer->speed_hz) {
++		ret = bcm2708_setup_state(spi->master, &spi->dev, &state,
++			spi->max_speed_hz, spi->chip_select, spi->mode,
++			spi->bits_per_word);
++		if (ret)
++			return ret;
++
++		stp = &state;
++	} else {
++		stp = spi->controller_state;
++	}
++
++	INIT_COMPLETION(bs->done);
++	bs->tx_buf = xfer->tx_buf;
++	bs->rx_buf = xfer->rx_buf;
++	bs->len = xfer->len;
++
++	cs = stp->cs | SPI_CS_INTR | SPI_CS_INTD | SPI_CS_TA;
++
++	bcm2708_wr(bs, SPI_CLK, stp->cdiv);
++	bcm2708_wr(bs, SPI_CS, cs);
++
++	ret = wait_for_completion_timeout(&bs->done,
++			msecs_to_jiffies(SPI_TIMEOUT_MS));
++	if (ret == 0) {
++		dev_err(&spi->dev, "transfer timed out\n");
++		return -ETIMEDOUT;
++	}
++
++	if (xfer->delay_usecs)
++		udelay(xfer->delay_usecs);
++
++	if (list_is_last(&xfer->transfer_list, &msg->transfers) ||
++			xfer->cs_change) {
++		/* clear TA and interrupt flags */
++		bcm2708_wr(bs, SPI_CS, stp->cs);
++	}
++
++	msg->actual_length += (xfer->len - bs->len);
++
++	return 0;
++}
++
++static void bcm2708_work(struct work_struct *work)
++{
++	struct bcm2708_spi *bs = container_of(work, struct bcm2708_spi, work);
++	unsigned long flags;
++	struct spi_message *msg;
++	struct spi_transfer *xfer;
++	int status = 0;
++
++	spin_lock_irqsave(&bs->lock, flags);
++	while (!list_empty(&bs->queue)) {
++		msg = list_first_entry(&bs->queue, struct spi_message, queue);
++		list_del_init(&msg->queue);
++		spin_unlock_irqrestore(&bs->lock, flags);
++
++		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++			status = bcm2708_process_transfer(bs, msg, xfer);
++			if (status)
++				break;
++		}
++
++		msg->status = status;
++		msg->complete(msg->context);
++
++		spin_lock_irqsave(&bs->lock, flags);
++	}
++	spin_unlock_irqrestore(&bs->lock, flags);
++}
++
++static int bcm2708_spi_setup(struct spi_device *spi)
++{
++	struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
++	struct bcm2708_spi_state *state;
++	int ret;
++
++	if (bs->stopping)
++		return -ESHUTDOWN;
++
++	if (!(spi->mode & SPI_NO_CS) &&
++			(spi->chip_select > spi->master->num_chipselect)) {
++		dev_dbg(&spi->dev,
++			"setup: invalid chipselect %u (%u defined)\n",
++			spi->chip_select, spi->master->num_chipselect);
++		return -EINVAL;
++	}
++
++	state = spi->controller_state;
++	if (!state) {
++		state = kzalloc(sizeof(*state), GFP_KERNEL);
++		if (!state)
++			return -ENOMEM;
++
++		spi->controller_state = state;
++	}
++
++	ret = bcm2708_setup_state(spi->master, &spi->dev, state,
++		spi->max_speed_hz, spi->chip_select, spi->mode,
++		spi->bits_per_word);
++	if (ret < 0) {
++		kfree(state);
++		spi->controller_state = NULL;
++	}
++
++	dev_dbg(&spi->dev,
++		"setup: cd %d: %d Hz, bpw %u, mode 0x%x -> CS=%08x CDIV=%04x\n",
++		spi->chip_select, spi->max_speed_hz, spi->bits_per_word,
++		spi->mode, state->cs, state->cdiv);
++
++	return 0;
++}
++
++static int bcm2708_spi_transfer(struct spi_device *spi, struct spi_message *msg)
++{
++	struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
++	struct spi_transfer *xfer;
++	int ret;
++	unsigned long flags;
++
++	if (unlikely(list_empty(&msg->transfers)))
++		return -EINVAL;
++
++	if (bs->stopping)
++		return -ESHUTDOWN;
++
++	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++		if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) {
++			dev_dbg(&spi->dev, "missing rx or tx buf\n");
++			return -EINVAL;
++		}
++
++		if (!xfer->bits_per_word || xfer->speed_hz)
++			continue;
++
++		ret = bcm2708_setup_state(spi->master, &spi->dev, NULL,
++			xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
++			spi->chip_select, spi->mode,
++			xfer->bits_per_word ? xfer->bits_per_word :
++				spi->bits_per_word);
++		if (ret)
++			return ret;
++	}
++
++	msg->status = -EINPROGRESS;
++	msg->actual_length = 0;
++
++	spin_lock_irqsave(&bs->lock, flags);
++	list_add_tail(&msg->queue, &bs->queue);
++	queue_work(bs->workq, &bs->work);
++	spin_unlock_irqrestore(&bs->lock, flags);
++
++	return 0;
++}
++
++static void bcm2708_spi_cleanup(struct spi_device *spi)
++{
++	if (spi->controller_state) {
++		kfree(spi->controller_state);
++		spi->controller_state = NULL;
++	}
++}
++
++static int __devinit bcm2708_spi_probe(struct platform_device *pdev)
++{
++	struct resource *regs;
++	int irq, err = -ENOMEM;
++	struct clk *clk;
++	struct spi_master *master;
++	struct bcm2708_spi *bs;
++
++	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!regs) {
++		dev_err(&pdev->dev, "could not get IO memory\n");
++		return -ENXIO;
++	}
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0) {
++		dev_err(&pdev->dev, "could not get IRQ\n");
++		return irq;
++	}
++
++	clk = clk_get(&pdev->dev, NULL);
++	if (IS_ERR(clk)) {
++		dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
++		return PTR_ERR(clk);
++	}
++
++	bcm2708_init_pinmode();
++
++	master = spi_alloc_master(&pdev->dev, sizeof(*bs));
++	if (!master) {
++		dev_err(&pdev->dev, "spi_alloc_master() failed\n");
++		goto out_clk_put;
++	}
++
++	/* the spi->mode bits understood by this driver: */
++	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
++
++	master->bus_num = pdev->id;
++	master->num_chipselect = 3;
++	master->setup = bcm2708_spi_setup;
++	master->transfer = bcm2708_spi_transfer;
++	master->cleanup = bcm2708_spi_cleanup;
++	platform_set_drvdata(pdev, master);
++
++	bs = spi_master_get_devdata(master);
++
++	spin_lock_init(&bs->lock);
++	INIT_LIST_HEAD(&bs->queue);
++	init_completion(&bs->done);
++	INIT_WORK(&bs->work, bcm2708_work);
++
++	bs->base = ioremap(regs->start, resource_size(regs));
++	if (!bs->base) {
++		dev_err(&pdev->dev, "could not remap memory\n");
++		goto out_master_put;
++	}
++
++	bs->workq = create_singlethread_workqueue(dev_name(&pdev->dev));
++	if (!bs->workq) {
++		dev_err(&pdev->dev, "could not create workqueue\n");
++		goto out_iounmap;
++	}
++
++	bs->irq = irq;
++	bs->clk = clk;
++	bs->stopping = false;
++
++	err = request_irq(irq, bcm2708_spi_interrupt, 0, dev_name(&pdev->dev),
++			master);
++	if (err) {
++		dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
++		goto out_workqueue;
++	}
++
++	/* initialise the hardware */
++	clk_enable(clk);
++	bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
++
++	err = spi_register_master(master);
++	if (err) {
++		dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
++		goto out_free_irq;
++	}
++
++	dev_info(&pdev->dev, "SPI Controller at 0x%08lx (irq %d)\n",
++		(unsigned long)regs->start, irq);
++
++	return 0;
++
++out_free_irq:
++	free_irq(bs->irq, master);
++out_workqueue:
++	destroy_workqueue(bs->workq);
++out_iounmap:
++	iounmap(bs->base);
++out_master_put:
++	spi_master_put(master);
++out_clk_put:
++	clk_put(clk);
++	return err;
++}
++
++static int __devexit bcm2708_spi_remove(struct platform_device *pdev)
++{
++	struct spi_master *master = platform_get_drvdata(pdev);
++	struct bcm2708_spi *bs = spi_master_get_devdata(master);
++
++	/* reset the hardware and block queue progress */
++	spin_lock_irq(&bs->lock);
++	bs->stopping = true;
++	bcm2708_wr(bs, SPI_CS, SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
++	spin_unlock_irq(&bs->lock);
++
++	flush_work_sync(&bs->work);
++
++	clk_disable(bs->clk);
++	clk_put(bs->clk);
++	free_irq(bs->irq, master);
++	iounmap(bs->base);
++
++	spi_unregister_master(master);
++
++	return 0;
++}
++
++static struct platform_driver bcm2708_spi_driver = {
++	.driver		= {
++		.name	= DRV_NAME,
++		.owner	= THIS_MODULE,
++	},
++	.probe		= bcm2708_spi_probe,
++	.remove		= __devexit_p(bcm2708_spi_remove),
++};
++
++
++static int __init bcm2708_spi_init(void)
++{
++	return platform_driver_probe(&bcm2708_spi_driver, bcm2708_spi_probe);
++}
++module_init(bcm2708_spi_init);
++
++static void __exit bcm2708_spi_exit(void)
++{
++	platform_driver_unregister(&bcm2708_spi_driver);
++}
++module_exit(bcm2708_spi_exit);
++
++
++//module_platform_driver(bcm2708_spi_driver);
++
++MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2708");
++MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:" DRV_NAME);
+-- 
+1.7.10
+
+From fc48dbcb3a1eb6a80ddf132b6ca65d408c268c84 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 10 Jul 2012 00:14:48 +0100
+Subject: [PATCH] Possible fix for failure to boot with compressed kernels
+
+---
+ arch/arm/mach-bcm2708/include/mach/uncompress.h |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-bcm2708/include/mach/uncompress.h b/arch/arm/mach-bcm2708/include/mach/uncompress.h
+index 8ad4f5c..582bb10 100644
+--- a/arch/arm/mach-bcm2708/include/mach/uncompress.h
++++ b/arch/arm/mach-bcm2708/include/mach/uncompress.h
+@@ -20,6 +20,7 @@
+  */
+ 
+ #include <linux/io.h>
++#include <linux/amba/serial.h>
+ #include <mach/hardware.h>
+ 
+ #define BCM2708_UART_DR	__io_address(UART0_BASE + 0x00)
+@@ -38,8 +39,12 @@ static inline void putc(int c)
+ 
+ static inline void flush(void)
+ {
+-	while (readl(BCM2708_UART_FR) & (1 << 3))
++	int fr;
++
++	do {
++		fr = __raw_readl(BCM2708_UART_FR);
+ 		barrier();
++	} while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
+ }
+ 
+ /*
+-- 
+1.7.10
+
+From 529f715dfcff43d012f242c3c7efa6bf339c0ae2 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 11 Jul 2012 00:29:52 +0100
+Subject: [PATCH 1/2] Another try at fixing compressed kernel booting
+
+---
+ arch/arm/mach-bcm2708/include/mach/uncompress.h |   41 ++++++++++++++++++++---
+ 1 file changed, 36 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/include/mach/uncompress.h b/arch/arm/mach-bcm2708/include/mach/uncompress.h
+index 582bb10..5c43412 100644
+--- a/arch/arm/mach-bcm2708/include/mach/uncompress.h
++++ b/arch/arm/mach-bcm2708/include/mach/uncompress.h
+@@ -23,18 +23,24 @@
+ #include <linux/amba/serial.h>
+ #include <mach/hardware.h>
+ 
+-#define BCM2708_UART_DR	__io_address(UART0_BASE + 0x00)
+-#define BCM2708_UART_FR	__io_address(UART0_BASE + 0x18)
++#define UART_BAUD 115200
++
++#define BCM2708_UART_DR	UART0_BASE + UART01x_DR
++#define BCM2708_UART_FR	UART0_BASE + UART01x_FR
++#define BCM2708_UART_IBRD UART0_BASE + UART011_IBRD
++#define BCM2708_UART_FBRD UART0_BASE + UART011_FBRD
++#define BCM2708_UART_LCRH UART0_BASE + UART011_LCRH
++#define BCM2708_UART_CR UART0_BASE + UART011_CR
+ 
+ /*
+  * This does not append a newline
+  */
+ static inline void putc(int c)
+ {
+-	while (readl(BCM2708_UART_FR) & (1 << 5))
++	while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF)
+ 		barrier();
+ 
+-	writel(c, BCM2708_UART_DR);
++	__raw_writel(c, BCM2708_UART_DR);
+ }
+ 
+ static inline void flush(void)
+@@ -47,8 +53,33 @@ static inline void flush(void)
+ 	} while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
+ }
+ 
++static inline void arch_decomp_setup(void)
++{
++	int temp, div, rem, frac;
++
++	temp = 16 * UART_BAUD;
++	div = UART0_CLOCK / temp;
++	rem = UART0_CLOCK % temp;
++	temp = (8 * rem) / UART_BAUD;
++	frac = (temp >> 1) + (temp & 1);
++
++	/* Make sure the UART is disabled before we start */
++	__raw_writel(0, BCM2708_UART_CR);
++
++	/* Set the baud rate */
++	__raw_writel(div, BCM2708_UART_IBRD);
++	__raw_writel(frac, BCM2708_UART_FBRD);
++
++	/* Set the UART to 8n1, FIFO enabled */
++	__raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH);
++
++	/* Enable the UART */
++	__raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE,
++			BCM2708_UART_CR);
++}
++
+ /*
+  * nothing to do
+  */
+-#define arch_decomp_setup()
+ #define arch_decomp_wdog()
++
+-- 
+1.7.10
+
+
+From d461c6d577070637ceeae52ea019e6d907b21c47 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 11 Jul 2012 13:55:11 +0100
+Subject: [PATCH 2/2] Add missing UART0_CLOCK from last commit
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c               |    2 +-
+ arch/arm/mach-bcm2708/include/mach/platform.h |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index a466f44..bf9f730 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -183,7 +183,7 @@ unsigned long long sched_clock(void)
+  * These are fixed clocks.
+  */
+ static struct clk ref24_clk = {
+-	.rate = 3000000,	/* The UART is clocked at 3MHz via APB_CLK */
++	.rate = UART0_CLOCK,	/* The UART is clocked at 3MHz via APB_CLK */
+ };
+ 
+ static struct clk osc_clk = {
+diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h
+index 3085af1..5a797ac 100644
+--- a/arch/arm/mach-bcm2708/include/mach/platform.h
++++ b/arch/arm/mach-bcm2708/include/mach/platform.h
+@@ -216,7 +216,7 @@
+ #define PM_RSTS_HADDRF_SET                                 0x00000002
+ #define PM_RSTS_HADDRQ_SET                                 0x00000001
+ 
+-
++#define UART0_CLOCK      3000000
+ 
+ #endif
+ 
+-- 
+1.7.10
+
+From 178f598a8ad9cc2eea1d33e6dc0d05fc80c2d87b Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 13 Jul 2012 18:34:18 +0100
+Subject: [PATCH 1/3] Add temporary fix for hang when quitting X
+
+---
+ drivers/video/bcm2708_fb.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
+index 2b23be6..e7d93fb 100644
+--- a/drivers/video/bcm2708_fb.c
++++ b/drivers/video/bcm2708_fb.c
+@@ -18,6 +18,7 @@
+ #include <linux/errno.h>
+ #include <linux/string.h>
+ #include <linux/slab.h>
++#include <linux/delay.h>
+ #include <linux/mm.h>
+ #include <linux/fb.h>
+ #include <linux/init.h>
+@@ -221,7 +222,9 @@ static int bcm2708_fb_set_par(struct fb_info *info)
+ 	/* inform vc about new framebuffer */
+ 	bcm_mailbox_write(MBOX_CHAN_FB, fb->dma);
+ 
+-	/* TODO: replace fb driver with vchiq version */
++	/* workaround occasional failure to read results. TODO: fix */
++	msleep(10);
++
+ 	/* wait for response */
+ 	bcm_mailbox_read(MBOX_CHAN_FB, &val);
+ 
+-- 
+1.7.10
+
+
+From f6e4f04b715deaec1e48d475318e36e26efcee15 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 14 Jul 2012 18:38:58 +0100
+Subject: [PATCH 2/3] Better fix for quitting X hang. Interrupted mailbox
+ reads are not something we can reliably recover from,
+ so down_interruptable is not a safe call.
+
+---
+ arch/arm/mach-bcm2708/vcio.c |   12 ++++--------
+ drivers/video/bcm2708_fb.c   |    3 ---
+ 2 files changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c
+index 799a0ac..3874051 100644
+--- a/arch/arm/mach-bcm2708/vcio.c
++++ b/arch/arm/mach-bcm2708/vcio.c
+@@ -119,14 +119,10 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28)
+ 	if (mbox->magic != MBOX_MAGIC)
+ 		rc = -EINVAL;
+ 	else {
+-		if (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;
+-		}
++		down(&mbox->sema[chan]);
++		*data28 = MBOX_DATA28(mbox->msg[chan]);
++		mbox->msg[chan] = 0;
++		rc = 0;
+ 	}
+ 	return rc;
+ }
+diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
+index e7d93fb..f2c55a6 100644
+--- a/drivers/video/bcm2708_fb.c
++++ b/drivers/video/bcm2708_fb.c
+@@ -222,9 +222,6 @@ static int bcm2708_fb_set_par(struct fb_info *info)
+ 	/* inform vc about new framebuffer */
+ 	bcm_mailbox_write(MBOX_CHAN_FB, fb->dma);
+ 
+-	/* workaround occasional failure to read results. TODO: fix */
+-	msleep(10);
+-
+ 	/* wait for response */
+ 	bcm_mailbox_read(MBOX_CHAN_FB, &val);
+ 
+-- 
+1.7.10
+
+
+From 1220673bfd5191e7eb1118a91c1581a51421aef1 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 17 Jul 2012 00:48:27 +0100
+Subject: [PATCH 3/3] Add sync_after_dma module parameter
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |   60 ++++++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 1d8751c..1d50cc6 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -52,7 +52,6 @@
+ #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
+@@ -137,6 +136,7 @@ static inline unsigned long int since_ns(hptime_t t)
+ 
+ static bool allow_highspeed = 1;
+ static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
++static bool sync_after_dma = 1;
+ 
+ #if 0
+ static void hptime_test(void)
+@@ -832,34 +832,34 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+ 						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=5000;
+-
+-		DBG("PDMA over - sync card\n");
+-		if (data->flags & MMC_DATA_READ)
+-			state_mask = SDHCI_DOING_READ;
+-		else
+-			state_mask = SDHCI_DOING_WRITE;
++		if (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=30*5000;
++
++			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)
+-		{
+-			udelay(30);
+-			continue;
++			while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE) 
++				& state_mask) && --timeout > 0)
++			{
++				udelay(1);
++				continue;
++			}
++			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");
+ 		}
+-		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",
+@@ -1315,7 +1315,9 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+ 		       SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+ 		       SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+                SDHCI_QUIRK_MISSING_CAPS |
+-               SDHCI_QUIRK_NO_HISPD_BIT;
++               SDHCI_QUIRK_NO_HISPD_BIT |
++               (sync_after_dma ? 0:SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12);
++
+ 
+ #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+ 	host->flags = SDHCI_USE_PLATDMA;
+@@ -1493,6 +1495,7 @@ static void __exit sdhci_drv_exit(void)
+ 
+ module_param(allow_highspeed, bool, 0444);
+ module_param(emmc_clock_freq, int, 0444);
++module_param(sync_after_dma, bool, 0444);
+ 
+ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+ MODULE_AUTHOR("Broadcom <info@broadcom.com>");
+@@ -1501,5 +1504,6 @@ static void __exit sdhci_drv_exit(void)
+ 
+ MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
+ MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
++MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
+ 
+ 
+-- 
+1.7.10
+
+From eab45cba7edffe1a2ccdd9bcd7b30009f50a7914 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 24 Jul 2012 11:11:03 +0100
+Subject: [PATCH 1/2] Fix var.width/var.height. They actually mean display
+ size. See #65
+
+---
+ drivers/video/bcm2708_fb.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
+index f2c55a6..5ca8aca 100644
+--- a/drivers/video/bcm2708_fb.c
++++ b/drivers/video/bcm2708_fb.c
+@@ -374,8 +374,8 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb)
+ 	fb->fb.var.vmode = FB_VMODE_NONINTERLACED;
+ 	fb->fb.var.activate = FB_ACTIVATE_NOW;
+ 	fb->fb.var.nonstd = 0;
+-	fb->fb.var.height = fbwidth;
+-	fb->fb.var.width = fbheight;
++	fb->fb.var.height = -1;		/* height of picture in mm    */
++	fb->fb.var.width = -1;		/* width of picture in mm    */
+ 	fb->fb.var.accel_flags = 0;
+ 
+ 	fb->fb.monspecs.hfmin = 0;
+-- 
+1.7.10
+
+
+From b57a8d8bb13670b25f06de9a002fb91025f46099 Mon Sep 17 00:00:00 2001
+From: Ian Tessier <ian@cim.mcgill.ca>
+Date: Wed, 25 Jul 2012 12:22:35 -0400
+Subject: [PATCH 2/2] The TIMER_PERIOD should be calculated using the timer
+ interrupt frequency.
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index bf9f730..eff6874 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -618,7 +618,7 @@ void __init bcm2708_init(void)
+ #endif
+ }
+ 
+-#define TIMER_PERIOD 10000	/* HZ in microsecs */
++#define TIMER_PERIOD DIV_ROUND_CLOSEST(STC_FREQ_HZ, HZ)
+ 
+ static void timer_set_mode(enum clock_event_mode mode,
+ 			   struct clock_event_device *clk)
+-- 
+1.7.10
+
+From c9ac8270d147da27526569cf4da29892c9523b7c Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Mon, 7 May 2012 10:45:36 +0100
+Subject: [PATCH] dwc_common_port: remove unused cruft with onerous
+ dependencies
+
+The dwc_common_port library used by the dwc_otg includes bignumber and
+crypto functions which require 64x64 multiplication functions. Remove
+this dead code.
+
+Signed-off-by: Chris Boot <bootc@bootc.net>
+---
+ drivers/usb/host/dwc_common_port/Makefile          |    4 +-
+ .../usb/host/dwc_common_port/dwc_common_linux.c    |  109 ----
+ drivers/usb/host/dwc_common_port/dwc_crypto.c      |  306 ----------
+ drivers/usb/host/dwc_common_port/dwc_crypto.h      |  103 ----
+ drivers/usb/host/dwc_common_port/dwc_dh.c          |  286 ---------
+ drivers/usb/host/dwc_common_port/dwc_dh.h          |   98 ---
+ drivers/usb/host/dwc_common_port/dwc_modpow.c      |  622 --------------------
+ drivers/usb/host/dwc_common_port/dwc_modpow.h      |   26 -
+ 8 files changed, 2 insertions(+), 1552 deletions(-)
+ delete mode 100644 drivers/usb/host/dwc_common_port/dwc_crypto.c
+ delete mode 100644 drivers/usb/host/dwc_common_port/dwc_crypto.h
+ delete mode 100644 drivers/usb/host/dwc_common_port/dwc_dh.c
+ delete mode 100644 drivers/usb/host/dwc_common_port/dwc_dh.h
+ delete mode 100644 drivers/usb/host/dwc_common_port/dwc_modpow.c
+ delete mode 100644 drivers/usb/host/dwc_common_port/dwc_modpow.h
+
+diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile
+index b1a74eb..b593b08 100644
+--- a/drivers/usb/host/dwc_common_port/Makefile
++++ b/drivers/usb/host/dwc_common_port/Makefile
+@@ -12,8 +12,8 @@ endif
+ CPPFLAGS	+= -DDWC_LINUX
+ 
+ obj-$(CONFIG_USB_DWCOTG)	+= dwc_common_port_lib.o
+-dwc_common_port_lib-objs	:= dwc_cc.o dwc_modpow.o dwc_dh.o \
+-				   dwc_crypto.o dwc_notifier.o \
++dwc_common_port_lib-objs	:= dwc_cc.o \
++				   dwc_notifier.o \
+ 				   dwc_common_linux.o dwc_mem.o
+ 
+ kernrelwd := $(subst ., ,$(KERNELRELEASE))
+diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
+index f269b39..8ac42a2 100644
+--- a/drivers/usb/host/dwc_common_port/dwc_common_linux.c
++++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
+@@ -1,7 +1,4 @@
+ #include "dwc_cc.h"
+-#include "dwc_modpow.h"
+-#include "dwc_dh.h"
+-#include "dwc_crypto.h"
+ #include "dwc_notifier.h"
+ 
+ #include <linux/kernel.h>
+@@ -51,24 +48,6 @@ static void dwc_common_port_exit_module(void)
+ EXPORT_SYMBOL(dwc_cc_cdid);
+ EXPORT_SYMBOL(dwc_cc_name);
+ 
+-#ifndef CONFIG_MACH_IPMATE
+-/* Modpow */
+-EXPORT_SYMBOL(dwc_modpow);
+-/* DH */
+-EXPORT_SYMBOL(dwc_dh_modpow);
+-EXPORT_SYMBOL(dwc_dh_derive_keys);
+-EXPORT_SYMBOL(dwc_dh_pk);
+-#endif /* CONFIG_MACH_IPMATE  */
+-/* Crypto */
+-EXPORT_SYMBOL(dwc_wusb_aes_encrypt);
+-EXPORT_SYMBOL(dwc_wusb_cmf);
+-EXPORT_SYMBOL(dwc_wusb_prf);
+-EXPORT_SYMBOL(dwc_wusb_fill_ccm_nonce);
+-EXPORT_SYMBOL(dwc_wusb_gen_nonce);
+-EXPORT_SYMBOL(dwc_wusb_gen_key);
+-EXPORT_SYMBOL(dwc_wusb_gen_mic);
+-
+-
+ /* Notification */
+ EXPORT_SYMBOL(dwc_alloc_notification_manager);
+ EXPORT_SYMBOL(dwc_free_notification_manager);
+@@ -96,7 +75,6 @@ static void dwc_common_port_exit_module(void)
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/ctype.h>
+-#include <linux/crypto.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
+@@ -457,93 +435,6 @@ void __DWC_FREE(void *addr)
+ }
+ EXPORT_SYMBOL(__DWC_FREE);
+ 
+-/* dwc_crypto.h */
+-
+-void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
+-{
+-	get_random_bytes(buffer, length);
+-}
+-EXPORT_SYMBOL(DWC_RANDOM_BYTES);
+-
+-int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
+-{
+-	struct crypto_blkcipher *tfm;
+-	struct blkcipher_desc desc;
+-	struct scatterlist sgd;
+-	struct scatterlist sgs;
+-
+-	tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+-	if (tfm == NULL) {
+-		printk("failed to load transform for aes CBC\n");
+-		return -1;
+-	}
+-
+-	crypto_blkcipher_setkey(tfm, key, keylen);
+-	crypto_blkcipher_set_iv(tfm, iv, 16);
+-
+-	sg_init_one(&sgd, out, messagelen);
+-	sg_init_one(&sgs, message, messagelen);
+-
+-	desc.tfm = tfm;
+-	desc.flags = 0;
+-
+-	if(crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
+-		crypto_free_blkcipher(tfm);
+-		DWC_ERROR("AES CBC encryption failed");
+-		return -1;
+-	}
+-
+-	crypto_free_blkcipher(tfm);
+-	return 0;
+-}
+-EXPORT_SYMBOL(DWC_AES_CBC);
+-
+-int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
+-{
+-	struct crypto_hash *tfm;
+-	struct hash_desc desc;
+-	struct scatterlist sg;
+-
+-	tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
+-	if (IS_ERR(tfm)) {
+-		DWC_ERROR("Failed to load transform for sha256: %ld\n", PTR_ERR(tfm));
+-		return 0;
+-	}
+-	desc.tfm = tfm;
+-	desc.flags = 0;
+-
+-	sg_init_one(&sg, message, len);
+-	crypto_hash_digest(&desc, &sg, len, out);
+-	crypto_free_hash(tfm);
+-
+-	return 1;
+-}
+-EXPORT_SYMBOL(DWC_SHA256);
+-
+-int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
+-		    uint8_t *key, uint32_t keylen, uint8_t *out)
+-{
+-	struct crypto_hash *tfm;
+-	struct hash_desc desc;
+-	struct scatterlist sg;
+-
+-	tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
+-	if (IS_ERR(tfm)) {
+-		DWC_ERROR("Failed to load transform for hmac(sha256): %ld\n", PTR_ERR(tfm));
+-		return 0;
+-	}
+-	desc.tfm = tfm;
+-	desc.flags = 0;
+-
+-	sg_init_one(&sg, message, messagelen);
+-	crypto_hash_setkey(tfm, key, keylen);
+-	crypto_hash_digest(&desc, &sg, messagelen, out);
+-	crypto_free_hash(tfm);
+-
+-	return 1;
+-}
+-EXPORT_SYMBOL(DWC_HMAC_SHA256);
+-
+ /* Byte Ordering Conversions. */
+ uint32_t DWC_CPU_TO_LE32(void *p)
+ {
+diff --git a/drivers/usb/host/dwc_common_port/dwc_crypto.c b/drivers/usb/host/dwc_common_port/dwc_crypto.c
+deleted file mode 100644
+index 747840e..0000000
+--- a/drivers/usb/host/dwc_common_port/dwc_crypto.c
++++ /dev/null
+@@ -1,306 +0,0 @@
+-/* =========================================================================
+- * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_crypto.c $
+- * $Revision: #1 $
+- * $Date: 2008/12/21 $
+- * $Change: 1156609 $
+- *
+- * Synopsys Portability Library Software and documentation
+- * (hereinafter, "Software") is an Unsupported proprietary work of
+- * Synopsys, Inc. unless otherwise expressly agreed to in writing
+- * between Synopsys and you.
+- *
+- * The Software IS NOT an item of Licensed Software or Licensed Product
+- * under any End User Software License Agreement or Agreement for
+- * Licensed Product with Synopsys or any supplement thereto. You are
+- * permitted to use and redistribute this Software in source and binary
+- * forms, with or without modification, provided that redistributions
+- * of source code must retain this notice. You may not view, use,
+- * disclose, copy or distribute this file or any information contained
+- * herein except pursuant to this license grant from Synopsys. If you
+- * do not agree with this notice, including the disclaimer below, then
+- * you are not authorized to use the Software.
+- *
+- * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+- * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+- * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
+- * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+- * DAMAGE.
+- * ========================================================================= */
+-
+-/** @file
+- * This file contains the WUSB cryptographic routines.
+- */
+-
+-#include "dwc_crypto.h"
+-#include "usb.h"
+-
+-#ifdef DEBUG
+-static inline void dump_bytes(char *name, uint8_t *bytes, int len)
+-{
+-	int i;
+-	DWC_PRINTF("%s: ", name);
+-	for (i=0; i<len; i++) {
+-		DWC_PRINTF("%02x ", bytes[i]);
+-	}
+-	DWC_PRINTF("\n");
+-}
+-#else
+-#define dump_bytes(x...)
+-#endif
+-
+-/* Display a block */
+-void show_block(const u8 *blk, const char *prefix, const char *suffix, int a)
+-{
+-#ifdef DEBUG_CRYPTO
+-	int i, blksize = 16;
+-
+-	DWC_DEBUG("%s", prefix);
+-
+-	if (suffix == NULL) {
+-		suffix = "\n";
+-		blksize = a;
+-	}
+-
+-	for (i = 0; i < blksize; i++)
+-		DWC_PRINT("%02x%s", *blk++, ((i & 3) == 3) ? "  " : " ");
+-	DWC_PRINT(suffix);
+-
+-#endif
+-}
+-
+-/**
+- * Encrypts an array of bytes using the AES encryption engine.
+- * If <code>dst</code> == <code>src</code>, then the bytes will be encrypted
+- * in-place.
+- *
+- * @return  0 on success, negative error code on error.
+- */
+-int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst)
+-{
+-	u8 block_t[16];
+-	DWC_MEMSET(block_t, 0, 16);
+-
+-	return DWC_AES_CBC(src, 16, key, 16, block_t, dst);
+-}
+-
+-/**
+- * The CCM-MAC-FUNCTION described in section 6.5 of the WUSB spec.
+- * This function takes a data string and returns the encrypted CBC
+- * Counter-mode MIC.
+- *
+- * @param key     The 128-bit symmetric key.
+- * @param nonce   The CCM nonce.
+- * @param label   The unique 14-byte ASCII text label.
+- * @param bytes   The byte array to be encrypted.
+- * @param len     Length of the byte array.
+- * @param result  Byte array to receive the 8-byte encrypted MIC.
+- */
+-void dwc_wusb_cmf(u8 *key, u8 *nonce,
+-		  char *label, u8 *bytes, int len, u8 *result)
+-{
+-	u8 block_m[16];
+-	u8 block_x[16];
+-	u8 block_t[8];
+-	int idx, blkNum;
+-	u16 la = (u16)(len + 14);
+-
+-	/* Set the AES-128 key */
+-	//dwc_aes_setkey(tfm, key, 16);
+-
+-	/* Fill block B0 from flags = 0x59, N, and l(m) = 0 */
+-	block_m[0] = 0x59;
+-	for (idx = 0; idx < 13; idx++)
+-		block_m[idx + 1] = nonce[idx];
+-	block_m[14] = 0;
+-	block_m[15] = 0;
+-
+-	/* Produce the CBC IV */
+-	dwc_wusb_aes_encrypt(block_m, key, block_x);
+-	show_block(block_m, "CBC IV in: ", "\n", 0);
+-	show_block(block_x, "CBC IV out:", "\n", 0);
+-
+-	/* Fill block B1 from l(a) = Blen + 14, and A */
+-	block_x[0] ^= (u8)(la >> 8);
+-	block_x[1] ^= (u8)la;
+-	for (idx = 0; idx < 14; idx++)
+-		block_x[idx + 2] ^= label[idx];
+-	show_block(block_x, "After xor: ", "b1\n", 16);
+-
+-	dwc_wusb_aes_encrypt(block_x, key, block_x);
+-	show_block(block_x, "After AES: ", "b1\n", 16);
+-
+-	idx = 0;
+-	blkNum = 0;
+-
+-	/* Fill remaining blocks with B */
+-	while (len-- > 0) {
+-		block_x[idx] ^= *bytes++;
+-		if (++idx >= 16) {
+-			idx = 0;
+-			show_block(block_x, "After xor: ", "\n", blkNum);
+-			dwc_wusb_aes_encrypt(block_x, key, block_x);
+-			show_block(block_x, "After AES: ", "\n", blkNum);
+-			blkNum++;
+-		}
+-	}
+-
+-	/* Handle partial last block */
+-	if (idx > 0) {
+-		show_block(block_x, "After xor: ", "\n", blkNum);
+-		dwc_wusb_aes_encrypt(block_x, key, block_x);
+-		show_block(block_x, "After AES: ", "\n", blkNum);
+-	}
+-
+-	/* Save the MIC tag */
+-	DWC_MEMCPY(block_t, block_x, 8);
+-	show_block(block_t, "MIC tag  : ", NULL, 8);
+-
+-	/* Fill block A0 from flags = 0x01, N, and counter = 0 */
+-	block_m[0] = 0x01;
+-	block_m[14] = 0;
+-	block_m[15] = 0;
+-
+-	/* Encrypt the counter */
+-	dwc_wusb_aes_encrypt(block_m, key, block_x);
+-	show_block(block_x, "CTR[MIC] : ", NULL, 8);
+-
+-	/* XOR with MIC tag */
+-	for (idx = 0; idx < 8; idx++) {
+-		block_t[idx] ^= block_x[idx];
+-	}
+-
+-	/* Return result to caller */
+-	DWC_MEMCPY(result, block_t, 8);
+-	show_block(result, "CCM-MIC  : ", NULL, 8);
+-
+-}
+-
+-/**
+- * The PRF function described in section 6.5 of the WUSB spec. This function
+- * concatenates MIC values returned from dwc_cmf() to create a value of
+- * the requested length.
+- *
+- * @param prf_len  Length of the PRF function in bits (64, 128, or 256).
+- * @param key, nonce, label, bytes, len  Same as for dwc_cmf().
+- * @param result   Byte array to receive the result.
+- */
+-void dwc_wusb_prf(int prf_len, u8 *key,
+-		  u8 *nonce, char *label, u8 *bytes, int len, u8 *result)
+-{
+-	int i;
+-
+-	nonce[0] = 0;
+-	for (i = 0; i < prf_len >> 6; i++, nonce[0]++) {
+-		dwc_wusb_cmf(key, nonce, label, bytes, len, result);
+-		result += 8;
+-	}
+-}
+-
+-/**
+- * Fills in CCM Nonce per the WUSB spec.
+- *
+- * @param[in] haddr Host address.
+- * @param[in] daddr Device address.
+- * @param[in] tkid Session Key(PTK) identifier.
+- * @param[out] nonce Pointer to where the CCM Nonce output is to be written.
+- */
+-void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid,
+-			     uint8_t *nonce)
+-{
+-
+-	DWC_DEBUG("%s %x %x\n", __func__, daddr, haddr);
+-
+-	DWC_MEMSET(&nonce[0], 0, 16);
+-
+-	DWC_MEMCPY(&nonce[6], tkid, 3);
+-	nonce[9] = daddr & 0xFF;
+-	nonce[10] = (daddr >> 8) & 0xFF;
+-	nonce[11] = haddr & 0xFF;
+-	nonce[12] = (haddr >> 8) & 0xFF;
+-
+-	dump_bytes("CCM nonce", nonce, 16);
+-}
+-
+-/**
+- * Generates a 16-byte cryptographic-grade random number for the Host/Device
+- * Nonce.
+- */
+-void dwc_wusb_gen_nonce(uint16_t addr, uint8_t *nonce)
+-{
+-	uint8_t inonce[16];
+-	uint32_t temp[4];
+-
+-	/* Fill in the Nonce */
+-	DWC_MEMSET(&inonce[0], 0, sizeof(inonce));
+-	inonce[9] = addr & 0xFF;
+-	inonce[10] = (addr >> 8) & 0xFF;
+-	inonce[11] = inonce[9];
+-	inonce[12] = inonce[10];
+-
+-	/* Collect "randomness samples" */
+-	DWC_RANDOM_BYTES((uint8_t *)temp, 16);
+-
+-	dwc_wusb_prf_128((uint8_t *)temp, nonce,
+-			 "Random Numbers", (uint8_t *)temp, sizeof(temp),
+-			 nonce);
+-}
+-
+-/**
+- * Generates the Session Key (PTK) and Key Confirmation Key (KCK) per the
+- * WUSB spec.
+- *
+- * @param[in] ccm_nonce Pointer to CCM Nonce.
+- * @param[in] mk Master Key to derive the session from
+- * @param[in] hnonce Pointer to Host Nonce.
+- * @param[in] dnonce Pointer to Device Nonce.
+- * @param[out] kck Pointer to where the KCK output is to be written.
+- * @param[out] ptk Pointer to where the PTK output is to be written.
+- */
+-void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk, uint8_t *hnonce,
+-		      uint8_t *dnonce, uint8_t *kck, uint8_t *ptk)
+-{
+-	uint8_t idata[32];
+-	uint8_t odata[32];
+-
+-	dump_bytes("ck", mk, 16);
+-	dump_bytes("hnonce", hnonce, 16);
+-	dump_bytes("dnonce", dnonce, 16);
+-
+-	/* The data is the HNonce and DNonce concatenated */
+-	DWC_MEMCPY(&idata[0], hnonce, 16);
+-	DWC_MEMCPY(&idata[16], dnonce, 16);
+-
+-	dwc_wusb_prf_256(mk, ccm_nonce, "Pair-wise keys", idata, 32, odata);
+-
+-	/* Low 16 bytes of the result is the KCK, high 16 is the PTK */
+-	DWC_MEMCPY(kck, &odata[0], 16);
+-	DWC_MEMCPY(ptk, &odata[16], 16);
+-
+-	dump_bytes("kck", kck, 16);
+-	dump_bytes("ptk", ptk, 16);
+-}
+-
+-/**
+- * Generates the Message Integrity Code over the Handshake data per the
+- * WUSB spec.
+- *
+- * @param ccm_nonce Pointer to CCM Nonce.
+- * @param kck   Pointer to Key Confirmation Key.
+- * @param data  Pointer to Handshake data to be checked.
+- * @param mic   Pointer to where the MIC output is to be written.
+- */
+-void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t *kck,
+-		      uint8_t *data, uint8_t *mic)
+-{
+-
+-	dwc_wusb_prf_64(kck, ccm_nonce, "out-of-bandMIC",
+-			data, WUSB_HANDSHAKE_LEN_FOR_MIC, mic);
+-}
+-
+diff --git a/drivers/usb/host/dwc_common_port/dwc_crypto.h b/drivers/usb/host/dwc_common_port/dwc_crypto.h
+deleted file mode 100644
+index 219d961..0000000
+--- a/drivers/usb/host/dwc_common_port/dwc_crypto.h
++++ /dev/null
+@@ -1,103 +0,0 @@
+-/* =========================================================================
+- * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_crypto.h $
+- * $Revision: #1 $
+- * $Date: 2008/12/21 $
+- * $Change: 1156609 $
+- *
+- * Synopsys Portability Library Software and documentation
+- * (hereinafter, "Software") is an Unsupported proprietary work of
+- * Synopsys, Inc. unless otherwise expressly agreed to in writing
+- * between Synopsys and you.
+- *
+- * The Software IS NOT an item of Licensed Software or Licensed Product
+- * under any End User Software License Agreement or Agreement for
+- * Licensed Product with Synopsys or any supplement thereto. You are
+- * permitted to use and redistribute this Software in source and binary
+- * forms, with or without modification, provided that redistributions
+- * of source code must retain this notice. You may not view, use,
+- * disclose, copy or distribute this file or any information contained
+- * herein except pursuant to this license grant from Synopsys. If you
+- * do not agree with this notice, including the disclaimer below, then
+- * you are not authorized to use the Software.
+- *
+- * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+- * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+- * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
+- * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+- * DAMAGE.
+- * ========================================================================= */
+-
+-#ifndef _DWC_CRYPTO_H_
+-#define _DWC_CRYPTO_H_
+-
+-/** @file
+- *
+- * This file contains declarations for the WUSB Cryptographic routines as
+- * defined in the WUSB spec.  They are only to be used internally by the DWC UWB
+- * modules.
+- */
+-
+-#include "dwc_os.h"
+-
+-int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst);
+-
+-void dwc_wusb_cmf(u8 *key, u8 *nonce,
+-		  char *label, u8 *bytes, int len, u8 *result);
+-void dwc_wusb_prf(int prf_len, u8 *key,
+-		  u8 *nonce, char *label, u8 *bytes, int len, u8 *result);
+-
+-/**
+- * The PRF-64 function described in section 6.5 of the WUSB spec.
+- *
+- * @param key, nonce, label, bytes, len, result  Same as for dwc_prf().
+- */
+-static inline void dwc_wusb_prf_64(u8 *key, u8 *nonce,
+-				   char *label, u8 *bytes, int len, u8 *result)
+-{
+-	dwc_wusb_prf(64, key, nonce, label, bytes, len, result);
+-}
+-
+-/**
+- * The PRF-128 function described in section 6.5 of the WUSB spec.
+- *
+- * @param key, nonce, label, bytes, len, result  Same as for dwc_prf().
+- */
+-static inline void dwc_wusb_prf_128(u8 *key, u8 *nonce,
+-				    char *label, u8 *bytes, int len, u8 *result)
+-{
+-	dwc_wusb_prf(128, key, nonce, label, bytes, len, result);
+-}
+-
+-/**
+- * The PRF-256 function described in section 6.5 of the WUSB spec.
+- *
+- * @param key, nonce, label, bytes, len, result  Same as for dwc_prf().
+- */
+-static inline void dwc_wusb_prf_256(u8 *key, u8 *nonce,
+-				    char *label, u8 *bytes, int len, u8 *result)
+-{
+-	dwc_wusb_prf(256, key, nonce, label, bytes, len, result);
+-}
+-
+-
+-void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid,
+-			       uint8_t *nonce);
+-void dwc_wusb_gen_nonce(uint16_t addr,
+-			  uint8_t *nonce);
+-
+-void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk,
+-			uint8_t *hnonce, uint8_t *dnonce,
+-			uint8_t *kck, uint8_t *ptk);
+-
+-
+-void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t
+-			*kck, uint8_t *data, uint8_t *mic);
+-
+-#endif /* _DWC_CRYPTO_H_ */
+diff --git a/drivers/usb/host/dwc_common_port/dwc_dh.c b/drivers/usb/host/dwc_common_port/dwc_dh.c
+deleted file mode 100644
+index 9529b6a..0000000
+--- a/drivers/usb/host/dwc_common_port/dwc_dh.c
++++ /dev/null
+@@ -1,286 +0,0 @@
+-/* =========================================================================
+- * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_dh.c $
+- * $Revision: #1 $
+- * $Date: 2008/12/21 $
+- * $Change: 1156609 $
+- *
+- * Synopsys Portability Library Software and documentation
+- * (hereinafter, "Software") is an Unsupported proprietary work of
+- * Synopsys, Inc. unless otherwise expressly agreed to in writing
+- * between Synopsys and you.
+- *
+- * The Software IS NOT an item of Licensed Software or Licensed Product
+- * under any End User Software License Agreement or Agreement for
+- * Licensed Product with Synopsys or any supplement thereto. You are
+- * permitted to use and redistribute this Software in source and binary
+- * forms, with or without modification, provided that redistributions
+- * of source code must retain this notice. You may not view, use,
+- * disclose, copy or distribute this file or any information contained
+- * herein except pursuant to this license grant from Synopsys. If you
+- * do not agree with this notice, including the disclaimer below, then
+- * you are not authorized to use the Software.
+- *
+- * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+- * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+- * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
+- * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+- * DAMAGE.
+- * ========================================================================= */
+-#ifndef CONFIG_MACH_IPMATE
+-#include "dwc_dh.h"
+-#include "dwc_modpow.h"
+-
+-#ifdef DEBUG
+-/* This function prints out a buffer in the format described in the Association
+- * Model specification. */
+-static void dh_dump(char *str, void *_num, int len)
+-{
+-	uint8_t *num = _num;
+-	int i;
+-	DWC_PRINTF("%s\n", str);
+-	for (i = 0; i < len; i ++) {
+-		DWC_PRINTF("%02x", num[i]);
+-		if (((i + 1) % 2) == 0) DWC_PRINTF(" ");
+-		if (((i + 1) % 26) == 0) DWC_PRINTF("\n");
+-	}
+-
+-	DWC_PRINTF("\n");
+-}
+-#else
+-#define dh_dump(_x...) do {; } while(0)
+-#endif
+-
+-/* Constant g value */
+-static __u32 dh_g[] = {
+-	0x02000000,
+-};
+-
+-/* Constant p value */
+-static __u32 dh_p[] = {
+-	0xFFFFFFFF, 0xFFFFFFFF, 0xA2DA0FC9, 0x34C26821, 0x8B62C6C4, 0xD11CDC80, 0x084E0229, 0x74CC678A,
+-	0xA6BE0B02, 0x229B133B, 0x79084A51, 0xDD04348E, 0xB31995EF, 0x1B433ACD, 0x6D0A2B30, 0x37145FF2,
+-	0x6D35E14F, 0x45C2516D, 0x76B585E4, 0xC67E5E62, 0xE9424CF4, 0x6BED37A6, 0xB65CFF0B, 0xEDB706F4,
+-	0xFB6B38EE, 0xA59F895A, 0x11249FAE, 0xE61F4B7C, 0x51662849, 0x3D5BE4EC, 0xB87C00C2, 0x05BF63A1,
+-	0x3648DA98, 0x9AD3551C, 0xA83F1669, 0x5FCF24FD, 0x235D6583, 0x96ADA3DC, 0x56F3621C, 0xBB528520,
+-	0x0729D59E, 0x6D969670, 0x4E350C67, 0x0498BC4A, 0x086C74F1, 0x7C2118CA, 0x465E9032, 0x3BCE362E,
+-	0x2C779EE3, 0x03860E18, 0xA283279B, 0x8FA207EC, 0xF05DC5B5, 0xC9524C6F, 0xF6CB2BDE, 0x18175895,
+-	0x7C499539, 0xE56A95EA, 0x1826D215, 0x1005FA98, 0x5A8E7215, 0x2DC4AA8A, 0x0D1733AD, 0x337A5004,
+-	0xAB2155A8, 0x64BA1CDF, 0x0485FBEC, 0x0AEFDB58, 0x5771EA8A, 0x7D0C065D, 0x850F97B3, 0xC7E4E1A6,
+-	0x8CAEF5AB, 0xD73309DB, 0xE0948C1E, 0x9D61254A, 0x26D2E3CE, 0x6BEED21A, 0x06FA2FF1, 0x64088AD9,
+-	0x730276D8, 0x646AC83E, 0x182B1F52, 0x0C207B17, 0x5717E1BB, 0x6C5D617A, 0xC0880977, 0xE246D9BA,
+-	0xA04FE208, 0x31ABE574, 0xFC5BDB43, 0x8E10FDE0, 0x20D1824B, 0xCAD23AA9, 0xFFFFFFFF, 0xFFFFFFFF,
+-};
+-
+-static void dh_swap_bytes(void *_in, void *_out, uint32_t len)
+-{
+-	uint8_t *in = _in;
+-	uint8_t *out = _out;
+-	int i;
+-	for (i=0; i<len; i++) {
+-		out[i] = in[len-1-i];
+-	}
+-}
+-
+-/* Computes the modular exponentiation (num^exp % mod).  num, exp, and mod are
+- * big endian numbers of size len, in bytes.  Each len value must be a multiple
+- * of 4. */
+-int dwc_dh_modpow(void *num, uint32_t num_len,
+-			 void *exp, uint32_t exp_len,
+-			 void *mod, uint32_t mod_len,
+-			 void *out)
+-{
+-	/* modpow() takes little endian numbers.  AM uses big-endian.  This
+-	 * function swaps bytes of numbers before passing onto modpow. */
+-
+-	int retval = 0;
+-	uint32_t *result;
+-
+-	uint32_t *bignum_num = DWC_ALLOC(num_len + 4);
+-	uint32_t *bignum_exp = DWC_ALLOC(exp_len + 4);
+-	uint32_t *bignum_mod = DWC_ALLOC(mod_len + 4);
+-
+-	dh_swap_bytes(num, &bignum_num[1], num_len);
+-	bignum_num[0] = num_len / 4;
+-
+-	dh_swap_bytes(exp, &bignum_exp[1], exp_len);
+-	bignum_exp[0] = exp_len / 4;
+-
+-	dh_swap_bytes(mod, &bignum_mod[1], mod_len);
+-	bignum_mod[0] = mod_len / 4;
+-
+-	result = dwc_modpow(bignum_num, bignum_exp, bignum_mod);
+-	if (!result) {
+-		retval = -1;
+-		goto dh_modpow_nomem;
+-	}
+-
+-	dh_swap_bytes(&result[1], out, result[0] * 4);
+-	DWC_FREE(result);
+-
+- dh_modpow_nomem:
+-	DWC_FREE(bignum_num);
+-	DWC_FREE(bignum_exp);
+-	DWC_FREE(bignum_mod);
+-	return retval;
+-}
+-
+-
+-int dwc_dh_pk(uint8_t nd, uint8_t *exp, uint8_t *pk, uint8_t *hash)
+-{
+-	int retval;
+-	uint8_t m3[385];
+-
+-#ifndef DH_TEST_VECTORS
+-	DWC_RANDOM_BYTES(exp, 32);
+-#endif
+-
+-	/* Compute the pkd */
+-	if ((retval = dwc_dh_modpow(dh_g, 4,
+-					  exp, 32,
+-					  dh_p, 384, pk))) {
+-		return retval;
+-	}
+-
+-	m3[384] = nd;
+-	DWC_MEMCPY(&m3[0], pk, 384);
+-	DWC_SHA256(m3, 385, hash);
+-
+- 	dh_dump("PK", pk, 384);
+- 	dh_dump("SHA-256(M3)", hash, 32);
+-	return 0;
+-}
+-
+-int dwc_dh_derive_keys(uint8_t nd, uint8_t *pkh, uint8_t *pkd,
+-			     uint8_t *exp, int is_host,
+-			     char *dd, uint8_t *ck, uint8_t *kdk)
+-{
+-	int retval;
+-	uint8_t mv[784];
+-	uint8_t sha_result[32];
+-	uint8_t dhkey[384];
+-	uint8_t shared_secret[384];
+-	char *message;
+-	uint32_t vd;
+-
+-	uint8_t *pk;
+-
+-	if (is_host) {
+-		pk = pkd;
+-	}
+-	else {
+-		pk = pkh;
+-	}
+-
+-	if ((retval = dwc_dh_modpow(pk, 384,
+-					  exp, 32,
+-					  dh_p, 384, shared_secret))) {
+-		return retval;
+-	}
+-	dh_dump("Shared Secret", shared_secret, 384);
+-
+-	DWC_SHA256(shared_secret, 384, dhkey);
+-	dh_dump("DHKEY", dhkey, 384);
+-
+-	DWC_MEMCPY(&mv[0], pkd, 384);
+-	DWC_MEMCPY(&mv[384], pkh, 384);
+-	DWC_MEMCPY(&mv[768], "displayed digest", 16);
+-	dh_dump("MV", mv, 784);
+-
+-	DWC_SHA256(mv, 784, sha_result);
+-	dh_dump("SHA-256(MV)", sha_result, 32);
+-	dh_dump("First 32-bits of SHA-256(MV)", sha_result, 4);
+-
+-	dh_swap_bytes(sha_result, &vd, 4);
+-#ifdef DEBUG
+-	DWC_PRINTF("Vd (decimal) = %d\n", vd);
+-#endif
+-
+-	switch (nd) {
+-	case 2:
+-		vd = vd % 100;
+-		DWC_SPRINTF(dd, "%02d", vd);
+-		break;
+-	case 3:
+-		vd = vd % 1000;
+-		DWC_SPRINTF(dd, "%03d", vd);
+-		break;
+-	case 4:
+-		vd = vd % 10000;
+-		DWC_SPRINTF(dd, "%04d", vd);
+-		break;
+-	}
+-#ifdef DEBUG
+-	DWC_PRINTF("Display Digits: %s\n", dd);
+-#endif
+-
+-	message = "connection key";
+-	DWC_HMAC_SHA256(message, DWC_STRLEN(message), dhkey, 32, sha_result);
+- 	dh_dump("HMAC(SHA-256, DHKey, connection key)", sha_result, 32);
+-	DWC_MEMCPY(ck, sha_result, 16);
+-
+-	message = "key derivation key";
+-	DWC_HMAC_SHA256(message, DWC_STRLEN(message), dhkey, 32, sha_result);
+- 	dh_dump("HMAC(SHA-256, DHKey, key derivation key)", sha_result, 32);
+-	DWC_MEMCPY(kdk, sha_result, 32);
+-
+-	return 0;
+-}
+-
+-
+-#ifdef DH_TEST_VECTORS
+-
+-static __u8 dh_a[] = {
+-	0x44, 0x00, 0x51, 0xd6,
+-	0xf0, 0xb5, 0x5e, 0xa9,
+-	0x67, 0xab, 0x31, 0xc6,
+-	0x8a, 0x8b, 0x5e, 0x37,
+-	0xd9, 0x10, 0xda, 0xe0,
+-	0xe2, 0xd4, 0x59, 0xa4,
+-	0x86, 0x45, 0x9c, 0xaa,
+-	0xdf, 0x36, 0x75, 0x16,
+-};
+-
+-static __u8 dh_b[] = {
+-	0x5d, 0xae, 0xc7, 0x86,
+-	0x79, 0x80, 0xa3, 0x24,
+-	0x8c, 0xe3, 0x57, 0x8f,
+-	0xc7, 0x5f, 0x1b, 0x0f,
+-	0x2d, 0xf8, 0x9d, 0x30,
+-	0x6f, 0xa4, 0x52, 0xcd,
+-	0xe0, 0x7a, 0x04, 0x8a,
+-	0xde, 0xd9, 0x26, 0x56,
+-};
+-
+-void dwc_run_dh_test_vectors(void)
+-{
+-	uint8_t pkd[384];
+-	uint8_t pkh[384];
+-	uint8_t hashd[32];
+-	uint8_t hashh[32];
+-	uint8_t ck[16];
+-	uint8_t kdk[32];
+-	char dd[5];
+-
+-	DWC_PRINTF("\n\n\nDH_TEST_VECTORS\n\n");
+-
+-	/* compute the PKd and SHA-256(PKd || Nd) */
+-	DWC_PRINTF("Computing PKd\n");
+-	dwc_dh_pk(2, dh_a, pkd, hashd);
+-
+-	/* compute the PKd and SHA-256(PKh || Nd) */
+-	DWC_PRINTF("Computing PKh\n");
+-	dwc_dh_pk(2, dh_b, pkh, hashh);
+-
+-	/* compute the dhkey */
+-	dwc_dh_derive_keys(2, pkh, pkd, dh_a, 0, dd, ck, kdk);
+-}
+-#endif /* DH_TEST_VECTORS */
+-
+-#endif /* CONFIG_IPMATE_MACH */
+diff --git a/drivers/usb/host/dwc_common_port/dwc_dh.h b/drivers/usb/host/dwc_common_port/dwc_dh.h
+deleted file mode 100644
+index 5a0e0cd..0000000
+--- a/drivers/usb/host/dwc_common_port/dwc_dh.h
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/* =========================================================================
+- * $File: //dwh/usb_iip/dev/software/dwc_common_port/dwc_dh.h $
+- * $Revision: #1 $
+- * $Date: 2008/12/21 $
+- * $Change: 1156609 $
+- *
+- * Synopsys Portability Library Software and documentation
+- * (hereinafter, "Software") is an Unsupported proprietary work of
+- * Synopsys, Inc. unless otherwise expressly agreed to in writing
+- * between Synopsys and you.
+- *
+- * The Software IS NOT an item of Licensed Software or Licensed Product
+- * under any End User Software License Agreement or Agreement for
+- * Licensed Product with Synopsys or any supplement thereto. You are
+- * permitted to use and redistribute this Software in source and binary
+- * forms, with or without modification, provided that redistributions
+- * of source code must retain this notice. You may not view, use,
+- * disclose, copy or distribute this file or any information contained
+- * herein except pursuant to this license grant from Synopsys. If you
+- * do not agree with this notice, including the disclaimer below, then
+- * you are not authorized to use the Software.
+- *
+- * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+- * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+- * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
+- * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+- * DAMAGE.
+- * ========================================================================= */
+-#ifndef _DWC_DH_H_
+-#define _DWC_DH_H_
+-
+-#include "dwc_os.h"
+-
+-/** @file
+- *
+- * This file defines the common functions on device and host for performing
+- * numeric association as defined in the WUSB spec.  They are only to be
+- * used internally by the DWC UWB modules. */
+-
+-extern int dwc_dh_sha256(uint8_t *message, uint32_t len, uint8_t *out);
+-extern int dwc_dh_hmac_sha256(uint8_t *message, uint32_t messagelen,
+-				     uint8_t *key, uint32_t keylen,
+-				     uint8_t *out);
+-extern int dwc_dh_modpow(void *num, uint32_t num_len,
+-			       void *exp, uint32_t exp_len,
+-			       void *mod, uint32_t mod_len,
+-			       void *out);
+-
+-/** Computes PKD or PKH, and SHA-256(PKd || Nd)
+- *
+- * PK = g^exp mod p.
+- *
+- * Input:
+- * Nd = Number of digits on the device.
+- *
+- * Output:
+- * exp = A 32-byte buffer to be filled with a randomly generated number.
+- *       used as either A or B.
+- * pk = A 384-byte buffer to be filled with the PKH or PKD.
+- * hash = A 32-byte buffer to be filled with SHA-256(PK || ND).
+- */
+-extern int dwc_dh_pk(uint8_t nd, uint8_t *exp, uint8_t *pkd, uint8_t *hash);
+-
+-/** Computes the DHKEY, and VD.
+- *
+- * If called from host, then it will comput DHKEY=PKD^exp % p.
+- * If called from device, then it will comput DHKEY=PKH^exp % p.
+- *
+- * Input:
+- * pkd = The PKD value.
+- * pkh = The PKH value.
+- * exp = The A value (if device) or B value (if host) generated in dwc_wudev_dh_pk.
+- * is_host = Set to non zero if a WUSB host is calling this function.
+- *
+- * Output:
+-
+- * dd = A pointer to an buffer to be set to the displayed digits string to be shown
+- *      to the user.  This buffer should be at 5 bytes long to hold 4 digits plus a
+- *      null termination character.  This buffer can be used directly for display.
+- * ck = A 16-byte buffer to be filled with the CK.
+- * kdk = A 32-byte buffer to be filled with the KDK.
+- */
+-extern int dwc_dh_derive_keys(uint8_t nd, uint8_t *pkh, uint8_t *pkd,
+-			      uint8_t *exp, int is_host,
+-			      char *dd, uint8_t *ck, uint8_t *kdk);
+-
+-#ifdef DH_TEST_VECTORS
+-extern void dwc_run_dh_test_vectors(void);
+-#endif
+-
+-#endif /* _DWC_DH_H_ */
+diff --git a/drivers/usb/host/dwc_common_port/dwc_modpow.c b/drivers/usb/host/dwc_common_port/dwc_modpow.c
+deleted file mode 100644
+index 563332d..0000000
+--- a/drivers/usb/host/dwc_common_port/dwc_modpow.c
++++ /dev/null
+@@ -1,622 +0,0 @@
+-/* Bignum routines adapted from PUTTY sources.  PuTTY copyright notice follows.
+- *
+- * PuTTY is copyright 1997-2007 Simon Tatham.
+- *
+- * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+- * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+- * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
+- * Kuhn, and CORE SDI S.A.
+- *
+- * Permission is hereby granted, free of charge, to any person
+- * obtaining a copy of this software and associated documentation files
+- * (the "Software"), to deal in the Software without restriction,
+- * including without limitation the rights to use, copy, modify, merge,
+- * publish, distribute, sublicense, and/or sell copies of the Software,
+- * and to permit persons to whom the Software is furnished to do so,
+- * subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice shall be
+- * included in all copies or substantial portions of the Software.
+-
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+- * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+- *
+- */
+-
+-#ifndef CONFIG_MACH_IPMATE
+-
+-
+-#include "dwc_modpow.h"
+-
+-#define BIGNUM_INT_MASK  0xFFFFFFFFUL
+-#define BIGNUM_TOP_BIT   0x80000000UL
+-#define BIGNUM_INT_BITS  32
+-
+-
+-static void *snmalloc(size_t n, size_t size)
+-{
+-    void *p;
+-    size *= n;
+-    if (size == 0) size = 1;
+-    p = DWC_ALLOC(size);
+-    return p;
+-}
+-
+-#define snewn(n, type) ((type *)snmalloc((n), sizeof(type)))
+-#define sfree DWC_FREE
+-
+-/*
+- * Usage notes:
+- *  * Do not call the DIVMOD_WORD macro with expressions such as array
+- *    subscripts, as some implementations object to this (see below).
+- *  * Note that none of the division methods below will cope if the
+- *    quotient won't fit into BIGNUM_INT_BITS. Callers should be careful
+- *    to avoid this case.
+- *    If this condition occurs, in the case of the x86 DIV instruction,
+- *    an overflow exception will occur, which (according to a correspondent)
+- *    will manifest on Windows as something like
+- *      0xC0000095: Integer overflow
+- *    The C variant won't give the right answer, either.
+- */
+-
+-#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
+-
+-#if defined __GNUC__ && defined __i386__
+-#define DIVMOD_WORD(q, r, hi, lo, w) \
+-    __asm__("div %2" : \
+-	    "=d" (r), "=a" (q) : \
+-	    "r" (w), "d" (hi), "a" (lo))
+-#else
+-#define DIVMOD_WORD(q, r, hi, lo, w) do { \
+-    BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
+-    q = n / w; \
+-    r = n % w; \
+-} while (0)
+-#endif
+-
+-//    q = n / w;                                
+-//    r = n % w;                                
+-
+-#define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
+-
+-#define BIGNUM_INTERNAL
+-
+-static Bignum newbn(int length)
+-{
+-    Bignum b = snewn(length + 1, BignumInt);
+-    //if (!b)
+-    //abort();		       /* FIXME */
+-    DWC_MEMSET(b, 0, (length + 1) * sizeof(*b));
+-    b[0] = length;
+-    return b;
+-}
+-
+-void freebn(Bignum b)
+-{
+-    /*
+-     * Burn the evidence, just in case.
+-     */
+-    DWC_MEMSET(b, 0, sizeof(b[0]) * (b[0] + 1));
+-    sfree(b);
+-}
+-
+-/*
+- * Compute c = a * b.
+- * Input is in the first len words of a and b.
+- * Result is returned in the first 2*len words of c.
+- */
+-static void internal_mul(BignumInt *a, BignumInt *b,
+-			 BignumInt *c, int len)
+-{
+-    int i, j;
+-    BignumDblInt t;
+-
+-    for (j = 0; j < 2 * len; j++)
+-	c[j] = 0;
+-
+-    for (i = len - 1; i >= 0; i--) {
+-	t = 0;
+-	for (j = len - 1; j >= 0; j--) {
+-	    t += MUL_WORD(a[i], (BignumDblInt) b[j]);
+-	    t += (BignumDblInt) c[i + j + 1];
+-	    c[i + j + 1] = (BignumInt) t;
+-	    t = t >> BIGNUM_INT_BITS;
+-	}
+-	c[i] = (BignumInt) t;
+-    }
+-}
+-
+-static void internal_add_shifted(BignumInt *number,
+-				 unsigned n, int shift)
+-{
+-    int word = 1 + (shift / BIGNUM_INT_BITS);
+-    int bshift = shift % BIGNUM_INT_BITS;
+-    BignumDblInt addend;
+-
+-    addend = (BignumDblInt)n << bshift;
+-
+-    while (addend) {
+-	addend += number[word];
+-	number[word] = (BignumInt) addend & BIGNUM_INT_MASK;
+-	addend >>= BIGNUM_INT_BITS;
+-	word++;
+-    }
+-}
+-
+-/*
+- * Compute a = a % m.
+- * Input in first alen words of a and first mlen words of m.
+- * Output in first alen words of a
+- * (of which first alen-mlen words will be zero).
+- * The MSW of m MUST have its high bit set.
+- * Quotient is accumulated in the `quotient' array, which is a Bignum
+- * rather than the internal bigendian format. Quotient parts are shifted
+- * left by `qshift' before adding into quot.
+- */
+-static void internal_mod(BignumInt *a, int alen,
+-			 BignumInt *m, int mlen,
+-			 BignumInt *quot, int qshift)
+-{
+-    BignumInt m0, m1;
+-    unsigned int h;
+-    int i, k;
+-
+-    m0 = m[0];
+-    if (mlen > 1)
+-	m1 = m[1];
+-    else
+-	m1 = 0;
+-
+-    for (i = 0; i <= alen - mlen; i++) {
+-	BignumDblInt t;
+-	unsigned int q, r, c, ai1;
+-
+-	if (i == 0) {
+-	    h = 0;
+-	} else {
+-	    h = a[i - 1];
+-	    a[i - 1] = 0;
+-	}
+-
+-	if (i == alen - 1)
+-	    ai1 = 0;
+-	else
+-	    ai1 = a[i + 1];
+-
+-	/* Find q = h:a[i] / m0 */
+-	if (h >= m0) {
+-	    /*
+-	     * Special case.
+-	     * 
+-	     * To illustrate it, suppose a BignumInt is 8 bits, and
+-	     * we are dividing (say) A1:23:45:67 by A1:B2:C3. Then
+-	     * our initial division will be 0xA123 / 0xA1, which
+-	     * will give a quotient of 0x100 and a divide overflow.
+-	     * However, the invariants in this division algorithm
+-	     * are not violated, since the full number A1:23:... is
+-	     * _less_ than the quotient prefix A1:B2:... and so the
+-	     * following correction loop would have sorted it out.
+-	     * 
+-	     * In this situation we set q to be the largest
+-	     * quotient we _can_ stomach (0xFF, of course).
+-	     */
+-	    q = BIGNUM_INT_MASK;
+-	} else {
+-	    /* Macro doesn't want an array subscript expression passed
+-	     * into it (see definition), so use a temporary. */
+-	    BignumInt tmplo = a[i];
+-	    DIVMOD_WORD(q, r, h, tmplo, m0);
+-
+-	    /* Refine our estimate of q by looking at
+-	     h:a[i]:a[i+1] / m0:m1 */
+-	    t = MUL_WORD(m1, q);
+-	    if (t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) {
+-		q--;
+-		t -= m1;
+-		r = (r + m0) & BIGNUM_INT_MASK;     /* overflow? */
+-		if (r >= (BignumDblInt) m0 &&
+-		    t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) q--;
+-	    }
+-	}
+-
+-	/* Subtract q * m from a[i...] */
+-	c = 0;
+-	for (k = mlen - 1; k >= 0; k--) {
+-	    t = MUL_WORD(q, m[k]);
+-	    t += c;
+-	    c = (unsigned)(t >> BIGNUM_INT_BITS);
+-	    if ((BignumInt) t > a[i + k])
+-		c++;
+-	    a[i + k] -= (BignumInt) t;
+-	}
+-
+-	/* Add back m in case of borrow */
+-	if (c != h) {
+-	    t = 0;
+-	    for (k = mlen - 1; k >= 0; k--) {
+-		t += m[k];
+-		t += a[i + k];
+-		a[i + k] = (BignumInt) t;
+-		t = t >> BIGNUM_INT_BITS;
+-	    }
+-	    q--;
+-	}
+-	if (quot)
+-	    internal_add_shifted(quot, q, qshift + BIGNUM_INT_BITS * (alen - mlen - i));
+-    }
+-}
+-
+-/*
+- * Compute p % mod.
+- * The most significant word of mod MUST be non-zero.
+- * We assume that the result array is the same size as the mod array.
+- * We optionally write out a quotient if `quotient' is non-NULL.
+- * We can avoid writing out the result if `result' is NULL.
+- */
+-void bigdivmod(Bignum p, Bignum mod, Bignum result, Bignum quotient)
+-{
+-    BignumInt *n, *m;
+-    int mshift;
+-    int plen, mlen, i, j;
+-
+-    /* Allocate m of size mlen, copy mod to m */
+-    /* We use big endian internally */
+-    mlen = mod[0];
+-    m = snewn(mlen, BignumInt);
+-    for (j = 0; j < mlen; j++)
+-	m[j] = mod[mod[0] - j];
+-
+-    /* Shift m left to make msb bit set */
+-    for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)
+-	if ((m[0] << mshift) & BIGNUM_TOP_BIT)
+-	    break;
+-    if (mshift) {
+-	for (i = 0; i < mlen - 1; i++)
+-	    m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));
+-	m[mlen - 1] = m[mlen - 1] << mshift;
+-    }
+-
+-    plen = p[0];
+-    /* Ensure plen > mlen */
+-    if (plen <= mlen)
+-	plen = mlen + 1;
+-
+-    /* Allocate n of size plen, copy p to n */
+-    n = snewn(plen, BignumInt);
+-    for (j = 0; j < plen; j++)
+-	n[j] = 0;
+-    for (j = 1; j <= (int)p[0]; j++)
+-	n[plen - j] = p[j];
+-
+-    /* Main computation */
+-    internal_mod(n, plen, m, mlen, quotient, mshift);
+-
+-    /* Fixup result in case the modulus was shifted */
+-    if (mshift) {
+-	for (i = plen - mlen - 1; i < plen - 1; i++)
+-	    n[i] = (n[i] << mshift) | (n[i + 1] >> (BIGNUM_INT_BITS - mshift));
+-	n[plen - 1] = n[plen - 1] << mshift;
+-	internal_mod(n, plen, m, mlen, quotient, 0);
+-	for (i = plen - 1; i >= plen - mlen; i--)
+-	    n[i] = (n[i] >> mshift) | (n[i - 1] << (BIGNUM_INT_BITS - mshift));
+-    }
+-
+-    /* Copy result to buffer */
+-    if (result) {
+-	for (i = 1; i <= (int)result[0]; i++) {
+-	    int j = plen - i;
+-	    result[i] = j >= 0 ? n[j] : 0;
+-	}
+-    }
+-
+-    /* Free temporary arrays */
+-    for (i = 0; i < mlen; i++)
+-	m[i] = 0;
+-    sfree(m);
+-    for (i = 0; i < plen; i++)
+-	n[i] = 0;
+-    sfree(n);
+-}
+-
+-/*
+- * Simple remainder.
+- */
+-Bignum bigmod(Bignum a, Bignum b)
+-{
+-    Bignum r = newbn(b[0]);
+-    bigdivmod(a, b, r, NULL);
+-    return r;
+-}
+-
+-/*
+- * Compute (base ^ exp) % mod.
+- */
+-Bignum dwc_modpow(Bignum base_in, Bignum exp, Bignum mod)
+-{
+-    BignumInt *a, *b, *n, *m;
+-    int mshift;
+-    int mlen, i, j;
+-    Bignum base, result;
+-
+-    /*
+-     * The most significant word of mod needs to be non-zero. It
+-     * should already be, but let's make sure.
+-     */
+-    //assert(mod[mod[0]] != 0);
+-
+-    /*
+-     * Make sure the base is smaller than the modulus, by reducing
+-     * it modulo the modulus if not.
+-     */
+-    base = bigmod(base_in, mod);
+-
+-    /* Allocate m of size mlen, copy mod to m */
+-    /* We use big endian internally */
+-    mlen = mod[0];
+-    m = snewn(mlen, BignumInt);
+-    for (j = 0; j < mlen; j++)
+-	m[j] = mod[mod[0] - j];
+-
+-    /* Shift m left to make msb bit set */
+-    for (mshift = 0; mshift < BIGNUM_INT_BITS - 1; mshift++)
+-	if ((m[0] << mshift) & BIGNUM_TOP_BIT)
+-	    break;
+-    if (mshift) {
+-	for (i = 0; i < mlen - 1; i++)
+-	    m[i] =
+-		(m[i] << mshift) | (m[i + 1] >>
+-				    (BIGNUM_INT_BITS - mshift));
+-	m[mlen - 1] = m[mlen - 1] << mshift;
+-    }
+-
+-    /* Allocate n of size mlen, copy base to n */
+-    n = snewn(mlen, BignumInt);
+-    i = mlen - base[0];
+-    for (j = 0; j < i; j++)
+-	n[j] = 0;
+-    for (j = 0; j < base[0]; j++)
+-	n[i + j] = base[base[0] - j];
+-
+-    /* Allocate a and b of size 2*mlen. Set a = 1 */
+-    a = snewn(2 * mlen, BignumInt);
+-    b = snewn(2 * mlen, BignumInt);
+-    for (i = 0; i < 2 * mlen; i++)
+-	a[i] = 0;
+-    a[2 * mlen - 1] = 1;
+-
+-    /* Skip leading zero bits of exp. */
+-    i = 0;
+-    j = BIGNUM_INT_BITS - 1;
+-    while (i < exp[0] && (exp[exp[0] - i] & (1 << j)) == 0) {
+-	j--;
+-	if (j < 0) {
+-	    i++;
+-	    j = BIGNUM_INT_BITS - 1;
+-	}
+-    }
+-
+-    /* Main computation */
+-    while (i < exp[0]) {
+-	while (j >= 0) {
+-	    internal_mul(a + mlen, a + mlen, b, mlen);
+-	    internal_mod(b, mlen * 2, m, mlen, NULL, 0);
+-	    if ((exp[exp[0] - i] & (1 << j)) != 0) {
+-		internal_mul(b + mlen, n, a, mlen);
+-		internal_mod(a, mlen * 2, m, mlen, NULL, 0);
+-	    } else {
+-		BignumInt *t;
+-		t = a;
+-		a = b;
+-		b = t;
+-	    }
+-	    j--;
+-	}
+-	i++;
+-	j = BIGNUM_INT_BITS - 1;
+-    }
+-
+-    /* Fixup result in case the modulus was shifted */
+-    if (mshift) {
+-	for (i = mlen - 1; i < 2 * mlen - 1; i++)
+-	    a[i] =
+-		(a[i] << mshift) | (a[i + 1] >>
+-				    (BIGNUM_INT_BITS - mshift));
+-	a[2 * mlen - 1] = a[2 * mlen - 1] << mshift;
+-	internal_mod(a, mlen * 2, m, mlen, NULL, 0);
+-	for (i = 2 * mlen - 1; i >= mlen; i--)
+-	    a[i] =
+-		(a[i] >> mshift) | (a[i - 1] <<
+-				    (BIGNUM_INT_BITS - mshift));
+-    }
+-
+-    /* Copy result to buffer */
+-    result = newbn(mod[0]);
+-    for (i = 0; i < mlen; i++)
+-	result[result[0] - i] = a[i + mlen];
+-    while (result[0] > 1 && result[result[0]] == 0)
+-	result[0]--;
+-
+-    /* Free temporary arrays */
+-    for (i = 0; i < 2 * mlen; i++)
+-	a[i] = 0;
+-    sfree(a);
+-    for (i = 0; i < 2 * mlen; i++)
+-	b[i] = 0;
+-    sfree(b);
+-    for (i = 0; i < mlen; i++)
+-	m[i] = 0;
+-    sfree(m);
+-    for (i = 0; i < mlen; i++)
+-	n[i] = 0;
+-    sfree(n);
+-
+-    freebn(base);
+-
+-    return result;
+-}
+-
+-
+-#ifdef UNITTEST
+-
+-static __u32 dh_p[] = {
+-	96,
+-	0xFFFFFFFF,
+-	0xFFFFFFFF,
+-	0xA93AD2CA,
+-	0x4B82D120,
+-	0xE0FD108E,
+-	0x43DB5BFC,
+-	0x74E5AB31,
+-	0x08E24FA0,
+-	0xBAD946E2,
+-	0x770988C0,
+-	0x7A615D6C,
+-	0xBBE11757,
+-	0x177B200C,
+-	0x521F2B18,
+-	0x3EC86A64,
+-	0xD8760273,
+-	0xD98A0864,
+-	0xF12FFA06,
+-	0x1AD2EE6B,
+-	0xCEE3D226,
+-	0x4A25619D,
+-	0x1E8C94E0,
+-	0xDB0933D7,
+-	0xABF5AE8C,
+-	0xA6E1E4C7,
+-	0xB3970F85,
+-	0x5D060C7D,
+-	0x8AEA7157,
+-	0x58DBEF0A,
+-	0xECFB8504,
+-	0xDF1CBA64,
+-	0xA85521AB,
+-	0x04507A33,
+-	0xAD33170D,
+-	0x8AAAC42D,
+-	0x15728E5A,
+-	0x98FA0510,
+-	0x15D22618,
+-	0xEA956AE5,
+-	0x3995497C,
+-	0x95581718,
+-	0xDE2BCBF6,
+-	0x6F4C52C9,
+-	0xB5C55DF0,
+-	0xEC07A28F,
+-	0x9B2783A2,
+-	0x180E8603,
+-	0xE39E772C,
+-	0x2E36CE3B,
+-	0x32905E46,
+-	0xCA18217C,
+-	0xF1746C08,
+-	0x4ABC9804,
+-	0x670C354E,
+-	0x7096966D,
+-	0x9ED52907,
+-	0x208552BB,
+-	0x1C62F356,
+-	0xDCA3AD96,
+-	0x83655D23,
+-	0xFD24CF5F,
+-	0x69163FA8,
+-	0x1C55D39A,
+-	0x98DA4836,
+-	0xA163BF05,
+-	0xC2007CB8,
+-	0xECE45B3D,
+-	0x49286651,
+-	0x7C4B1FE6,
+-	0xAE9F2411,
+-	0x5A899FA5,
+-	0xEE386BFB,
+-	0xF406B7ED,
+-	0x0BFF5CB6,
+-	0xA637ED6B,
+-	0xF44C42E9,
+-	0x625E7EC6,
+-	0xE485B576,
+-	0x6D51C245,
+-	0x4FE1356D,
+-	0xF25F1437,
+-	0x302B0A6D,
+-	0xCD3A431B,
+-	0xEF9519B3,
+-	0x8E3404DD,
+-	0x514A0879,
+-	0x3B139B22,
+-	0x020BBEA6,
+-	0x8A67CC74,
+-	0x29024E08,
+-	0x80DC1CD1,
+-	0xC4C6628B,
+-	0x2168C234,
+-	0xC90FDAA2,
+-	0xFFFFFFFF,
+-	0xFFFFFFFF,
+-};
+-
+-static __u32 dh_a[] = {
+-	8,
+-	0xdf367516,
+-	0x86459caa,
+-	0xe2d459a4,
+-	0xd910dae0,
+-	0x8a8b5e37,
+-	0x67ab31c6,
+-	0xf0b55ea9,
+-	0x440051d6,
+-};
+-
+-static __u32 dh_b[] = {
+-	8,
+-	0xded92656,
+-	0xe07a048a,
+-	0x6fa452cd,
+-	0x2df89d30,
+-	0xc75f1b0f,
+-	0x8ce3578f, 
+-	0x7980a324,
+-	0x5daec786,
+-};
+-
+-static __u32 dh_g[] = {
+-	1,
+-	2,
+-};
+-
+-int main(void)
+-{
+-	int i;
+-	__u32 *k;
+-	k = modpow(dh_g, dh_a, dh_p);
+-
+-	printf("\n\n");
+-	for (i=0; i<k[0]; i++) {
+-		__u32 word32 = k[k[0] - i];
+-		__u16 l = word32 & 0xffff;
+-		__u16 m = (word32 & 0xffff0000) >> 16;
+-		printf("%04x %04x ", m, l);
+-		if (!((i + 1)%13)) printf("\n");
+-	}
+-	printf("\n\n");
+-
+-	if ((k[0] == 0x60) && (k[1] == 0x28e490e5) && (k[0x60] == 0x5a0d3d4e)) {
+-		printf("PASS\n\n");
+-	}
+-	else {
+-		printf("FAIL\n\n");
+-	}
+-
+-}
+-
+-#endif /* UNITTEST */
+-
+-#endif /* CONFIG_MACH_IPMATE */
+diff --git a/drivers/usb/host/dwc_common_port/dwc_modpow.h b/drivers/usb/host/dwc_common_port/dwc_modpow.h
+deleted file mode 100644
+index 980f9f1..0000000
+--- a/drivers/usb/host/dwc_common_port/dwc_modpow.h
++++ /dev/null
+@@ -1,26 +0,0 @@
+-/*
+- * dwc_modpow.h
+- * See dwc_modpow.c for license and changes
+- */
+-#ifndef _DWC_MODPOW_H
+-#define _DWC_MODPOW_H
+-
+-#include "dwc_os.h"
+-
+-/** @file
+- *
+- * This file defines the module exponentiation function which is only used
+- * internally by the DWC UWB modules for calculation of PKs during numeric
+- * association.  The routine is taken from the PUTTY, an open source terminal
+- * emulator.  The PUTTY License is preserved in the dwc_modpow.c file.
+- *
+- */
+-
+-typedef uint32_t BignumInt;
+-typedef uint64_t BignumDblInt;
+-typedef BignumInt *Bignum;
+-
+-/* Compute modular exponentiaion */
+-extern Bignum dwc_modpow(Bignum base_in, Bignum exp, Bignum mod);
+-
+-#endif /* _LINUX_BIGNUM_H */
+-- 
+1.7.10
+
+From 9592f718fc300e4b40a0b0f9b7c3c2c901144df5 Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Mon, 7 May 2012 10:56:11 +0100
+Subject: [PATCH] arm: remove divdi3, it's not necessary at all
+
+This was added for the DWC OTG driver in commit d5ef856. As we've
+removed the dead code from that driver that depends on this, it is no
+longer required at all.
+
+Signed-off-by: Chris Boot <bootc@bootc.net>
+---
+ arch/arm/boot/compressed/Makefile   |    8 +-
+ arch/arm/boot/compressed/divdi3.c   |  338 -----------------------------------
+ arch/arm/boot/compressed/longlong.h |  151 ----------------
+ 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 ----------------
+ 8 files changed, 2 insertions(+), 1018 deletions(-)
+ delete mode 100644 arch/arm/boot/compressed/divdi3.c
+ delete mode 100644 arch/arm/boot/compressed/longlong.h
+ delete mode 100644 arch/arm/lib/divdi3.c
+ delete mode 100644 arch/arm/lib/longlong.h
+
+diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
+index a441240..0c74a6f 100644
+--- linux-3.3.8/arch/arm/boot/compressed/Makefile.orig	2012-08-15 15:41:02.088642218 -0400
++++ linux-3.3.8/arch/arm/boot/compressed/Makefile	2012-08-15 15:41:38.681205671 -0400
+@@ -147,17 +147,11 @@
+ LDFLAGS_vmlinux += -T
+ 
+ # For __aeabi_uidivmod
+-lib1funcs = $(obj)/lib1funcs.o $(obj)/divdi3.o
++lib1funcs = $(obj)/lib1funcs.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
+diff --git a/arch/arm/boot/compressed/divdi3.c b/arch/arm/boot/compressed/divdi3.c
+deleted file mode 100644
+index 0848d21..0000000
+--- a/arch/arm/boot/compressed/divdi3.c
++++ /dev/null
+@@ -1,338 +0,0 @@
+-/* 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;
+-}
+diff --git a/arch/arm/boot/compressed/longlong.h b/arch/arm/boot/compressed/longlong.h
+deleted file mode 100644
+index 38e0dcc..0000000
+--- a/arch/arm/boot/compressed/longlong.h
++++ /dev/null
+@@ -1,151 +0,0 @@
+-/* 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
+diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
+index 13ed864..aeef960 100644
+--- a/arch/arm/kernel/armksyms.c
++++ b/arch/arm/kernel/armksyms.c
+@@ -46,8 +46,6 @@
+ 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);
+ 
+@@ -136,8 +134,6 @@
+ EXPORT_SYMBOL(__aeabi_uidiv);
+ EXPORT_SYMBOL(__aeabi_uidivmod);
+ EXPORT_SYMBOL(__aeabi_ulcmp);
+-EXPORT_SYMBOL(__aeabi_ldivmod);
+-EXPORT_SYMBOL(__aeabi_uldivmod);
+ #endif
+ 
+ 	/* bitops */
+diff --git a/arch/arm/lib/divdi3.c b/arch/arm/lib/divdi3.c
+deleted file mode 100644
+index 0848d21..0000000
+--- a/arch/arm/lib/divdi3.c
++++ /dev/null
+@@ -1,338 +0,0 @@
+-/* 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;
+-}
+diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
+index 1dfab8b..c562f64 100644
+--- a/arch/arm/lib/lib1funcs.S
++++ b/arch/arm/lib/lib1funcs.S
+@@ -349,33 +349,6 @@ 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:
+diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
+deleted file mode 100644
+index 38e0dcc..0000000
+--- a/arch/arm/lib/longlong.h
++++ /dev/null
+@@ -1,151 +0,0 @@
+-/* 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
+-- 
+1.7.10
+
+--- a/arch/arm/lib/Makefile
++++ b/arch/arm/lib/Makefile
+@@ -14,7 +14,7 @@ lib-y		:= backtrace.o changebit.o csumip
+ 		   ashldi3.o ashrdi3.o lshrdi3.o muldi3.o             \
+ 		   ucmpdi2.o lib1funcs.o div64.o                      \
+ 		   io-readsb.o io-writesb.o io-readsl.o io-writesl.o  \
+-		   call_with_stack.o divdi3.o
++		   call_with_stack.o
+ 
+ mmu-y	:= clear_user.o copy_page.o getuser.o putuser.o
+ 
+From 6b812ebea364ffcc3cb1a75a41765fdd57d0cb0b Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Mon, 7 May 2012 10:58:15 +0100
+Subject: [PATCH 1/4] Remove some patch backup files
+
+Signed-off-by: Chris Boot <bootc@bootc.net>
+---
+ arch/arm/mach-bcm2708/include/mach/irqs.h.orig     |  185 -----------------
+ arch/arm/mach-bcm2708/include/mach/platform.h.orig |  210 --------------------
+ 2 files changed, 395 deletions(-)
+ delete mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h.orig
+ delete mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h.orig
+
+diff --git a/arch/arm/mach-bcm2708/include/mach/irqs.h.orig b/arch/arm/mach-bcm2708/include/mach/irqs.h.orig
+deleted file mode 100644
+index afa7a34..0000000
+--- a/arch/arm/mach-bcm2708/include/mach/irqs.h.orig
++++ /dev/null
+@@ -1,185 +0,0 @@
+-/*
+- *  arch/arm/mach-bcm2708/include/mach/irqs.h
+- *
+- *  Copyright (C) 2010 Broadcom
+- *  Copyright (C) 2003 ARM Limited
+- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- */
+-
+-#include <mach/platform.h>
+-
+-/*
+- *  IRQ interrupts definitions are the same as the INT definitions
+- *  held within platform.h
+- */
+-#define IRQ_ARMCTRL_START     0
+-#define IRQ_TIMER0            (IRQ_ARMCTRL_START + INTERRUPT_TIMER0)
+-#define IRQ_TIMER1            (IRQ_ARMCTRL_START + INTERRUPT_TIMER1)
+-#define IRQ_TIMER2            (IRQ_ARMCTRL_START + INTERRUPT_TIMER2)
+-#define IRQ_TIMER3            (IRQ_ARMCTRL_START + INTERRUPT_TIMER3)
+-#define IRQ_CODEC0            (IRQ_ARMCTRL_START + INTERRUPT_CODEC0)
+-#define IRQ_CODEC1            (IRQ_ARMCTRL_START + INTERRUPT_CODEC1)
+-#define IRQ_CODEC2            (IRQ_ARMCTRL_START + INTERRUPT_CODEC2)
+-#define IRQ_JPEG              (IRQ_ARMCTRL_START + INTERRUPT_JPEG)
+-#define IRQ_ISP               (IRQ_ARMCTRL_START + INTERRUPT_ISP)
+-#define IRQ_USB               (IRQ_ARMCTRL_START + INTERRUPT_USB)
+-#define IRQ_3D                (IRQ_ARMCTRL_START + INTERRUPT_3D)
+-#define IRQ_TRANSPOSER        (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER)
+-#define IRQ_MULTICORESYNC0    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0)
+-#define IRQ_MULTICORESYNC1    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1)
+-#define IRQ_MULTICORESYNC2    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2)
+-#define IRQ_MULTICORESYNC3    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3)
+-#define IRQ_DMA0              (IRQ_ARMCTRL_START + INTERRUPT_DMA0)
+-#define IRQ_DMA1              (IRQ_ARMCTRL_START + INTERRUPT_DMA1)
+-#define IRQ_DMA2              (IRQ_ARMCTRL_START + INTERRUPT_DMA2)
+-#define IRQ_DMA3              (IRQ_ARMCTRL_START + INTERRUPT_DMA3)
+-#define IRQ_DMA4              (IRQ_ARMCTRL_START + INTERRUPT_DMA4)
+-#define IRQ_DMA5              (IRQ_ARMCTRL_START + INTERRUPT_DMA5)
+-#define IRQ_DMA6              (IRQ_ARMCTRL_START + INTERRUPT_DMA6)
+-#define IRQ_DMA7              (IRQ_ARMCTRL_START + INTERRUPT_DMA7)
+-#define IRQ_DMA8              (IRQ_ARMCTRL_START + INTERRUPT_DMA8)
+-#define IRQ_DMA9              (IRQ_ARMCTRL_START + INTERRUPT_DMA9)
+-#define IRQ_DMA10             (IRQ_ARMCTRL_START + INTERRUPT_DMA10)
+-#define IRQ_DMA11             (IRQ_ARMCTRL_START + INTERRUPT_DMA11)
+-#define IRQ_DMA12             (IRQ_ARMCTRL_START + INTERRUPT_DMA12)
+-#define IRQ_AUX               (IRQ_ARMCTRL_START + INTERRUPT_AUX)
+-#define IRQ_ARM               (IRQ_ARMCTRL_START + INTERRUPT_ARM)
+-#define IRQ_VPUDMA            (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA)
+-#define IRQ_HOSTPORT          (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT)
+-#define IRQ_VIDEOSCALER       (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER)
+-#define IRQ_CCP2TX            (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX)
+-#define IRQ_SDC               (IRQ_ARMCTRL_START + INTERRUPT_SDC)
+-#define IRQ_DSI0              (IRQ_ARMCTRL_START + INTERRUPT_DSI0)
+-#define IRQ_AVE               (IRQ_ARMCTRL_START + INTERRUPT_AVE)
+-#define IRQ_CAM0              (IRQ_ARMCTRL_START + INTERRUPT_CAM0)
+-#define IRQ_CAM1              (IRQ_ARMCTRL_START + INTERRUPT_CAM1)
+-#define IRQ_HDMI0             (IRQ_ARMCTRL_START + INTERRUPT_HDMI0)
+-#define IRQ_HDMI1             (IRQ_ARMCTRL_START + INTERRUPT_HDMI1)
+-#define IRQ_PIXELVALVE1       (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1)
+-#define IRQ_I2CSPISLV         (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV)
+-#define IRQ_DSI1              (IRQ_ARMCTRL_START + INTERRUPT_DSI1)
+-#define IRQ_PWA0              (IRQ_ARMCTRL_START + INTERRUPT_PWA0)
+-#define IRQ_PWA1              (IRQ_ARMCTRL_START + INTERRUPT_PWA1)
+-#define IRQ_CPR               (IRQ_ARMCTRL_START + INTERRUPT_CPR)
+-#define IRQ_SMI               (IRQ_ARMCTRL_START + INTERRUPT_SMI)
+-#define IRQ_GPIO0             (IRQ_ARMCTRL_START + INTERRUPT_GPIO0)
+-#define IRQ_GPIO1             (IRQ_ARMCTRL_START + INTERRUPT_GPIO1)
+-#define IRQ_GPIO2             (IRQ_ARMCTRL_START + INTERRUPT_GPIO2)
+-#define IRQ_GPIO3             (IRQ_ARMCTRL_START + INTERRUPT_GPIO3)
+-#define IRQ_I2C               (IRQ_ARMCTRL_START + INTERRUPT_I2C)
+-#define IRQ_SPI               (IRQ_ARMCTRL_START + INTERRUPT_SPI)
+-#define IRQ_I2SPCM            (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM)
+-#define IRQ_SDIO              (IRQ_ARMCTRL_START + INTERRUPT_SDIO)
+-#define IRQ_UART              (IRQ_ARMCTRL_START + INTERRUPT_UART)
+-#define IRQ_SLIMBUS           (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS)
+-#define IRQ_VEC               (IRQ_ARMCTRL_START + INTERRUPT_VEC)
+-#define IRQ_CPG               (IRQ_ARMCTRL_START + INTERRUPT_CPG)
+-#define IRQ_RNG               (IRQ_ARMCTRL_START + INTERRUPT_RNG)
+-#define IRQ_ARASANSDIO        (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO)
+-#define IRQ_AVSPMON           (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON)
+-
+-#define IRQ_ARM_TIMER         (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER)
+-#define IRQ_ARM_MAILBOX       (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX)
+-#define IRQ_ARM_DOORBELL_0    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0)
+-#define IRQ_ARM_DOORBELL_1    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1)
+-#define IRQ_VPU0_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED)
+-#define IRQ_VPU1_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED)
+-#define IRQ_ILLEGAL_TYPE0     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0)
+-#define IRQ_ILLEGAL_TYPE1     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1)
+-#define IRQ_PENDING1          (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
+-#define IRQ_PENDING2          (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
+-
+-/*
+- *  FIQ interrupts definitions are the same as the INT definitions.
+- */
+-#define FIQ_TIMER0            INT_TIMER0
+-#define FIQ_TIMER1            INT_TIMER1
+-#define FIQ_TIMER2            INT_TIMER2
+-#define FIQ_TIMER3            INT_TIMER3
+-#define FIQ_CODEC0            INT_CODEC0
+-#define FIQ_CODEC1            INT_CODEC1
+-#define FIQ_CODEC2            INT_CODEC2
+-#define FIQ_JPEG              INT_JPEG
+-#define FIQ_ISP               INT_ISP
+-#define FIQ_USB               INT_USB
+-#define FIQ_3D                INT_3D
+-#define FIQ_TRANSPOSER        INT_TRANSPOSER
+-#define FIQ_MULTICORESYNC0    INT_MULTICORESYNC0
+-#define FIQ_MULTICORESYNC1    INT_MULTICORESYNC1
+-#define FIQ_MULTICORESYNC2    INT_MULTICORESYNC2
+-#define FIQ_MULTICORESYNC3    INT_MULTICORESYNC3
+-#define FIQ_DMA0              INT_DMA0
+-#define FIQ_DMA1              INT_DMA1
+-#define FIQ_DMA2              INT_DMA2
+-#define FIQ_DMA3              INT_DMA3
+-#define FIQ_DMA4              INT_DMA4
+-#define FIQ_DMA5              INT_DMA5
+-#define FIQ_DMA6              INT_DMA6
+-#define FIQ_DMA7              INT_DMA7
+-#define FIQ_DMA8              INT_DMA8
+-#define FIQ_DMA9              INT_DMA9
+-#define FIQ_DMA10             INT_DMA10
+-#define FIQ_DMA11             INT_DMA11
+-#define FIQ_DMA12             INT_DMA12
+-#define FIQ_AUX               INT_AUX
+-#define FIQ_ARM               INT_ARM
+-#define FIQ_VPUDMA            INT_VPUDMA
+-#define FIQ_HOSTPORT          INT_HOSTPORT
+-#define FIQ_VIDEOSCALER       INT_VIDEOSCALER
+-#define FIQ_CCP2TX            INT_CCP2TX
+-#define FIQ_SDC               INT_SDC
+-#define FIQ_DSI0              INT_DSI0
+-#define FIQ_AVE               INT_AVE
+-#define FIQ_CAM0              INT_CAM0
+-#define FIQ_CAM1              INT_CAM1
+-#define FIQ_HDMI0             INT_HDMI0
+-#define FIQ_HDMI1             INT_HDMI1
+-#define FIQ_PIXELVALVE1       INT_PIXELVALVE1
+-#define FIQ_I2CSPISLV         INT_I2CSPISLV
+-#define FIQ_DSI1              INT_DSI1
+-#define FIQ_PWA0              INT_PWA0
+-#define FIQ_PWA1              INT_PWA1
+-#define FIQ_CPR               INT_CPR
+-#define FIQ_SMI               INT_SMI
+-#define FIQ_GPIO0             INT_GPIO0
+-#define FIQ_GPIO1             INT_GPIO1
+-#define FIQ_GPIO2             INT_GPIO2
+-#define FIQ_GPIO3             INT_GPIO3
+-#define FIQ_I2C               INT_I2C
+-#define FIQ_SPI               INT_SPI
+-#define FIQ_I2SPCM            INT_I2SPCM
+-#define FIQ_SDIO              INT_SDIO
+-#define FIQ_UART              INT_UART
+-#define FIQ_SLIMBUS           INT_SLIMBUS
+-#define FIQ_VEC               INT_VEC
+-#define FIQ_CPG               INT_CPG
+-#define FIQ_RNG               INT_RNG
+-#define FIQ_ARASANSDIO        INT_ARASANSDIO
+-#define FIQ_AVSPMON           INT_AVSPMON
+-
+-#define FIQ_ARM_TIMER         INT_ARM_TIMER
+-#define FIQ_ARM_MAILBOX       INT_ARM_MAILBOX
+-#define FIQ_ARM_DOORBELL_0    INT_ARM_DOORBELL_0
+-#define FIQ_ARM_DOORBELL_1    INT_ARM_DOORBELL_1
+-#define FIQ_VPU0_HALTED       INT_VPU0_HALTED
+-#define FIQ_VPU1_HALTED       INT_VPU1_HALTED
+-#define FIQ_ILLEGAL_TYPE0     INT_ILLEGAL_TYPE0
+-#define FIQ_ILLEGAL_TYPE1     INT_ILLEGAL_TYPE1
+-#define FIQ_PENDING1          INT_PENDING1
+-#define FIQ_PENDING2          INT_PENDING2
+-
+-#define NR_IRQS			      (64 + 21)
+diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h.orig b/arch/arm/mach-bcm2708/include/mach/platform.h.orig
+deleted file mode 100644
+index 90ad9e3..0000000
+--- a/arch/arm/mach-bcm2708/include/mach/platform.h.orig
++++ /dev/null
+@@ -1,210 +0,0 @@
+-/*
+- * 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 */
+-- 
+1.7.10
+
+
+From 2a1275cc191ff7b8fa44b031a9f52aff5718bb94 Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Mon, 7 May 2012 11:21:15 +0100
+Subject: [PATCH 2/4] mach-bcm2708: fix mach/debug-macro.S so that early
+ printk works
+
+Not sure what the original code was trying to do as it was completely
+wrong on many levels. This patch fixes the macro to return the correct
+physical and virtual addresses of the PL011 UART on the RPi.
+
+Note that you need to boot the compressed kernel (zImage) so that the
+UART is configured at boot, or your kernel will hang when it tries to
+access the UART.
+
+Signed-off-by: Chris Boot <bootc@bootc.net>
+---
+ arch/arm/mach-bcm2708/include/mach/debug-macro.S |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/include/mach/debug-macro.S b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
+index 8abbf32..88229d8 100644
+--- a/arch/arm/mach-bcm2708/include/mach/debug-macro.S
++++ b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
+@@ -12,13 +12,11 @@
+  *
+ */
+ 
+-		.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
++#include <mach/platform.h>
++
++		.macro	addruart, rp, rv
++		ldr	\rp, =UART0_BASE
++		ldr	\rv, =IO_ADDRESS(UART0_BASE)
+ 		.endm
+ 
+ #include <asm/hardware/debug-pl01x.S>
+-- 
+1.7.10
+
+
+From 334ad414ec89738d39166b9df2af69bcd75d9815 Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Tue, 8 May 2012 14:50:35 +0100
+Subject: [PATCH 4/4] vcos: add linux/kernel.h include
+
+---
+ .../vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h    |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
+index f841e12..5f82aaf 100644
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
++++ b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
+@@ -26,6 +26,7 @@
+ #include <stddef.h>
+ #include <linux/types.h>
+ #include <linux/bug.h>
++#include <linux/kernel.h>
+ 
+ #define VCOSPRE_ extern
+ #define VCOSPOST_
+-- 
+1.7.10
+
+From f7287d5193cf87b2f8ecdd31140a572cdaa71927 Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Tue, 8 May 2012 14:51:16 +0100
+Subject: [PATCH] bcm2708: update for 3.2 kernel
+
+Signed-off-by: Chris Boot <bootc@bootc.net>
+
+Conflicts:
+
+	arch/arm/Kconfig.debug
+	arch/arm/mach-bcm2708/include/mach/memory.h
+---
+ arch/arm/Kconfig                                 |    2 +
+ arch/arm/Kconfig.debug                           |  185 ++++++++++++++++++++++
+ arch/arm/mach-bcm2708/bcm2708.c                  |   23 ++-
+ arch/arm/mach-bcm2708/include/mach/debug-macro.S |    2 +-
+ arch/arm/mach-bcm2708/include/mach/memory.h      |    6 +-
+ 5 files changed, 207 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index bf9f730..92ad46e 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -23,7 +23,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/serial_8250.h>
+ #include <linux/platform_device.h>
+-#include <linux/sysdev.h>
++#include <linux/syscore_ops.h>
+ #include <linux/interrupt.h>
+ #include <linux/amba/bus.h>
+ #include <linux/amba/clcd.h>
+@@ -34,16 +34,13 @@
+ #include <linux/spi/spi.h>
+ 
+ #include <linux/version.h>
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ #include <linux/clkdev.h>
+-#else
+-#include <asm/clkdev.h>
+-#endif
+ #include <asm/system.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <linux/leds.h>
+ #include <asm/mach-types.h>
++#include <asm/sched_clock.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/flash.h>
+@@ -72,6 +69,8 @@
+  */
+ #define DMA_MASK_BITS_COMMON 32
+ 
++static DEFINE_CLOCK_DATA(cd);
++
+ /* command line parameters */
+ static unsigned boardrev, serial;
+ 
+@@ -175,8 +174,15 @@ static void __init bcm2708_clocksource_init(void)
+ 
+ unsigned long long sched_clock(void)
+ {
+-	return clocksource_cyc2ns(clocksource_stc.read(&clocksource_stc),
+-				  clocksource_stc.mult, clocksource_stc.shift);
++	u32 cyc = clocksource_stc.read(&clocksource_stc);
++	return cyc_to_fixed_sched_clock(&cd, cyc, clocksource_stc.mask,
++			clocksource_stc.mult, clocksource_stc.shift);
++}
++
++static void notrace bcm2708_update_sched_clock(void)
++{
++	u32 cyc = clocksource_stc.read(&clocksource_stc);
++	update_sched_clock(&cd, cyc, clocksource_stc.mask);
+ }
+ 
+ /*
+@@ -696,6 +702,9 @@ static void __init bcm2708_timer_init(void)
+ 	 */
+ 	setup_irq(IRQ_TIMER3, &bcm2708_timer_irq);
+ 
++	init_fixed_sched_clock(&cd, bcm2708_update_sched_clock, 32,
++		STC_FREQ_HZ, clocksource_stc.mult, clocksource_stc.shift);
++
+ 	timer0_clockevent.mult =
+ 	    div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift);
+ 	timer0_clockevent.max_delta_ns =
+diff --git a/arch/arm/mach-bcm2708/include/mach/debug-macro.S b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
+index 88229d8..2d0dc1c 100644
+--- a/arch/arm/mach-bcm2708/include/mach/debug-macro.S
++++ b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
+@@ -14,7 +14,7 @@
+ 
+ #include <mach/platform.h>
+ 
+-		.macro	addruart, rp, rv
++		.macro	addruart, rp, rv, tmp
+ 		ldr	\rp, =UART0_BASE
+ 		ldr	\rv, =IO_ADDRESS(UART0_BASE)
+ 		.endm
+diff --git a/arch/arm/mach-bcm2708/include/mach/memory.h b/arch/arm/mach-bcm2708/include/mach/memory.h
+index e76fb0a..5d47513 100644
+--- a/arch/arm/mach-bcm2708/include/mach/memory.h
++++ b/arch/arm/mach-bcm2708/include/mach/memory.h
+@@ -32,8 +32,8 @@
+ /*
+  * Physical DRAM offset.
+  */
+-#define PLAT_PHYS_OFFSET	 UL(0x00000000)
+-#define ARMMEM_OFFSET    UL(0x00000000)   /* offset in VC of ARM memory */
++#define PLAT_PHYS_OFFSET	UL(0x00000000)
++#define VC_ARMMEM_OFFSET	UL(0x00000000)   /* offset in VC of ARM memory */
+ 
+ #ifdef CONFIG_BCM2708_NOL2CACHE
+  #define _REAL_BUS_OFFSET UL(0xC0000000)   /* don't use L1 or L2 caches */
+@@ -48,7 +48,7 @@
+  * 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 BUS_OFFSET          (VC_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 - PLAT_PHYS_OFFSET))
+-- 
+1.7.10
+
+--- linux-3.3.8.orig/arch/arm/Kconfig	2012-08-15 13:17:48.914124783 -0400
++++ linux-3.3.8/arch/arm/Kconfig	2012-08-15 16:15:20.700499111 -0400
+@@ -966,12 +966,13 @@
+ 	select CPU_V6
+ 	select ARM_AMBA
+ 	select HAVE_CLK
++	select HAVE_SCHED_CLOCK
++	select NEED_MACH_MEMORY_H
+ 	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.
+ 
+--- linux-3.3.8.orig/arch/arm/Kconfig.debug	2012-06-01 03:16:13.000000000 -0400
++++ linux-3.3.8/arch/arm/Kconfig.debug	2012-08-15 16:16:54.629965451 -0400
+@@ -292,6 +292,14 @@
+ 		  Say Y here if you want the debug print routines to direct
+ 		  their output to the serial port on MSM 8960 devices.
+ 
++	config DEBUG_BCM2708_UART0
++		bool "Broadcom BCM2708 UART0 (PL011)"
++		depends on MACH_BCM2708
++		help
++		  Say Y here if you want the debug print routines to direct
++		  their output to UART 0. The port must have been initialised
++		  by the boot-loader before use.
++
+ endchoice
+ 
+ config EARLY_PRINTK
+From 8f1d8e82a88abb9e6ea6ee007cc5724fca748d59 Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc@bootc.net>
+Date: Sun, 15 Jul 2012 16:52:11 +0100
+Subject: [PATCH 1/4] bcm2708: use a constant SC_MULT / SC_SHIFT
+
+The calculated values somehow don't agree with the sched_clock code and
+we end up with warnings like:
+
+sched_clock: wrong multiply/shift: 2097152000>>21 vs calculated 4194304000>>22
+sched_clock: fix multiply/shift to avoid scheduler hiccups
+
+So use the constant values much like arch/arm/mach-tegra/timer.c does.
+
+Signed-off-by: Chris Boot <bootc@bootc.net>
+---
+ arch/arm/mach-bcm2708/bcm2708.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index 92ad46e..b814a35 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -141,9 +141,16 @@ void __init bcm2708_map_io(void)
+ 	iotable_init(bcm2708_io_desc, ARRAY_SIZE(bcm2708_io_desc));
+ }
+ 
+-// The STC is a free running counter that increments at the rate of 1MHz
++/* The STC is a free running counter that increments at the rate of 1MHz */
+ #define STC_FREQ_HZ 1000000
+ 
++/*
++ * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
++ * This gives a resolution of about 1us and a wrap period of about 1h11min.
++ */
++#define SC_MULT		4194304000u
++#define SC_SHIFT	22
++
+ static cycle_t stc_read_cycles(struct clocksource *cs)
+ {
+ 	/* STC: a free running counter that increments at the rate of 1MHz */
+@@ -165,7 +172,6 @@ unsigned long frc_clock_ticks32(void)
+ 
+ static void __init bcm2708_clocksource_init(void)
+ {
+-	// calculate .shift and .mult values and register clocksource
+ 	if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) {
+ 		printk(KERN_ERR "timer: failed to initialize clock "
+ 		       "source %s\n", clocksource_stc.name);
+@@ -176,7 +182,7 @@ unsigned long long sched_clock(void)
+ {
+ 	u32 cyc = clocksource_stc.read(&clocksource_stc);
+ 	return cyc_to_fixed_sched_clock(&cd, cyc, clocksource_stc.mask,
+-			clocksource_stc.mult, clocksource_stc.shift);
++			SC_MULT, SC_SHIFT);
+ }
+ 
+ static void notrace bcm2708_update_sched_clock(void)
+@@ -703,7 +709,7 @@ static void __init bcm2708_timer_init(void)
+ 	setup_irq(IRQ_TIMER3, &bcm2708_timer_irq);
+ 
+ 	init_fixed_sched_clock(&cd, bcm2708_update_sched_clock, 32,
+-		STC_FREQ_HZ, clocksource_stc.mult, clocksource_stc.shift);
++		STC_FREQ_HZ, SC_MULT, SC_SHIFT);
+ 
+ 	timer0_clockevent.mult =
+ 	    div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift);
+-- 
+1.7.10
+
+
+From 20eadb1d5d1b450e7e95b4410e187a51f971f470 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <dc4@broadcom.com>
+Date: Tue, 31 Jul 2012 16:42:03 +0100
+Subject: [PATCH 2/4] Sync with bootc's file
+
+---
+ arch/arm/mach-bcm2708/power.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c
+index d147bb6..256bf1a 100644
+--- a/arch/arm/mach-bcm2708/power.c
++++ b/arch/arm/mach-bcm2708/power.c
+@@ -14,7 +14,6 @@
+ #include <linux/module.h>
+ #include <linux/semaphore.h>
+ #include <linux/bug.h>
+-#include <linux/delay.h>
+ #include <mach/power.h>
+ #include <mach/vcio.h>
+ #include <mach/arm_power.h>
+@@ -97,6 +96,7 @@ int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request)
+ 				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);
+@@ -111,14 +111,14 @@ int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request)
+ 
+ 				if (rc == 0) {
+ 					if (actual != global_request) {
+-						printk(KERN_INFO
+-						     "%s: Fail: prev global %x, new global %x, actual %x request %x, others_request %x\n",
++						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);
++						BUG_ON((others_request & actual)
++						       != others_request);
+ 						request &= actual;
+ 						rc = -EIO;
+ 					}
+-- 
+1.7.10
+
+
+From 8b1821c5aa046ee4816ecbf3000a90cf6b2debc4 Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Thu, 21 Jun 2012 00:57:59 +0200
+Subject: [PATCH 3/4] sdhci-bcm2708: use extension FIFO to buffer DMA
+ transfers
+
+The additional FIFO might speed up transfers in some cases.
+---
+ drivers/mmc/host/sdhci-bcm2708.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 1d50cc6..882ae42 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -79,6 +79,8 @@
+ #define POWER_LAZY_OFF 1
+ #define POWER_ON  2
+ 
++#define REG_EXRDFIFO_EN     0x80
++#define REG_EXRDFIFO_CFG    0x84
+ 
+ /*****************************************************************************\
+  *									     *
+@@ -967,10 +969,12 @@ static ssize_t attr_dma_store(struct device *_dev,
+ 		int on = simple_strtol(buf, NULL, 0);
+ 		if (on) {
+ 			host->flags |= SDHCI_USE_PLATDMA;
++			sdhci_bcm2708_writel(host, 1, REG_EXRDFIFO_EN);
+ 			printk(KERN_INFO "%s: DMA enabled\n",
+ 			       mmc_hostname(host->mmc));
+ 		} else {
+ 			host->flags &= ~(SDHCI_USE_PLATDMA | SDHCI_REQ_USE_DMA);
++			sdhci_bcm2708_writel(host, 0, REG_EXRDFIFO_EN);
+ 			printk(KERN_INFO "%s: DMA disabled\n",
+ 			       mmc_hostname(host->mmc));
+ 		}
+@@ -1399,6 +1403,12 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+ 	ret = device_create_file(&pdev->dev, &dev_attr_dma_wait);
+ 	ret = device_create_file(&pdev->dev, &dev_attr_status);
+ 
++#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
++	/* enable extension fifo for paced DMA transfers */
++	sdhci_bcm2708_writel(host, 1, REG_EXRDFIFO_EN);
++	sdhci_bcm2708_writel(host, 4, REG_EXRDFIFO_CFG);
++#endif
++
+ 	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);
+-- 
+1.7.10
+
+
+From f20f6ae0c3a1338a67be8848f9f2613b9d562b2d Mon Sep 17 00:00:00 2001
+From: Grigori Goronzy <greg@blackbox>
+Date: Tue, 31 Jul 2012 23:18:12 +0200
+Subject: [PATCH 4/4] sdhci-bcm2708: use multiblock-type transfers for single
+ blocks
+
+There are issues with both single block reads (missed completion)
+and writes (data loss in some cases!). Just don't do single block
+transfers anymore, and treat them like multiblock transfers. This
+adds a quirk for this and uses it.
+---
+ drivers/mmc/card/block.c         |    2 +-
+ drivers/mmc/host/sdhci-bcm2708.c |    3 +++
+ include/linux/mmc/host.h         |    1 +
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
+index d62f4cd..b2a844d 100644
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -965,7 +965,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+ 	if (disable_multi && brq->data.blocks > 1)
+ 		brq->data.blocks = 1;
+ 
+-	if (brq->data.blocks > 1 || do_rel_wr) {
++	if (brq->data.blocks > 1 || do_rel_wr || card->host->caps2 & MMC_CAP2_FORCE_MULTIBLOCK) {
+ 		/* SPI multiblock writes terminate using a special
+ 		 * token, not a STOP_TRANSMISSION request.
+ 		 */
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 882ae42..ad44fbe 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -1392,6 +1392,9 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+ 
+     if (allow_highspeed)
+         host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
++
++    /* single block writes cause data loss with some SD cards! */
++    host->mmc->caps2 |= MMC_CAP2_FORCE_MULTIBLOCK;
+ #endif
+ 
+ 	ret = sdhci_add_host(host);
+-- 
+1.7.10
+
+--- linux-3.3.8.orig/include/linux/mmc/host.h	2012-06-01 03:16:13.000000000 -0400
++++ linux-3.3.8/include/linux/mmc/host.h	2012-08-15 16:24:50.641386541 -0400
+@@ -258,6 +258,7 @@
+ #define MMC_CAP2_HS200		(MMC_CAP2_HS200_1_8V_SDR | \
+ 				 MMC_CAP2_HS200_1_2V_SDR)
+ #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
++#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 8)	/* Always use multiblock transfers */
+ 
+ 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
+ 	unsigned int        power_notify_type;
+From c6851e9ade0ea7135cd7bde2e92204d550439b64 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 1 Aug 2012 19:02:14 +0100
+Subject: [PATCH 1/3] Add module parameter for missing_status quirk.
+ sdhci-bcm2708.missing_status=0 may improve interrupt
+ latency
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index ad44fbe..1ac1e64 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -139,6 +139,7 @@ static inline unsigned long int since_ns(hptime_t t)
+ static bool allow_highspeed = 1;
+ static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
+ static bool sync_after_dma = 1;
++static bool missing_status = 1;
+ 
+ #if 0
+ static void hptime_test(void)
+@@ -1271,7 +1272,6 @@ static unsigned int sdhci_bcm2708_missing_status(struct sdhci_host *host)
+ 	.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
+ 	.voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
+ 	.uhs_broken = sdhci_bcm2708_uhs_broken,
+-	.missing_status = sdhci_bcm2708_missing_status,
+ };
+ 
+ /*****************************************************************************\
+@@ -1310,6 +1310,9 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+ 		ret = PTR_ERR(host);
+ 		goto err;
+ 	}
++	if (missing_status) {
++		sdhci_bcm2708_ops.missing_status = sdhci_bcm2708_missing_status;
++	}
+ 
+ 	host->hw_name = "BCM2708_Arasan";
+ 	host->ops = &sdhci_bcm2708_ops;
+@@ -1509,6 +1512,7 @@ static void __exit sdhci_drv_exit(void)
+ module_param(allow_highspeed, bool, 0444);
+ module_param(emmc_clock_freq, int, 0444);
+ module_param(sync_after_dma, bool, 0444);
++module_param(missing_status, bool, 0444);
+ 
+ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+ MODULE_AUTHOR("Broadcom <info@broadcom.com>");
+@@ -1518,5 +1522,6 @@ static void __exit sdhci_drv_exit(void)
+ MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
+ MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
+ MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
++MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
+ 
+ 
+-- 
+1.7.10
+
+
+From b6d5be452c1f10aa3b678d18252e4c2ac0a75878 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 7 Aug 2012 22:24:16 +0100
+Subject: [PATCH 2/3] Some fixed for ALSA. Mute and volume changing should be
+ improved
+
+---
+ sound/arm/bcm2835-ctl.c   |   76 +++++++++++++++++-----------
+ sound/arm/bcm2835-pcm.c   |   24 ++++++---
+ sound/arm/bcm2835-vchiq.c |   34 +++++++++----
+ sound/arm/bcm2835.h       |  123 +++++++--------------------------------------
+ 4 files changed, 106 insertions(+), 151 deletions(-)
+
+diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c
+index f901ddd..0c1b80a 100755
+--- a/sound/arm/bcm2835-ctl.c
++++ b/sound/arm/bcm2835-ctl.c
+@@ -33,29 +33,22 @@
+ 
+ #include "bcm2835.h"
+ 
+-
+-/* functions to convert alsa to chip volume and back. */
+-int alsa2chip(int vol)
+-{
+-	return -((vol << 8) / 100);
+-}
+-
+-int chip2alsa(int vol)
+-{
+-	return -((vol * 100) >> 8);
+-}
++/* volume maximum and minimum in terms of 0.01dB */
++#define CTRL_VOL_MAX 400
++#define CTRL_VOL_MIN -10239 /* originally -10240 */
+ 
+ 
+ static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
+ 				struct snd_ctl_elem_info *uinfo)
+ {
++	audio_info(" ... IN ");
+ 	if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ 		uinfo->count = 1;
+-		uinfo->value.integer.min = -10240;
+-		uinfo->value.integer.max = 400;      /* 2303 */
++		uinfo->value.integer.min = CTRL_VOL_MIN;
++		uinfo->value.integer.max = CTRL_VOL_MAX;      /* 2303 */
+ 	} else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
+-		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
++		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ 		uinfo->count = 1;
+ 		uinfo->value.integer.min = 0;
+ 		uinfo->value.integer.max = 1;
+@@ -63,12 +56,38 @@ static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
+ 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ 		uinfo->count = 1;
+ 		uinfo->value.integer.min = 0;
+-		uinfo->value.integer.max = AUDIO_DEST_MAX-0;
++		uinfo->value.integer.max = AUDIO_DEST_MAX-1;
+ 	}
+-
++	audio_info(" ... OUT ");
+ 	return 0;
+ }
+ 
++/* toggles mute on or off depending on the value of nmute, and returns
++ * 1 if the mute value was changed, otherwise 0
++ */
++static int toggle_mute(struct bcm2835_chip *chip, int nmute)
++{
++	/* if settings are ok, just return 0 */
++	if(chip->mute == nmute)
++		return 0;
++
++	/* if the sound is muted then we need to unmute */
++	if(chip->mute == CTRL_VOL_MUTE)
++	{
++		chip->volume = chip->old_volume; /* copy the old volume back */
++		audio_info("Unmuting, old_volume = %d, volume = %d ...", chip->old_volume, chip->volume);
++	}
++	else /* otherwise we mute */
++	{
++		chip->old_volume = chip->volume;
++		chip->volume = 26214; /* set volume to minimum level AKA mute */
++		audio_info("Muting, old_volume = %d, volume = %d ...", chip->old_volume, chip->volume);
++	}
++
++	chip->mute = nmute;
++	return 1;
++}
++
+ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol,
+ 			       struct snd_ctl_elem_value *ucontrol)
+ {
+@@ -93,9 +112,10 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
+ 	int changed = 0;
+ 
+ 	if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
+-		if (chip->mute) {
+-			chip->mute = 0;
+-			changed = 1;
++		audio_info("Volume change attempted.. volume = %d new_volume = %d", chip->volume, (int)ucontrol->value.integer.value[0]);
++		if (chip->mute == CTRL_VOL_MUTE) {
++			/* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */
++			return 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */
+ 		}
+ 		if (changed
+ 		    || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) {
+@@ -105,11 +125,10 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
+ 		}
+ 
+ 	} else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
+-		/* Not implemented */
+-		if (ucontrol->value.integer.value[0] != chip->mute) {
+-			chip->mute = ucontrol->value.integer.value[0];
+-			changed = 0;
+-		}
++		/* Now implemented */
++		audio_info(" Mute attempted");
++		changed = toggle_mute(chip, ucontrol->value.integer.value[0]);
++
+ 	} else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) {
+ 		if (ucontrol->value.integer.value[0] != chip->dest) {
+ 			chip->dest = ucontrol->value.integer.value[0];
+@@ -125,22 +144,21 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
+ 	return changed;
+ }
+ 
+-static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, -10240, 1, 1);
++static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1);
+ 
+ static struct snd_kcontrol_new snd_bcm2835_ctl[] __devinitdata = {
+ 	{
+ 	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 	 .name = "PCM Playback Volume",
+ 	 .index = 0,
+-	 .access =
+-	 SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE,
++	 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ 	 .private_value = PCM_PLAYBACK_VOLUME,
+ 	 .info = snd_bcm2835_ctl_info,
+ 	 .get = snd_bcm2835_ctl_get,
+ 	 .put = snd_bcm2835_ctl_put,
+ 	 .count = 1,
+ 	 .tlv = {.p = snd_bcm2835_db_scale}
+-	 },
++	},
+ 	{
+ 	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 	 .name = "PCM Playback Switch",
+@@ -162,7 +180,7 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
+ 	 .get = snd_bcm2835_ctl_get,
+ 	 .put = snd_bcm2835_ctl_put,
+ 	 .count = 1,
+-	 },
++	},
+ };
+ 
+ int __devinit snd_bcm2835_new_ctl(bcm2835_chip_t * chip)
+diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c
+index ff3eb4e..6cc80dd 100755
+--- a/sound/arm/bcm2835-pcm.c
++++ b/sound/arm/bcm2835-pcm.c
+@@ -26,11 +26,11 @@
+ 	.rate_max = 48000,
+ 	.channels_min = 1,
+ 	.channels_max = 2,
+-	.buffer_bytes_max = (4 * 8 - 1) * 1024,	/* Needs to be less than audioplay buffer size */
++	.buffer_bytes_max = 32 * 1024,	/* Needs to be less than audioplay buffer size */
+ 	.period_bytes_min = 1 * 1024,
+-	.period_bytes_max = (4 * 8 - 1) * 1024,
++	.period_bytes_max = 32 * 1024,
+ 	.periods_min = 1,
+-	.periods_max = 4 * 8 - 1,
++	.periods_max = 32,
+ };
+ 
+ static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
+@@ -64,14 +64,18 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id)
+ 		    ((alsa_stream->pos + consumed) / alsa_stream->period_size))
+ 			new_period = 1;
+ 	}
+-	audio_debug("updating pos cur: %d + %d max:%d new_period:%d\n",
++	audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n",
+ 		      alsa_stream->pos,
+-		      (consumed /** AUDIO_IPC_BLOCK_BUFFER_SIZE*/ ),
+-		      alsa_stream->buffer_size, new_period);
++		      consumed,
++		      alsa_stream->buffer_size,
++			  (int)(alsa_stream->period_size*alsa_stream->substream->runtime->periods),
++			  frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr),
++			  new_period);
+ 	if (alsa_stream->buffer_size) {
+ 		alsa_stream->pos += consumed;
+ 		alsa_stream->pos %= alsa_stream->buffer_size;
+ 	}
++
+ 	if (alsa_stream->substream) {
+ 		if (new_period)
+ 			snd_pcm_period_elapsed(alsa_stream->substream);
+@@ -135,7 +139,6 @@ static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
+ 	runtime->private_data = alsa_stream;
+ 	runtime->private_free = snd_bcm2835_playback_free;
+ 	runtime->hw = snd_bcm2835_playback_hw;
+-
+ 	/* minimum 16 bytes alignment (for vchiq bulk transfers) */
+ 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+ 				   16);
+@@ -224,6 +227,10 @@ static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	}
+ 
+ 	bcm2835_audio_setup(alsa_stream);
++
++	/* in preparation of the stream, set the controls (volume level) of the stream */
++	bcm2835_audio_set_ctls(alsa_stream->chip);
++
+ 	audio_info(" .. OUT\n");
+ 
+ 	return err;
+@@ -382,7 +389,8 @@ int __devinit snd_bcm2835_new_pcm(bcm2835_chip_t * chip)
+ 	strcpy(pcm->name, "bcm2835 ALSA");
+ 	chip->pcm = pcm;
+ 	chip->dest = AUDIO_DEST_AUTO;
+-	chip->volume = 100;
++	chip->volume = alsa2chip(0);
++	chip->mute = CTRL_VOL_UNMUTE;	/*disable mute on startup */
+ 	/* set operators */
+ 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ 			&snd_bcm2835_playback_ops);
+diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c
+index 23c0aa3..68d838d 100755
+--- a/sound/arm/bcm2835-vchiq.c
++++ b/sound/arm/bcm2835-vchiq.c
+@@ -43,12 +43,18 @@
+ 
+ /* Default VCOS logging level */
+ #define LOG_LEVEL  VCOS_LOG_WARN
+-
+ /* Logging macros (for remapping to other logging mechanisms, i.e., printf) */
+-#define LOG_ERR( fmt, arg... )   vcos_log_error( "%s:%d " fmt, __func__, __LINE__, ##arg)
+-#define LOG_WARN( fmt, arg... )  vcos_log_warn( "%s:%d " fmt, __func__, __LINE__, ##arg)
+-#define LOG_INFO( fmt, arg... )  vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+-#define LOG_DBG( fmt, arg... )   vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++#ifdef AUDIO_DEBUG_ENABLE
++	#define LOG_ERR( fmt, arg... )   pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg)
++	#define LOG_WARN( fmt, arg... )  pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++	#define LOG_INFO( fmt, arg... )  pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++	#define LOG_DBG( fmt, arg... )   pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++#else
++	#define LOG_ERR( fmt, arg... ) vcos_log_error( "%s:%d " fmt, __func__, __LINE__, ##arg)
++	#define LOG_WARN( fmt, arg... ) vcos_log_warn( "%s:%d " fmt, __func__, __LINE__, ##arg)
++	#define LOG_INFO( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++	#define LOG_DBG( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++#endif
+ 
+ typedef struct opaque_AUDIO_INSTANCE_T {
+ 	uint32_t num_connections;
+@@ -103,7 +109,7 @@ int bcm2835_audio_start(bcm2835_alsa_stream_t * alsa_stream)
+ 	LOG_DBG(" .. IN\n");
+ 	if (alsa_stream->my_wq) {
+ 		my_work_t *work = kmalloc(sizeof(my_work_t), GFP_ATOMIC);
+-		/* Queue some work (item 1) */
++		/*--- Queue some work (item 1) ---*/
+ 		if (work) {
+ 			INIT_WORK((struct work_struct *)work, my_wq_function);
+ 			work->alsa_stream = alsa_stream;
+@@ -124,7 +130,7 @@ int bcm2835_audio_stop(bcm2835_alsa_stream_t * alsa_stream)
+ 	LOG_DBG(" .. IN\n");
+ 	if (alsa_stream->my_wq) {
+ 		my_work_t *work = kmalloc(sizeof(my_work_t), GFP_ATOMIC);
+-		/* Queue some work (item 1) */
++		 /*--- Queue some work (item 1) ---*/
+ 		if (work) {
+ 			INIT_WORK((struct work_struct *)work, my_wq_function);
+ 			work->alsa_stream = alsa_stream;
+@@ -142,6 +148,7 @@ int bcm2835_audio_stop(bcm2835_alsa_stream_t * alsa_stream)
+ void my_workqueue_init(bcm2835_alsa_stream_t * alsa_stream)
+ {
+ 	alsa_stream->my_wq = create_workqueue("my_queue");
++	return;
+ }
+ 
+ void my_workqueue_quit(bcm2835_alsa_stream_t * alsa_stream)
+@@ -151,6 +158,7 @@ void my_workqueue_quit(bcm2835_alsa_stream_t * alsa_stream)
+ 		destroy_workqueue(alsa_stream->my_wq);
+ 		alsa_stream->my_wq = NULL;
+ 	}
++	return;
+ }
+ 
+ static void audio_vchi_callback(void *param,
+@@ -501,14 +509,22 @@ int bcm2835_audio_set_ctls(bcm2835_chip_t * chip)
+ 	int i;
+ 	int ret = 0;
+ 	LOG_DBG(" .. IN\n");
++
+ 	/* change ctls for all substreams */
+ 	for (i = 0; i < MAX_SUBSTREAMS; i++) {
+ 		if (chip->avail_substreams & (1 << i)) {
+ 			if (!chip->alsa_stream[i])
++			{
++				LOG_DBG(" No ALSA stream available?! ");
+ 				ret = 0;
+-			else if (bcm2835_audio_set_ctls_chan
++			}
++			else if (bcm2835_audio_set_ctls_chan /* returns 0 on success */
+ 				 (chip->alsa_stream[i], chip) != 0)
+-				ret = -1;
++				 {
++					LOG_DBG("Couldn't set the controls for stream %d", i);
++					ret = -1;
++				 }
++			LOG_DBG(" Controls set for stream %d", i);
+ 		}
+ 	}
+ 	LOG_DBG(" .. OUT ret=%d\n", ret);
+diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h
+index 134a483..3db5e51 100755
+--- a/sound/arm/bcm2835.h
++++ b/sound/arm/bcm2835.h
+@@ -15,8 +15,6 @@
+ #ifndef __SOUND_ARM_BCM2835_H
+ #define __SOUND_ARM_BCM2835_H
+ 
+-#define SUBSTREAM_NUM 1
+-
+ #include <linux/device.h>
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+@@ -27,13 +25,14 @@
+ #include <sound/pcm_params.h>
+ #include <linux/workqueue.h>
+ 
+-/* #define DUMP_RAW_DATA */
+-//#define AUDIO_DEBUG_ENABLE
+-//#define AUDIO_VERBOSE_DEBUG_ENABLE
++/*
++#define AUDIO_DEBUG_ENABLE
++#define AUDIO_VERBOSE_DEBUG_ENABLE
++*.
+ 
+ /* Debug macros */
+-#ifdef AUDIO_DEBUG_ENABLE
+ 
++#ifdef AUDIO_DEBUG_ENABLE
+ #ifdef AUDIO_VERBOSE_DEBUG_ENABLE
+ 
+ #define audio_debug(fmt, arg...)	\
+@@ -44,17 +43,17 @@
+ 
+ #else
+ 
+-#define audio_debug(fmt, arg...)	do {} while (0)
++#define audio_debug(fmt, arg...)
+ 
+-#define audio_info(fmt, arg...)	        do {} while (0)
++#define audio_info(fmt, arg...)
+ 
+ #endif /* AUDIO_VERBOSE_DEBUG_ENABLE */
+ 
+ #else
+ 
+-#define audio_debug(fmt, arg...)	do {} while (0)
++#define audio_debug(fmt, arg...)
+ 
+-#define audio_info(fmt, arg...)		do {} while (0)
++#define audio_info(fmt, arg...)
+ 
+ #endif /* AUDIO_DEBUG_ENABLE */
+ 
+@@ -69,75 +68,15 @@
+ 
+ #define MAX_SUBSTREAMS			(8)
+ #define AVAIL_SUBSTREAMS_MASK		(0xff)
++enum {
++	CTRL_VOL_MUTE,
++	CTRL_VOL_UNMUTE
++};
+ 
+-#define AUDIO_IPC_BLOCK_NUM_BUFFERS    (8)
+-#define AUDIO_IPC_BLOCK_BUFFER_SIZE    (1024*8)
+-
+-#define AUDIO_CONTROL_OFFSET			(0x00)
+-#define CTRL_EN_SHIFT			(0)
+-#define CTRL_EN_MASK			(0x00000001)
+-#define CTRL_PLAY_SHIFT			(1)
+-#define CTRL_PLAY_MASK			(0x00000002)
+-#define CTRL_MUTE_SHIFT			(2)
+-#define CTRL_MUTE_MASK			(0x00000004)
+-#define CTRL_SETUP_SHIFT		(3)
+-#define CTRL_SETUP_MASK			(0x00000008)
+-#define CTRL_FLUSH_SHIFT	    (4)
+-#define CTRL_FLUSH_MASK			(0x00000010)
+-#define CTRL_STOPMODE_SHIFT	    (5)
+-#define CTRL_STOPMODE_MASK		(0x00000020)
+-
+-#define AUDIO_STATUS_OFFSET			(0x04)
+-#define STAT_EN_SHIFT			(0)
+-#define STAT_EN_MASK			(0x00000001)
+-#define STAT_PLAY_SHIFT			(1)
+-#define STAT_PLAY_MASK			(0x00000002)
+-#define STAT_MUTE_SHIFT			(2)
+-#define STAT_MUTE_MASK			(0x00000004)
+-#define STAT_SETUP_SHIFT		(3)
+-#define STAT_SETUP_MASK			(0x00000008)
+-#define STAT_FLUSH_SHIFT	    (4)
+-#define STAT_FLUSH_MASK			(0x00000010)
+-#define STAT_STOPMODE_SHIFT	    (5)
+-#define STAT_STOPMODE_MASK		(0x00000020)
+-
+-/* Interrupt status */
+-#define AUDIO_INTSTAT_OFFSET			(0x08)
+-#define INTSTAT_CONTROL_SHIFT		(0)
+-#define INTSTAT_CONTROL_MASK		(0x0000000f)
+-#define INTSTAT_FIFO_SHIFT		(4)
+-#define INTSTAT_FIFO_MASK		(0x000000f0)
+-
+-/* Configuration */
+-#define AUDIO_DESTINATION_OFFSET		(0x0C)
+-#define AUDIO_SAMPLE_RATE_OFFSET		(0x10)
+-#define AUDIO_BIT_RATE_OFFSET			(0x14)
+-#define AUDIO_VOLUME_OFFSET			(0x18)
+-#define AUDIO_CHANNELS_OFFSET			(0x1C)
+-
+-/* Implemention of peterson's algorithm for shared memory semaphores */
+-#define AUDIO_FLAG0_OFFSET			(0x20)
+-#define AUDIO_FLAG1_OFFSET			(0x24)
+-#define AUDIO_TURN_OFFSET			(0x28)
+-
+-/* Fifo registers */
+-#define AUDIO_IN_WRITE_PTR_OFFSET		(0x30)
+-#define AUDIO_IN_READ_PTR_OFFSET		(0x34)
+-#define AUDIO_IN_FIFO_SIZE_OFFSET		(0x38)
+-#define AUDIO_IN_FIFO_ENTRY_OFFSET		(0x3C)
+-#define AUDIO_IN_FIFO_START_OFFSET		(0x40)
+-
+-/* 8 entries here of 4 words each = 0x80 gap from 0x50 */
+-#define AUDIO_IN_FIFO_OFFSET			(0x50)
+-
+-#define AUDIO_OUT_WRITE_PTR_OFFSET		(0xD0)
+-#define AUDIO_OUT_READ_PTR_OFFSET		(0xD4)
+-#define AUDIO_OUT_FIFO_SIZE_OFFSET		(0xD8)
+-#define AUDIO_OUT_FIFO_ENTRY_OFFSET		(0xDC)
+-#define AUDIO_OUT_FIFO_START_OFFSET		(0xE0)
+-
+-/* 8 entries here of 4 words each = 0x80 gap from 0xF0 */
+-#define AUDIO_OUT_FIFO_OFFSET			(0xF0)
++/* macros for alsa2chip and chip2alsa, instead of functions */
++
++#define alsa2chip(vol) (uint)(-((vol << 8) / 100))	/* convert alsa to chip volume (defined as macro rather than function call) */
++#define chip2alsa(vol) -((vol * 100) >> 8)			/* convert chip to alsa volume */
+ 
+ /* Some constants for values .. */
+ typedef enum {
+@@ -153,15 +92,6 @@
+ 	PCM_PLAYBACK_DEVICE,
+ } SND_BCM2835_CTRL_T;
+ 
+-/* this struct is tightly packed - its size is 16bytes */
+-typedef struct {
+-	uint32_t buffer_id;
+-	uint32_t buffer_size;
+-	uint32_t buffer_ptr;
+-	uint32_t spare;
+-
+-} AUDIO_FIFO_ENTRY_T;
+-
+ /* definition of the chip-specific record */
+ typedef struct bcm2835_chip {
+ 	struct snd_card *card;
+@@ -172,20 +102,11 @@
+ 	struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS];
+ 
+ 	int volume;
++	int old_volume; /* stores the volume value whist muted */
+ 	int dest;
+ 	int mute;
+ } bcm2835_chip_t;
+ 
+-typedef struct bcm2835_audio_buffer {
+-	uint32_t buffer_id;
+-	phys_addr_t bus_addr;
+-	uint8_t __iomem *start;
+-	uint32_t size;
+-	uint32_t data_left;
+-	struct list_head link;
+-
+-} bcm2835_audio_buffer_t;
+-
+ typedef struct bcm2835_alsa_stream {
+ 	bcm2835_chip_t *chip;
+ 	struct snd_pcm_substream *substream;
+@@ -200,10 +121,6 @@
+ 	int running;
+ 	int draining;
+ 
+-#ifdef DUMP_RAW_DATA
+-	/* for debug */
+-	int file;
+-#endif
+ 	unsigned int pos;
+ 	unsigned int buffer_size;
+ 	unsigned int period_size;
+@@ -220,9 +137,6 @@
+ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip);
+ int snd_bcm2835_new_pcm(bcm2835_chip_t * chip);
+ 
+-void bcm2835_audio_fifo_get_lock(bcm2835_alsa_stream_t * alsa_stream);
+-void bcm2835_audio_fifo_put_lock(bcm2835_alsa_stream_t * alsa_stream);
+-
+ int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream);
+ int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream);
+ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
+@@ -234,7 +148,6 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
+ int bcm2835_audio_set_ctls(bcm2835_chip_t * chip);
+ int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count,
+ 			void *src);
+-//uint32_t bcm2835_audio_buffers_consumed_bytes(bcm2835_alsa_stream_t *alsa_stream);
+ uint32_t bcm2835_audio_retrieve_buffers(bcm2835_alsa_stream_t * alsa_stream);
+ void bcm2835_audio_flush_buffers(bcm2835_alsa_stream_t * alsa_stream);
+ void bcm2835_audio_flush_playback_buffers(bcm2835_alsa_stream_t * alsa_stream);
+-- 
+1.7.10
+
+
+From 921a3d1180d23cfc8a75eb2a0288b3b2fb9f1fdb Mon Sep 17 00:00:00 2001
+From: ddv2005 <ddv@abinet.com>
+Date: Sun, 5 Aug 2012 10:42:12 -0400
+Subject: [PATCH 3/3] Fix spinlock recursion in sdhci-bcm2708.c
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 1ac1e64..349d7ab 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -656,7 +656,7 @@ static void schci_bcm2708_dma_go(struct sdhci_host *host)
+ 
+ 	BUG_ON(NULL == host);
+ 
+-	spin_lock_irqsave(&host->lock, flags);
++//	spin_lock_irqsave(&host->lock, flags);
+ 
+ 	if (host_priv->dma_wanted) {
+ 		if (NULL == data) {
+@@ -736,7 +736,7 @@ static void schci_bcm2708_dma_go(struct sdhci_host *host)
+ #endif
+ 	}
+ 
+-	spin_unlock_irqrestore(&host->lock, flags);
++//	spin_unlock_irqrestore(&host->lock, flags);
+ }
+ 
+ 
+@@ -753,7 +753,7 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+ 
+ 	BUG_ON(NULL == host);
+ 
+-	spin_lock_irqsave(&host->lock, flags);
++//	spin_lock_irqsave(&host->lock, flags);
+ 	data = host->data;
+ 
+ #ifdef CHECK_DMA_USE
+@@ -778,7 +778,7 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+ 
+ 	if (NULL == data) {
+ 		DBG("PDMA unused completion - status 0x%X\n", dma_cs);
+-		spin_unlock_irqrestore(&host->lock, flags);
++//		spin_unlock_irqrestore(&host->lock, flags);
+ 		return;
+ 	}
+ 	sg = data->sg;
+@@ -871,7 +871,7 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host,
+ 						SDHCI_INT_SPACE_AVAIL);
+ 		}
+ 	}
+-	spin_unlock_irqrestore(&host->lock, flags);
++//	spin_unlock_irqrestore(&host->lock, flags);
+ }
+ 
+ static irqreturn_t sdhci_bcm2708_dma_irq(int irq, void *dev_id)
+-- 
+1.7.10
+
+--- linux-3.3.8/arch/arm/mach-bcm2708/bcm2708.c.orig	2012-08-19 17:17:21.085900365 -0400
++++ linux-3.3.8/arch/arm/mach-bcm2708/bcm2708.c	2012-08-19 17:32:09.322292814 -0400
+@@ -41,6 +41,7 @@
+ #include <linux/leds.h>
+ #include <asm/mach-types.h>
+ #include <asm/sched_clock.h>
++#include <linux/clocksource.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/flash.h>
+@@ -144,51 +145,14 @@
+ /* The STC is a free running counter that increments at the rate of 1MHz */
+ #define STC_FREQ_HZ 1000000
+ 
+-/*
+- * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
+- * This gives a resolution of about 1us and a wrap period of about 1h11min.
+- */
+-#define SC_MULT		4194304000u
+-#define SC_SHIFT	22
+-
+-static cycle_t stc_read_cycles(struct clocksource *cs)
++static u32 notrace bcm2708_read_sched_clock(void)
+ {
+-	/* STC: a free running counter that increments at the rate of 1MHz */
+-	return (cycle_t) readl(__io_address(ST_BASE + 0x04));
++	return readl(__io_address(ST_BASE + 0x04));
+ }
+ 
+-static struct clocksource clocksource_stc = {
+-	.name = "stc",
+-	.rating = 300,
+-	.read = stc_read_cycles,
+-	.mask = CLOCKSOURCE_MASK(32),
+-	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+-};
+-
+ unsigned long frc_clock_ticks32(void)
+ {
+-	return (unsigned long)stc_read_cycles(&clocksource_stc);
+-}
+-
+-static void __init bcm2708_clocksource_init(void)
+-{
+-	if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) {
+-		printk(KERN_ERR "timer: failed to initialize clock "
+-		       "source %s\n", clocksource_stc.name);
+-	}
+-}
+-
+-unsigned long long sched_clock(void)
+-{
+-	u32 cyc = clocksource_stc.read(&clocksource_stc);
+-	return cyc_to_fixed_sched_clock(&cd, cyc, clocksource_stc.mask,
+-			SC_MULT, SC_SHIFT);
+-}
+-
+-static void notrace bcm2708_update_sched_clock(void)
+-{
+-	u32 cyc = clocksource_stc.read(&clocksource_stc);
+-	update_sched_clock(&cd, cyc, clocksource_stc.mask);
++	return bcm2708_read_sched_clock();
+ }
+ 
+ /*
+@@ -583,6 +547,7 @@
+ 	int i;
+ 
+ 	pm_power_off = bcm2708_power_off;
++	arm_pm_restart = arch_reset;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ 		clkdev_add(&lookups[i]);
+@@ -696,9 +661,6 @@
+  */
+ static void __init bcm2708_timer_init(void)
+ {
+-	/* init high res timer */
+-	bcm2708_clocksource_init();
+-
+ 	/*
+ 	 * Initialise to a known state (all timers off)
+ 	 */
+@@ -708,18 +670,12 @@
+ 	 */
+ 	setup_irq(IRQ_TIMER3, &bcm2708_timer_irq);
+ 
+-	init_fixed_sched_clock(&cd, bcm2708_update_sched_clock, 32,
+-		STC_FREQ_HZ, SC_MULT, SC_SHIFT);
+-
+-	timer0_clockevent.mult =
+-	    div_sc(STC_FREQ_HZ, 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);
++	setup_sched_clock(bcm2708_read_sched_clock, 32, STC_FREQ_HZ);
++	if (clocksource_mmio_init(__io_address(ST_BASE + 0x04), "stc",
++		STC_FREQ_HZ, 300, 32, clocksource_mmio_readl_up))
++		printk(KERN_ERR "timer: failed to initialize clock source stc\n");
++	clockevents_config_and_register(&timer0_clockevent, STC_FREQ_HZ,
++		0xf, 0xffffffff);
+ }
+ 
+ struct sys_timer bcm2708_timer = {
+--- linux-3.3.8/arch/arm/Kconfig.orig	2012-08-19 17:36:06.593582525 -0400
++++ linux-3.3.8/arch/arm/Kconfig	2012-08-19 17:36:20.737778724 -0400
+@@ -967,6 +967,7 @@
+ 	select ARM_AMBA
+ 	select HAVE_CLK
+ 	select HAVE_SCHED_CLOCK
++	select CLKSRC_MMIO
+ 	select NEED_MACH_MEMORY_H
+ 	select CLKDEV_LOOKUP
+ 	select GENERIC_CLOCKEVENTS
