linux 2.6.20: refreshed NHK-15 patches to build after stable update
authorMarcin Juszkiewicz <marcin@juszkiewicz.com.pl>
Thu, 11 Feb 2010 09:59:37 +0000 (10:59 +0100)
committerMarcin Juszkiewicz <marcin@juszkiewicz.com.pl>
Thu, 11 Feb 2010 10:01:07 +0000 (11:01 +0100)
Signed-off-by: Marcin Juszkiewicz <marcin@juszkiewicz.com.pl>
recipes/linux/linux-2.6.20/nhk15/0001-kbuild-include-limits.h-in-sumversion.c-for-path_max.patch [deleted file]
recipes/linux/linux-2.6.20/nhk15/audio_codec_patch_base_v5.6.0.patch
recipes/linux/linux-2.6.20/nhk15/hrw-make-create-kconfig-executable.patch
recipes/linux/linux-2.6.20/nhk15/linux-2.6.20_01_dec_2.patch
recipes/linux/linux-2.6.20/nhk15/nomadik_baseline_linux_2620.patch
recipes/linux/linux-2.6.20/nhk15/patch_audiocodec_glitch.patch
recipes/linux/linux-2.6.20/nhk15/patch_classdamp_pm_v_audio_codec_patch.patch
recipes/linux/linux_2.6.20.bb

diff --git a/recipes/linux/linux-2.6.20/nhk15/0001-kbuild-include-limits.h-in-sumversion.c-for-path_max.patch b/recipes/linux/linux-2.6.20/nhk15/0001-kbuild-include-limits.h-in-sumversion.c-for-path_max.patch
deleted file mode 100644 (file)
index 4871601..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From fc31c7716355a226b8ed4e16f4581e5c8fa53570 Mon Sep 17 00:00:00 2001
-From: Mike Frysinger <vapier@gentoo.org>
-Date: Thu, 17 May 2007 14:57:20 -0400
-Subject: [PATCH] kbuild: include limits.h in sumversion.c for PATH_MAX
-
-POSIX says limits.h defines PATH_MAX so we should include it (which fixes
-compiling on some systems like OS X).
-
-Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
----
- scripts/mod/sumversion.c |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
-
-diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
-index 6873d5a..d9cc690 100644
---- a/scripts/mod/sumversion.c
-+++ b/scripts/mod/sumversion.c
-@@ -7,6 +7,7 @@
- #include <ctype.h>
- #include <errno.h>
- #include <string.h>
-+#include <limits.h>
- #include "modpost.h"
- /*
--- 
-1.6.3.3
-
index 1a7bd9e..5b9c187 100644 (file)
@@ -1,7 +1,14 @@
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c
---- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c    2008-11-24 14:06:25.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c     2008-11-26 18:37:16.000000000 +0530
-@@ -1292,12 +1292,14 @@ static int link_msp (struct instance_des
+---
+ drivers/media/nomadik_mm/saa/nomadik-saa.c |    4 +++-
+ sound/arm/nomadik_alsa.c                   |    4 ++++
+ sound/nomadik_stw5095.c                    |   17 +++++++++++++++++
+ 3 files changed, 24 insertions(+), 1 deletion(-)
+
+--- linux-2.6.20.orig/drivers/media/nomadik_mm/saa/nomadik-saa.c
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c
+@@ -1290,16 +1290,18 @@ static int link_msp (struct instance_des
+       }
        else
        {
                /*Configure Output sink for audiocodec*/
@@ -17,15 +24,18 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linu
                down(&saa_desc->open_lock);
                if(saa_desc->msp_out_flag != 0){
                        printk ("SAA_DRV ERROR : MSP OUT already used \n");
-diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.c ../new/linux-2.6.20/sound/arm/nomadik_alsa.c
---- linux-2.6.20/sound/arm/nomadik_alsa.c      2008-11-24 14:06:29.000000000 +0530
-+++ ../new/linux-2.6.20/sound/arm/nomadik_alsa.c       2008-11-26 18:36:26.000000000 +0530
-@@ -568,10 +568,14 @@ static int snd_nomadik_alsa_pcm_open(snd
+                       up(&saa_desc->open_lock);
+                       return -EBUSY;
+--- linux-2.6.20.orig/sound/arm/nomadik_alsa.c
++++ linux-2.6.20/sound/arm/nomadik_alsa.c
+@@ -566,14 +566,18 @@ static int snd_nomadik_alsa_pcm_open(snd
+       /* Set the hardware configuration */
+       stream_id = substream->pstr->stream;
        if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
                runtime->hw = snd_nomadik_playback_hw;
                /* configure the output sink for the acodec */
 +              #if 0
-+              if(codec_conf.codec_output != chip->output_device){                     
++              if(codec_conf.codec_output != chip->output_device){
                if ((error = nomadik_acodec_select_output(chip->output_device, USER_ALSA))) {
                        printk("ALSA: ERROR: select output failed\n");
                        return error;
@@ -35,10 +45,13 @@ diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.c ../new/linux-2.6.20/sound/arm
        } else {
                runtime->hw = snd_nomadik_capture_hw;
                /* configure the input source for the acodec */
-diff -Nauprw linux-2.6.20/sound/nomadik_stw5095.c ../new/linux-2.6.20/sound/nomadik_stw5095.c
---- linux-2.6.20/sound/nomadik_stw5095.c       2008-11-24 14:06:29.000000000 +0530
-+++ ../new/linux-2.6.20/sound/nomadik_stw5095.c        2008-11-26 18:36:04.000000000 +0530
-@@ -3237,6 +3237,7 @@ t_codec_error nomadik_acodec_setuser(t_a
+               if ((error = nomadik_acodec_select_input(chip->input_device, USER_ALSA))) {
+                       printk("ALSA: ERROR: select input failed\n");
+--- linux-2.6.20.orig/sound/nomadik_stw5095.c
++++ linux-2.6.20/sound/nomadik_stw5095.c
+@@ -3235,19 +3235,32 @@ t_codec_error nomadik_acodec_setuser(t_a
+  * Unset the current user for acodec.
+  */
  
  t_codec_error nomadik_acodec_unsetuser(t_acodec_user user)
  {
@@ -46,11 +59,13 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5095.c ../new/linux-2.6.20/sound/noma
        t_codec_error codec_error = CODEC_OK;
  
        if(g_codec_system_context.cur_user != user){
-@@ -3246,6 +3247,18 @@ t_codec_error nomadik_acodec_unsetuser(t
+               printk
+                       ("ERROR : Trying to free audiocodec already in use by other user %d\n", g_codec_system_context.cur_user);
+               return CODEC_ERROR;
        }
        else {
                g_codec_system_context.cur_user = NO_USER;
-+              
++
 +              err = STMPE2401_Install_Callback(STMPE0, EGPIO_PIN_7 ,NULL,(void*)user);
 +              if (err != STMPE2401_OK)
 +              {
@@ -65,7 +80,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5095.c ../new/linux-2.6.20/sound/noma
                  nomadik_acodec_powerdown(0);
          }
  
-@@ -3282,6 +3295,10 @@ static void codec_callback1(void *user)
+       return (codec_error);
+ }
+@@ -3280,10 +3293,14 @@ static void codec_callback1(void *user)
+ {
+       int err,codec_error;
        uint8 byte_value;
        t_acodec_user t;
        t = (t_acodec_user) user;
@@ -76,3 +95,5 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5095.c ../new/linux-2.6.20/sound/noma
        err = STMPE2401_GetGpioVal(STMPE0,EGPIO_PIN_7,&byte_value);
        switch(byte_value)      {
  
+       case 0:
+               err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_12,STMPE2401_PRIMARY_FUNCTION);
index 7a2ccae..8cb13ba 100644 (file)
@@ -12,6 +12,6 @@
        @echo "Generating $(TOPDIR)/arch/arm/mach-nomadik/Kconfig"
 +      @chmod 755 ./create_kconfig.pl
        @./create_kconfig.pl $(TOPDIR)/arch/arm/mach-nomadik
- endif 
+ endif
  
  # end of Auto board configuration/dependency resolution
index 4876337..62be30a 100644 (file)
@@ -1,7 +1,13 @@
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c       2008-11-24 14:06:26.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c        2008-12-01 17:31:42.589136000 +0530
-@@ -38,6 +38,7 @@
+---
+ drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c | 2910 +++++++++++++++++++++---
+ drivers/media/video/v4l2-nomadik.c              |    2 
+ 2 files changed, 2644 insertions(+), 268 deletions(-)
+
+--- linux-2.6.20.orig/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c
+@@ -36,10 +36,11 @@
+ #include <linux/delay.h>
  #include "nomadik_sva_vpip.h"
  
  #define VPIP_DEFAULT_LOG_LEVEL                4
@@ -9,7 +15,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  
  int vpip_debug = VPIP_DEFAULT_LOG_LEVEL;
  module_param(vpip_debug, int, 0644);
-@@ -790,20 +791,29 @@ return ret_val;
+ MODULE_PARM_DESC(vpip_debug,"Debug level for VPIP messages");
+@@ -788,79 +789,106 @@ IRP_ASSERT(irp_write_packet(srv_open,
+ return ret_val;
+ }EXPORT_SYMBOL(write_pages_exposure);
  
  
  
@@ -41,7 +51,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeManagerStatus_bThisLoLevelState ,  0x0100,   0x0000 },
  {   ModeManagerStatus_bNextLoLevelState ,  0x0102,   0x0000 },
  {   ModeManagerStatus_bHiLevelState ,  0x0104,   0x0000 },
-@@ -813,52 +823,70 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeManagerStatus_bCycles ,  0x0106,   0x0000 },
+ {   ModeManagerStatus_fModeStaticSetupsChanged ,  0x0108,   0x0000 },
+ {   ModeManagerStatus_bTestCoin ,  0x010a,   0x0000 },
  {   ModeManagerStatus_fCycleForTest ,  0x010c,   0x0000 },
  {   ModeManagerStatus_bNumberOfFramesStreamed ,  0x010e,   0x0000 },
  {   ModeManagerStatus_bPrevFrameCountForExposure ,  0x0110,   0x0000 },
@@ -138,7 +150,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   PipeSetupBankB_uwPipeOutputSize_X_LSByte ,  0x0402,   0x0000 },
  {   PipeSetupBankB_uwPipeOutputSize_X_MSByte ,  0x0401,   0x0000 },
  {   PipeSetupBankB_uwPipeOutputSize_Y_LSByte ,  0x0406,   0x0000 },
-@@ -871,22 +899,37 @@ struct nomadik_vpip_param vpip_default_p
+ {   PipeSetupBankB_uwPipeOutputSize_Y_MSByte ,  0x0405,   0x0000 },
+ {   PipeSetupBankB_bPipeOutputFormat ,  0x0408,   0x0000 },
+@@ -869,26 +897,41 @@ struct nomadik_vpip_param vpip_default_p
+ {   PipeSetupBankB_fEnableItuEmbeddedCodes ,  0x040e,   0x0000 },
+ {   PipeSetupBankB_bPixValidLineTypes ,  0x0410,   0x0000 },
  {   PipeSetupBankB_fGenerateVSync ,  0x0412,   0x0000 },
  {   PipeSetupBankB_fCb_Cr_Flip ,  0x0414,   0x0000 },
  {   PipeSetupBankB_fY_CbCr_Flip ,  0x0416,   0x0000 },
@@ -177,7 +193,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   LocalPipe0SetupBank_uwPipeOutputSize_X_LSByte ,  0x0682,   0x0000 },
  {   LocalPipe0SetupBank_uwPipeOutputSize_X_MSByte ,  0x0681,   0x0000 },
  {   LocalPipe0SetupBank_uwPipeOutputSize_Y_LSByte ,  0x0686,   0x0000 },
-@@ -899,13 +942,19 @@ struct nomadik_vpip_param vpip_default_p
+ {   LocalPipe0SetupBank_uwPipeOutputSize_Y_MSByte ,  0x0685,   0x0000 },
+ {   LocalPipe0SetupBank_bPipeOutputFormat ,  0x0688,   0x0000 },
+@@ -897,83 +940,119 @@ struct nomadik_vpip_param vpip_default_p
+ {   LocalPipe0SetupBank_fEnableItuEmbeddedCodes ,  0x068e,   0x0000 },
+ {   LocalPipe0SetupBank_bPixValidLineTypes ,  0x0690,   0x0000 },
  {   LocalPipe0SetupBank_fGenerateVSync ,  0x0692,   0x0000 },
  {   LocalPipe0SetupBank_fCb_Cr_Flip ,  0x0694,   0x0000 },
  {   LocalPipe0SetupBank_fY_CbCr_Flip ,  0x0696,   0x0000 },
@@ -197,7 +217,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   Pipe0Control_fOverrideOFCropRegisters ,  0x070e,   0x0000 },
  {   Pipe0Control_uwHCropRising_LSByte ,  0x0712,   0x0000 },
  {   Pipe0Control_uwHCropRising_MSByte ,  0x0711,   0x0000 },
-@@ -915,27 +964,45 @@ struct nomadik_vpip_param vpip_default_p
+ {   Pipe0Control_uwHCropFalling_LSByte ,  0x0716,   0x0000 },
+ {   Pipe0Control_uwHCropFalling_MSByte ,  0x0715,   0x0000 },
+ {   Pipe0Control_uwVCropRisingCrse_LSByte ,  0x071a,   0x0000 },
  {   Pipe0Control_uwVCropRisingCrse_MSByte ,  0x0719,   0x0000 },
  {   Pipe0Control_uwVCropFallingCrse_LSByte ,  0x071e,   0x0000 },
  {   Pipe0Control_uwVCropFallingCrse_MSByte ,  0x071d,   0x0000 },
@@ -246,7 +268,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MasterI2cStatus_bResourceStatus ,  0x0a00,   0x0000 },
  {   MasterI2cStatus_uwI2CClkDiv_LSByte ,  0x0a04,   0x0000 },
  {   MasterI2cStatus_uwI2CClkDiv_MSByte ,  0x0a03,   0x0000 },
-@@ -943,24 +1010,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   MasterI2cStatus_fTransactionError ,  0x0a06,   0x0000 },
  {   MasterI2cStatus_bNumberOfTransactionFailures ,  0x0a08,   0x0000 },
  {   MasterI2cStatus_bNumberOfConsecutiveGrabFailures ,  0x0a0a,   0x0000 },
  {   MasterI2cStatus_bNumberOfForcedReleases ,  0x0a0c,   0x0000 },
@@ -286,7 +308,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_LSByte ,  0x0c02,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_MSByte ,  0x0c01,   0x0000 },
  {   VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_LSByte ,  0x0c06,   0x0000 },
-@@ -971,7 +1050,7 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_MSByte ,  0x0c05,   0x0000 },
+ {   VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte ,  0x0c0a,   0x0000 },
+ {   VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte ,  0x0c09,   0x0000 },
+ {   VideoTimingSensorConstraints_uwMinimumPllMultiplier_LSByte ,  0x0c0e,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumPllMultiplier_MSByte ,  0x0c0d,   0x0000 },
  {   VideoTimingSensorConstraints_uwMaximumPllMultiplier_LSByte ,  0x0c12,   0x0000 },
  {   VideoTimingSensorConstraints_uwMaximumPllMultiplier_MSByte ,  0x0c11,   0x0000 },
@@ -295,7 +320,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte ,  0x0c15,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_LSByte ,  0x0c1a,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_MSByte ,  0x0c19,   0x0000 },
-@@ -993,6 +1072,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_LSByte ,  0x0c1e,   0x0000 },
+ {   VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_MSByte ,  0x0c1d,   0x0000 },
+@@ -991,17 +1070,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_MSByte ,  0x0c35,   0x0000 },
+ {   VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte ,  0x0c3a,   0x0000 },
  {   VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte ,  0x0c39,   0x0000 },
  {   VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte ,  0x0c3e,   0x0000 },
  {   VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte ,  0x0c3d,   0x0000 },
@@ -305,7 +334,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorScalingSubSamplingCapabilities_bSensorScalingMode ,  0x0c80,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwScalerMMin_LSByte ,  0x0c84,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwScalerMMin_MSByte ,  0x0c83,   0x0000 },
-@@ -1000,6 +1082,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorScalingSubSamplingCapabilities_uwScalerMMax_LSByte ,  0x0c88,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwScalerMMax_MSByte ,  0x0c87,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwMaxOddInc_LSByte ,  0x0c8c,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwMaxOddInc_MSByte ,  0x0c8b,   0x0000 },
@@ -315,7 +344,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingOutput_uwPrePllClockDiv_LSByte ,  0x0d02,   0x0000 },
  {   VideoTimingOutput_uwPrePllClockDiv_MSByte ,  0x0d01,   0x0000 },
  {   VideoTimingOutput_fpPllInputFrequency_Mhz_LSByte ,  0x0d06,   0x0000 },
-@@ -1028,7 +1113,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingOutput_fpPllInputFrequency_Mhz_MSByte ,  0x0d05,   0x0000 },
+ {   VideoTimingOutput_uwPllMultiplier_LSByte ,  0x0d0a,   0x0000 },
+@@ -1026,24 +1111,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingOutput_uwOPPixelClockDiv_MSByte ,  0x0d2d,   0x0000 },
+ {   VideoTimingOutput_fpOPPixelClockFrequency_Mhz_LSByte ,  0x0d32,   0x0000 },
  {   VideoTimingOutput_fpOPPixelClockFrequency_Mhz_MSByte ,  0x0d31,   0x0000 },
  {   VideoTimingOutput_fpOutputTimingClockDerating_LSByte ,  0x0d36,   0x0000 },
  {   VideoTimingOutput_fpOutputTimingClockDerating_MSByte ,  0x0d35,   0x0000 },
@@ -329,7 +362,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingInputsFarSensor_VideoTimingMode ,  0x0e00,   0x0001 },
  {   VideoTimingInputsFarSensor_bSensorBitsPerSystemClock ,  0x0e02,   0x0002 },
  {   VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte ,  0x0e06,   0x0000 },
-@@ -1037,11 +1128,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte ,  0x0e05,   0x0808 },
+ {   VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte ,  0x0e0a,   0x0000 },
  {   VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte ,  0x0e09,   0x508a },
  {   VideoTimingInputsFarSensor_VsyncPolarity ,  0x0e0c,   0x0000 },
  {   VideoTimingInputsFarSensor_HsyncPolarity ,  0x0e0e,   0x0000 },
@@ -347,7 +381,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_LSByte ,  0x0f02,   0x0000 },
  {   VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_MSByte ,  0x0f01,   0x0000 },
  {   VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_LSByte ,  0x0f06,   0x0000 },
-@@ -1074,6 +1171,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_MSByte ,  0x0f05,   0x0000 },
+ {   VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte ,  0x0f0a,   0x0000 },
+@@ -1072,17 +1169,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_MSByte ,  0x0f35,   0x0000 },
+ {   VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte ,  0x0f3a,   0x0000 },
  {   VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte ,  0x0f39,   0x0000 },
  {   VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte ,  0x0f3e,   0x0000 },
  {   VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte ,  0x0f3d,   0x0000 },
@@ -357,7 +395,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFarScalingSubSamplingCapabilities_bSensorScalingMode ,  0x0f80,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwScalerMMin_LSByte ,  0x0f84,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwScalerMMin_MSByte ,  0x0f83,   0x0000 },
-@@ -1081,6 +1181,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFarScalingSubSamplingCapabilities_uwScalerMMax_LSByte ,  0x0f88,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwScalerMMax_MSByte ,  0x0f87,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_LSByte ,  0x0f8c,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_MSByte ,  0x0f8b,   0x0000 },
@@ -367,7 +405,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingFarOutput_uwPrePllClockDiv_LSByte ,  0x1002,   0x0000 },
  {   VideoTimingFarOutput_uwPrePllClockDiv_MSByte ,  0x1001,   0x0000 },
  {   VideoTimingFarOutput_fpPllInputFrequency_Mhz_LSByte ,  0x1006,   0x0000 },
-@@ -1109,7 +1212,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarOutput_fpPllInputFrequency_Mhz_MSByte ,  0x1005,   0x0000 },
+ {   VideoTimingFarOutput_uwPllMultiplier_LSByte ,  0x100a,   0x0000 },
+@@ -1107,24 +1210,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarOutput_uwOPPixelClockDiv_MSByte ,  0x102d,   0x0000 },
+ {   VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_LSByte ,  0x1032,   0x0000 },
  {   VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_MSByte ,  0x1031,   0x0000 },
  {   VideoTimingFarOutput_fpOutputTimingClockDerating_LSByte ,  0x1036,   0x0000 },
  {   VideoTimingFarOutput_fpOutputTimingClockDerating_MSByte ,  0x1035,   0x0000 },
@@ -381,7 +423,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingInputsNearSensor_VideoTimingMode ,  0x1100,   0x0001 },
  {   VideoTimingInputsNearSensor_bSensorBitsPerSystemClock ,  0x1102,   0x0002 },
  {   VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte ,  0x1106,   0x0000 },
-@@ -1118,11 +1227,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte ,  0x1105,   0x0808 },
+ {   VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte ,  0x110a,   0x0000 },
  {   VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte ,  0x1109,   0x508a },
  {   VideoTimingInputsNearSensor_VsyncPolarity ,  0x110c,   0x0000 },
  {   VideoTimingInputsNearSensor_HsyncPolarity ,  0x110e,   0x0000 },
@@ -399,7 +442,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_LSByte ,  0x1202,   0x0000 },
  {   VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_MSByte ,  0x1201,   0x0000 },
  {   VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_LSByte ,  0x1206,   0x0000 },
-@@ -1155,6 +1270,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_MSByte ,  0x1205,   0x0000 },
+ {   VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte ,  0x120a,   0x0000 },
+@@ -1153,17 +1268,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_MSByte ,  0x1235,   0x0000 },
+ {   VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte ,  0x123a,   0x0000 },
  {   VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte ,  0x1239,   0x0000 },
  {   VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte ,  0x123e,   0x0000 },
  {   VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte ,  0x123d,   0x0000 },
@@ -409,7 +456,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorNearScalingSubSamplingCapabilities_bSensorScalingMode ,  0x1280,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwScalerMMin_LSByte ,  0x1284,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwScalerMMin_MSByte ,  0x1283,   0x0000 },
-@@ -1162,6 +1280,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorNearScalingSubSamplingCapabilities_uwScalerMMax_LSByte ,  0x1288,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwScalerMMax_MSByte ,  0x1287,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_LSByte ,  0x128c,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_MSByte ,  0x128b,   0x0000 },
@@ -419,7 +466,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingNearOutput_uwPrePllClockDiv_LSByte ,  0x1302,   0x0000 },
  {   VideoTimingNearOutput_uwPrePllClockDiv_MSByte ,  0x1301,   0x0000 },
  {   VideoTimingNearOutput_fpPllInputFrequency_Mhz_LSByte ,  0x1306,   0x0000 },
-@@ -1190,35 +1311,47 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearOutput_fpPllInputFrequency_Mhz_MSByte ,  0x1305,   0x0000 },
+ {   VideoTimingNearOutput_uwPllMultiplier_LSByte ,  0x130a,   0x0000 },
+@@ -1188,39 +1309,51 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearOutput_uwOPPixelClockDiv_MSByte ,  0x132d,   0x0000 },
+ {   VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_LSByte ,  0x1332,   0x0000 },
  {   VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_MSByte ,  0x1331,   0x0000 },
  {   VideoTimingNearOutput_fpOutputTimingClockDerating_LSByte ,  0x1336,   0x0000 },
  {   VideoTimingNearOutput_fpOutputTimingClockDerating_MSByte ,  0x1335,   0x0000 },
@@ -476,7 +527,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_LSByte ,  0x1502,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_MSByte ,  0x1501,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_LSByte ,  0x1506,   0x0000 },
-@@ -1230,8 +1363,10 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_MSByte ,  0x1505,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte ,  0x150a,   0x0000 },
+@@ -1228,12 +1361,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_LSByte ,  0x150e,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_MSByte ,  0x150d,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte ,  0x1512,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte ,  0x1511,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_LSByte ,  0x1516,   0x0000 },
@@ -487,7 +542,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte ,  0x1519,   0x0080 },
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_LSByte ,  0x151e,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_MSByte ,  0x151d,   0x0000 },
-@@ -1265,7 +1400,11 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorAnalogGainType_LSByte ,  0x1522,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorAnalogGainType_MSByte ,  0x1521,   0x0000 },
+@@ -1263,11 +1398,15 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte ,  0x1554,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_MSByte ,  0x1553,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_LSByte ,  0x1558,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_MSByte ,  0x1557,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorDataPedestal_LSByte ,  0x155c,   0x0000 },
@@ -499,7 +558,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_LSByte ,  0x1582,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_MSByte ,  0x1581,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_LSByte ,  0x1586,   0x0000 },
-@@ -1278,8 +1417,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_MSByte ,  0x1585,   0x0000 },
+ {   SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte ,  0x158a,   0x0000 },
+@@ -1276,12 +1415,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_MSByte ,  0x158d,   0x0000 },
+ {   SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte ,  0x1592,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte ,  0x1591,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_LSByte ,  0x1596,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_MSByte ,  0x1595,   0x0000 },
@@ -510,7 +573,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_LSByte ,  0x159e,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_MSByte ,  0x159d,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainType_LSByte ,  0x15a2,   0x0000 },
-@@ -1313,6 +1452,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorAnalogGainType_MSByte ,  0x15a1,   0x0000 },
+ {   SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_LSByte ,  0x15a6,   0x0000 },
+@@ -1311,10 +1450,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_MSByte ,  0x15d3,   0x0000 },
+ {   SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_LSByte ,  0x15d8,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_MSByte ,  0x15d7,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorDataPedestal_LSByte ,  0x15dc,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorDataPedestal_MSByte ,  0x15db,   0x0000 },
@@ -520,7 +587,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_LSByte ,  0x1602,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_MSByte ,  0x1601,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_LSByte ,  0x1606,   0x0000 },
-@@ -1324,8 +1466,10 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_MSByte ,  0x1605,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte ,  0x160a,   0x0000 },
+@@ -1322,12 +1464,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_LSByte ,  0x160e,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_MSByte ,  0x160d,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte ,  0x1612,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte ,  0x1611,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_LSByte ,  0x1616,   0x0000 },
@@ -531,7 +602,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte ,  0x1619,   0x0080 },
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_LSByte ,  0x161e,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_MSByte ,  0x161d,   0x0000 },
-@@ -1360,6 +1504,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_LSByte ,  0x1622,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_MSByte ,  0x1621,   0x0000 },
+@@ -1358,10 +1502,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_MSByte ,  0x1653,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_LSByte ,  0x1658,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_MSByte ,  0x1657,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_LSByte ,  0x165c,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_MSByte ,  0x165b,   0x0000 },
@@ -541,7 +616,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFrameConstraintsFar_uwVTXAddrMin_LSByte ,  0x1682,   0x0000 },
  {   SensorFrameConstraintsFar_uwVTXAddrMin_MSByte ,  0x1681,   0x0000 },
  {   SensorFrameConstraintsFar_uwVTYAddrMin_LSByte ,  0x1686,   0x0000 },
-@@ -1388,6 +1535,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsFar_uwVTYAddrMin_MSByte ,  0x1685,   0x0000 },
+ {   SensorFrameConstraintsFar_uwVTXAddrMax_LSByte ,  0x168a,   0x0000 },
+@@ -1386,10 +1533,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsFar_uwMaxVTLineLengthPck_MSByte ,  0x16ad,   0x0000 },
+ {   SensorFrameConstraintsFar_uwMinVTLineBlankingPck_LSByte ,  0x16b2,   0x0000 },
  {   SensorFrameConstraintsFar_uwMinVTLineBlankingPck_MSByte ,  0x16b1,   0x0000 },
  {   SensorFrameConstraintsFar_uwMinVTFrameBlanking_LSByte ,  0x16b6,   0x0000 },
  {   SensorFrameConstraintsFar_uwMinVTFrameBlanking_MSByte ,  0x16b5,   0x0000 },
@@ -551,7 +630,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFrameConstraintsNear_uwVTXAddrMin_LSByte ,  0x1702,   0x0000 },
  {   SensorFrameConstraintsNear_uwVTXAddrMin_MSByte ,  0x1701,   0x0000 },
  {   SensorFrameConstraintsNear_uwVTYAddrMin_LSByte ,  0x1706,   0x0000 },
-@@ -1416,8 +1566,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsNear_uwVTYAddrMin_MSByte ,  0x1705,   0x0000 },
+ {   SensorFrameConstraintsNear_uwVTXAddrMax_LSByte ,  0x170a,   0x0000 },
+@@ -1414,12 +1564,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsNear_uwMaxVTLineLengthPck_MSByte ,  0x172d,   0x0000 },
+ {   SensorFrameConstraintsNear_uwMinVTLineBlankingPck_LSByte ,  0x1732,   0x0000 },
  {   SensorFrameConstraintsNear_uwMinVTLineBlankingPck_MSByte ,  0x1731,   0x0000 },
  {   SensorFrameConstraintsNear_uwMinVTFrameBlanking_LSByte ,  0x1736,   0x0000 },
  {   SensorFrameConstraintsNear_uwMinVTFrameBlanking_MSByte ,  0x1735,   0x0000 },
@@ -568,7 +651,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   CurrentFrameDimension_uwVTFrameLengthLines_LSByte ,  0x1802,   0x0000 },
  {   CurrentFrameDimension_uwVTFrameLengthLines_MSByte ,  0x1801,   0x0000 },
  {   CurrentFrameDimension_uwVTLineLengthPck_LSByte ,  0x1806,   0x0000 },
-@@ -1449,6 +1605,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   CurrentFrameDimension_uwVTLineLengthPck_MSByte ,  0x1805,   0x0000 },
+ {   CurrentFrameDimension_uwVTXAddrStart_LSByte ,  0x180a,   0x0000 },
+@@ -1447,10 +1603,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   CurrentFrameDimension_bScalingMode ,  0x1834,   0x0000 },
+ {   CurrentFrameDimension_fpScaleFactor_LSByte ,  0x1838,   0x0000 },
  {   CurrentFrameDimension_fpScaleFactor_MSByte ,  0x1837,   0x0000 },
  {   CurrentFrameDimension_uwScalerM_LSByte ,  0x183c,   0x0000 },
  {   CurrentFrameDimension_uwScalerM_MSByte ,  0x183b,   0x0000 },
@@ -578,7 +665,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFrameConstraints_uwVTXAddrMin_LSByte ,  0x1882,   0x0000 },
  {   SensorFrameConstraints_uwVTXAddrMin_MSByte ,  0x1881,   0x0000 },
  {   SensorFrameConstraints_uwVTYAddrMin_LSByte ,  0x1886,   0x0000 },
-@@ -1477,12 +1636,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraints_uwVTYAddrMin_MSByte ,  0x1885,   0x0000 },
+ {   SensorFrameConstraints_uwVTXAddrMax_LSByte ,  0x188a,   0x0000 },
+@@ -1475,16 +1634,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraints_uwMaxVTLineLengthPck_MSByte ,  0x18ad,   0x0000 },
+ {   SensorFrameConstraints_uwMinVTLineBlankingPck_LSByte ,  0x18b2,   0x0000 },
  {   SensorFrameConstraints_uwMinVTLineBlankingPck_MSByte ,  0x18b1,   0x0000 },
  {   SensorFrameConstraints_uwMinVTFrameBlanking_LSByte ,  0x18b6,   0x0000 },
  {   SensorFrameConstraints_uwMinVTFrameBlanking_MSByte ,  0x18b5,   0x0000 },
@@ -597,7 +688,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FrameDimensionStatus_fFrameLengthChangePending ,  0x1980,   0x0000 },
  {   FrameDimensionStatus_fFrameDimensionChangePending ,  0x1982,   0x0000 },
  {   FrameDimensionStatus_uwVTFrameLengthPending_lines_LSByte ,  0x1986,   0x0000 },
-@@ -1505,49 +1670,93 @@ struct nomadik_vpip_param vpip_default_p
+ {   FrameDimensionStatus_uwVTFrameLengthPending_lines_MSByte ,  0x1985,   0x0000 },
+ {   FrameDimensionStatus_fFrameLengthChangeInhibitedForCoarseExposure ,  0x1988,   0x0000 },
+@@ -1503,53 +1668,97 @@ struct nomadik_vpip_param vpip_default_p
+ {   FrameDimensionStatus_uwMaximumSensorFOVY_LSByte ,  0x19a4,   0x0000 },
+ {   FrameDimensionStatus_uwMaximumSensorFOVY_MSByte ,  0x19a3,   0x0000 },
  {   FrameDimensionStatus_uwOPXOutputSize_LSByte ,  0x19a8,   0x0000 },
  {   FrameDimensionStatus_uwOPXOutputSize_MSByte ,  0x19a7,   0x0000 },
  {   FrameDimensionStatus_fSensorPreScaleFactorChanged ,  0x19aa,   0x0000 },
@@ -706,7 +801,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FlashManagerStatus_fFlashSequencePending ,  0x1d00,   0x0000 },
  {   FlashManagerStatus_cNumberFramesRequiredForPreFlashes ,  0x1d02,   0x0000 },
  {   FlashManagerStatus_fpMainFlashPulseWidth_us_LSByte ,  0x1d06,   0x0000 },
-@@ -1571,24 +1780,29 @@ struct nomadik_vpip_param vpip_default_p
+ {   FlashManagerStatus_fpMainFlashPulseWidth_us_MSByte ,  0x1d05,   0x0000 },
+ {   FlashManagerStatus_fpPreFlashPulseWidth_us_LSByte ,  0x1d0a,   0x0000 },
+@@ -1569,46 +1778,61 @@ struct nomadik_vpip_param vpip_default_p
+ {   FlashManagerStatus_wStartPreFlashPixel_LSByte ,  0x1d26,   0x0000 },
+ {   FlashManagerStatus_wStartPreFlashPixel_MSByte ,  0x1d25,   0x0000 },
  {   FlashManagerStatus_cNumberFramesRequired ,  0x1d28,   0x0000 },
  {   FlashManagerStatus_fPreFlashPending ,  0x1d2a,   0x0000 },
  {   FlashManagerStatus_fMainFlashPending ,  0x1d2c,   0x0000 },
@@ -740,7 +839,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureControls_uwFlashGunModeCoarseIntegration_lines_LSByte ,  0x1da6,   0x0000 },
  {   ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte ,  0x1da5,   0x0000 },
  {   ExposureControls_uwFlashGunModeFineIntegration_pixels_LSByte ,  0x1daa,   0x0000 },
-@@ -1599,14 +1813,24 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte ,  0x1da9,   0x0000 },
+ {   ExposureControls_uwFlashGunModeCodedAnalogGain_LSByte ,  0x1dae,   0x0000 },
+ {   ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte ,  0x1dad,   0x0000 },
+ {   ExposureControls_fpFlashGunModeDigitalGain_LSByte ,  0x1db2,   0x0000 },
  {   ExposureControls_fpFlashGunModeDigitalGain_MSByte ,  0x1db1,   0x0000 },
  {   ExposureControls_fFreezeAutoExposure ,  0x1db4,   0x0000 },
  {   ExposureControls_fpUserMaximumIntegrationTime_us_LSByte ,  0x1db8,   0x0000 },
@@ -767,7 +869,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureStatus_fWhiteBalanceGainIncludedInCurrentExposure ,  0x1e04,   0x0000 },
  {   ExposureStatus_fBadExposureForIterativeWhiteBalance ,  0x1e06,   0x0000 },
  {   ExposureStatus_uwCoarseIntegrationPending_lines_LSByte ,  0x1e0a,   0x0000 },
-@@ -1630,6 +1854,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureStatus_uwCoarseIntegrationPending_lines_MSByte ,  0x1e09,   0x0000 },
+ {   ExposureStatus_uwFineIntegrationPending_pixels_LSByte ,  0x1e0e,   0x0000 },
+@@ -1628,31 +1852,46 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureStatus_fpTotalIntegrationTimePending_us_MSByte ,  0x1e27,   0x0000 },
+ {   ExposureStatus_uwCodedAnalogGainPending_LSByte ,  0x1e2c,   0x0000 },
  {   ExposureStatus_uwCodedAnalogGainPending_MSByte ,  0x1e2b,   0x0000 },
  {   ExposureStatus_fExposureIsStableforAutoFocus ,  0x1e2e,   0x0000 },
  {   ExposureStatus_bRuntimeExposureTarget ,  0x1e30,   0x0000 },
@@ -777,7 +883,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureParametersApplied_uwCoarseIntegration_lines_LSByte ,  0x1e82,   0x0000 },
  {   ExposureParametersApplied_uwCoarseIntegration_lines_MSByte ,  0x1e81,   0x0000 },
  {   ExposureParametersApplied_uwFineIntegration_pixels_LSByte ,  0x1e86,   0x0000 },
-@@ -1638,8 +1865,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureParametersApplied_uwFineIntegration_pixels_MSByte ,  0x1e85,   0x0000 },
+ {   ExposureParametersApplied_uwCodedAnalogGain_LSByte ,  0x1e8a,   0x0000 },
  {   ExposureParametersApplied_uwCodedAnalogGain_MSByte ,  0x1e89,   0x0000 },
  {   ExposureParametersApplied_fpDigitalGain_LSByte ,  0x1e8e,   0x0000 },
  {   ExposureParametersApplied_fpDigitalGain_MSByte ,  0x1e8d,   0x0000 },
@@ -792,7 +899,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureCycleTest_fpInitialDesiredExposureTime_LSByte ,  0x1f82,   0x0000 },
  {   ExposureCycleTest_fpInitialDesiredExposureTime_MSByte ,  0x1f81,   0x0000 },
  {   ExposureCycleTest_fpFinalDesiredExposureTime_LSByte ,  0x1f86,   0x0000 },
-@@ -1647,10 +1880,16 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureCycleTest_fpFinalDesiredExposureTime_MSByte ,  0x1f85,   0x0000 },
  {   ExposureCycleTest_fpExposureStep_LSByte ,  0x1f8a,   0x0000 },
  {   ExposureCycleTest_fpExposureStep_MSByte ,  0x1f89,   0x0000 },
  {   ExposureCycleTest_bStepDirection ,  0x1f8c,   0x0000 },
@@ -809,7 +916,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureAlgorithmControls_fpMaximumStep_LSByte ,  0x2082,   0x0000 },
  {   ExposureAlgorithmControls_fpMaximumStep_MSByte ,  0x2081,   0x0000 },
  {   ExposureAlgorithmControls_fpMinimumStep_LSByte ,  0x2086,   0x0000 },
-@@ -1664,9 +1903,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpMinimumStep_MSByte ,  0x2085,   0x0000 },
+ {   ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_LSByte ,  0x208a,   0x0000 },
+@@ -1662,13 +1901,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_LSByte ,  0x2092,   0x0000 },
+ {   ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_MSByte ,  0x2091,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_LSByte ,  0x2096,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_MSByte ,  0x2095,   0x0000 },
  {   ExposureAlgorithmControls_fpDigitalGainFloor_LSByte ,  0x209a,   0x0000 },
@@ -824,7 +935,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_LSByte ,  0x20a2,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_MSByte ,  0x20a1,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_LSByte ,  0x20a6,   0x0000 },
-@@ -1682,34 +1926,61 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_MSByte ,  0x20a5,   0x0000 },
+ {   ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_LSByte ,  0x20aa,   0x0000 },
+@@ -1680,53 +1924,103 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpMaximumManualExposureTime_s_LSByte ,  0x20b6,   0x0000 },
+ {   ExposureAlgorithmControls_fpMaximumManualExposureTime_s_MSByte ,  0x20b5,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_LSByte ,  0x20ba,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_MSByte ,  0x20b9,   0x0000 },
  {   ExposureAlgorithmControls_bLeakShift ,  0x20bc,   0x0000 },
@@ -891,7 +1006,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceStatus_bStatus ,  0x2380,   0x0000 },
  {   WhiteBalanceStatus_fUnityGainsUsed ,  0x2382,   0x0000 },
  {   WhiteBalanceStatus_fpRedGain_LSByte ,  0x2386,   0x0000 },
-@@ -1718,13 +1989,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceStatus_fpRedGain_MSByte ,  0x2385,   0x0000 },
+ {   WhiteBalanceStatus_fpGreenGain_LSByte ,  0x238a,   0x0000 },
  {   WhiteBalanceStatus_fpGreenGain_MSByte ,  0x2389,   0x0000 },
  {   WhiteBalanceStatus_fpBlueGain_LSByte ,  0x238e,   0x0000 },
  {   WhiteBalanceStatus_fpBlueGain_MSByte ,  0x238d,   0x0000 },
@@ -928,7 +1044,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MinWeightedWBControls_fDisable ,  0x2500,   0x0000 },
  {   MinWeightedWBControls_uwSaturationThreshold_LSByte ,  0x2504,   0x0000 },
  {   MinWeightedWBControls_uwSaturationThreshold_MSByte ,  0x2503,   0x0300 },
-@@ -1737,6 +2031,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   MinWeightedWBControls_fpRedTiltGain_LSByte ,  0x2508,   0x0000 },
+ {   MinWeightedWBControls_fpRedTiltGain_MSByte ,  0x2507,   0x3e00 },
+@@ -1735,38 +2029,56 @@ struct nomadik_vpip_param vpip_default_p
+ {   MinWeightedWBControls_fpGreen2TiltGain_LSByte ,  0x2510,   0x0000 },
+ {   MinWeightedWBControls_fpGreen2TiltGain_MSByte ,  0x250f,   0x3e40 },
  {   MinWeightedWBControls_fpBlueTiltGain_LSByte ,  0x2514,   0x0000 },
  {   MinWeightedWBControls_fpBlueTiltGain_MSByte ,  0x2513,   0x3e40 },
  {   MinWeightedWBControls_GreenChannelToAccumulate ,  0x2516,   0x0000 },
@@ -938,7 +1058,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MinWeightedWBStatus_uwZone_X_Offset_LSByte ,  0x2582,   0x0000 },
  {   MinWeightedWBStatus_uwZone_X_Offset_MSByte ,  0x2581,   0x0000 },
  {   MinWeightedWBStatus_uwZone_Y_Offset_LSByte ,  0x2586,   0x0000 },
-@@ -1747,24 +2044,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   MinWeightedWBStatus_uwZone_Y_Offset_MSByte ,  0x2585,   0x0000 },
+ {   MinWeightedWBStatus_uwZone_X_Size_LSByte ,  0x258a,   0x0000 },
+ {   MinWeightedWBStatus_uwZone_X_Size_MSByte ,  0x2589,   0x0000 },
+ {   MinWeightedWBStatus_uwZone_Y_Size_LSByte ,  0x258e,   0x0000 },
  {   MinWeightedWBStatus_uwZone_Y_Size_MSByte ,  0x258d,   0x0000 },
  {   MinWeightedWBStatus_fpNumberMacroPixel_LSByte ,  0x2592,   0x0000 },
  {   MinWeightedWBStatus_fpNumberMacroPixel_MSByte ,  0x2591,   0x0000 },
@@ -988,7 +1111,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutomaticFrameRateStatus_fpImpliedGain_LSByte ,  0x2782,   0x0000 },
  {   AutomaticFrameRateStatus_fpImpliedGain_MSByte ,  0x2781,   0x0000 },
  {   AutomaticFrameRateStatus_uwMaximumFrameLength_lines_LSByte ,  0x2786,   0x0000 },
-@@ -1781,9 +2093,20 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutomaticFrameRateStatus_uwMaximumFrameLength_lines_MSByte ,  0x2785,   0x0000 },
+ {   AutomaticFrameRateStatus_uwMinimumFrameLength_lines_LSByte ,  0x278a,   0x0000 },
+@@ -1779,32 +2091,99 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutomaticFrameRateStatus_uwCurrentFrameLength_lines_MSByte ,  0x2795,   0x0000 },
+ {   AutomaticFrameRateStatus_uwDesiredFrameLength_lines_LSByte ,  0x279a,   0x0000 },
  {   AutomaticFrameRateStatus_uwDesiredFrameLength_lines_MSByte ,  0x2799,   0x0000 },
  {   AutomaticFrameRateStatus_fAutomaticFrameRateStable ,  0x279c,   0x0000 },
  {   AutomaticFrameRateStatus_fAutomaticFrameRateClip ,  0x279e,   0x0000 },
@@ -1009,7 +1136,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   StaticFrameRateStatus_uwRequestedFrameRate_Hz_LSByte ,  0x2882,   0x0000 },
  {   StaticFrameRateStatus_uwRequestedFrameRate_Hz_MSByte ,  0x2881,   0x0000 },
  {   StaticFrameRateStatus_uwMaxFrameRate_Hz_LSByte ,  0x2886,   0x0000 },
-@@ -1794,15 +2117,71 @@ struct nomadik_vpip_param vpip_default_p
+ {   StaticFrameRateStatus_uwMaxFrameRate_Hz_MSByte ,  0x2885,   0x0000 },
+ {   StaticFrameRateStatus_uwMinFrameRate_Hz_LSByte ,  0x288a,   0x0000 },
+ {   StaticFrameRateStatus_uwMinFrameRate_Hz_MSByte ,  0x2889,   0x0000 },
+ {   StaticFrameRateStatus_fChangePending ,  0x288c,   0x0000 },
  {   StaticFrameRateStatus_uwRequiredFrameLength_lines_LSByte ,  0x2890,   0x0000 },
  {   StaticFrameRateStatus_uwRequiredFrameLength_lines_MSByte ,  0x288f,   0x0000 },
  {   StaticFrameRateStatus_ClipFrameRate ,  0x2892,   0x0000 },
@@ -1081,7 +1211,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte ,  0x2b02,   0x0000 },
  {   ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte ,  0x2b01,   0x3fd3 },
  {   ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte ,  0x2b06,   0x0000 },
-@@ -1821,6 +2200,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte ,  0x2b05,   0xbce0 },
+ {   ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte ,  0x2b0a,   0x0000 },
+@@ -1819,10 +2198,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte ,  0x2b19,   0xb717 },
+ {   ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte ,  0x2b1e,   0x0000 },
  {   ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte ,  0x2b1d,   0xbd29 },
  {   ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte ,  0x2b22,   0x0000 },
  {   ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte ,  0x2b21,   0x3fc6 },
@@ -1090,7 +1224,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte ,  0x2b82,   0x0002 },
  {   ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte ,  0x2b81,   0x6400 },
  {   ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte ,  0x2b86,   0x0002 },
-@@ -1839,6 +2220,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte ,  0x2b85,   0x6400 },
+ {   ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte ,  0x2b8a,   0x0002 },
+@@ -1837,10 +2218,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte ,  0x2b99,   0xe900 },
+ {   ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte ,  0x2b9e,   0x0000 },
  {   ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte ,  0x2b9d,   0xe900 },
  {   ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte ,  0x2ba2,   0x0000 },
  {   ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte ,  0x2ba1,   0xe900 },
@@ -1100,7 +1238,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixDamped_wRInR_LSByte ,  0x2c02,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wRInR_MSByte ,  0x2c01,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wGInR_LSByte ,  0x2c06,   0x0000 },
-@@ -1857,6 +2241,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixDamped_wGInR_MSByte ,  0x2c05,   0x0000 },
+ {   ColourEngine0_ColourMatrixDamped_wBInR_LSByte ,  0x2c0a,   0x0000 },
+@@ -1855,17 +2239,53 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixDamped_wRInB_MSByte ,  0x2c19,   0x0000 },
+ {   ColourEngine0_ColourMatrixDamped_wGInB_LSByte ,  0x2c1e,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wGInB_MSByte ,  0x2c1d,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wBInB_LSByte ,  0x2c22,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wBInB_MSByte ,  0x2c21,   0x0000 },
@@ -1119,7 +1261,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping ,  0x2c80,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte ,  0x2c84,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte ,  0x2c83,   0x62ac },
-@@ -1864,6 +2260,30 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte ,  0x2c88,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte ,  0x2c87,   0x64ac },
  {   ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte ,  0x2c8c,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte ,  0x2c8b,   0x0000 },
@@ -1150,7 +1292,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ApertureCorrectionControls_fDisableCorrection ,  0x2d00,   0x0000 },
  {   ColourEngine0_ApertureCorrectionControls_bMaxGain ,  0x2d02,   0x0010 },
  {   ColourEngine0_ApertureCorrectionControls_fDisableGainDamping ,  0x2d04,   0x0000 },
-@@ -1882,9 +2302,25 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_LSByte ,  0x2d08,   0x0000 },
+ {   ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte ,  0x2d07,   0x5871 },
+@@ -1880,21 +2300,53 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte ,  0x2d19,   0x5871 },
+ {   ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_LSByte ,  0x2d1e,   0x0000 },
  {   ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte ,  0x2d1d,   0x63d1 },
  {   ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_LSByte ,  0x2d22,   0x0000 },
  {   ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte ,  0x2d21,   0x3a00 },
@@ -1176,7 +1322,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_GammaCorrection_fEnabled ,  0x2e00,   0x0001 },
  {   ColourEngine0_GammaCorrection_bMode ,  0x2e02,   0x0001 },
  {   ColourEngine0_GammaCorrection_SharpRed ,  0x2e04,   0x0013 },
-@@ -1893,6 +2329,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_GammaCorrection_SharpGreen ,  0x2e06,   0x0013 },
+ {   ColourEngine0_GammaCorrection_SharpBlue ,  0x2e08,   0x0013 },
  {   ColourEngine0_GammaCorrection_SoftRed ,  0x2e0a,   0x0013 },
  {   ColourEngine0_GammaCorrection_SoftGreen ,  0x2e0c,   0x0013 },
  {   ColourEngine0_GammaCorrection_SoftBlue ,  0x2e0e,   0x0013 },
@@ -1199,7 +1346,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   NoraControls_fDisable ,  0x2e80,   0x0001 },
  {   NoraControls_fDisableNoraPromoting ,  0x2e82,   0x0000 },
  {   NoraControls_bMaximumValue ,  0x2e84,   0x0001 },
-@@ -1905,7 +2357,33 @@ struct nomadik_vpip_param vpip_default_p
+ {   NoraControls_fDifferentTextureDegreeForBlue ,  0x2e86,   0x0000 },
+ {   NoraControls_fSplitNoiseLevel ,  0x2e88,   0x0000 },
+@@ -1903,11 +2355,37 @@ struct nomadik_vpip_param vpip_default_p
+ {   NoraControls_DamperLowThreshold_MSByte ,  0x2e8d,   0x4000 },
+ {   NoraControls_DamperHighThreshold_LSByte ,  0x2e92,   0x0000 },
  {   NoraControls_DamperHighThreshold_MSByte ,  0x2e91,   0x4500 },
  {   NoraControls_MinimumDamperOutput_LSByte ,  0x2e96,   0x0000 },
  {   NoraControls_MinimumDamperOutput_MSByte ,  0x2e95,   0x0000 },
@@ -1233,7 +1384,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ScytheFilterControls_fDisableFilter ,  0x2f80,   0x0000 },
  {   ScytheFilterControls_fSquareLaw ,  0x2f82,   0x0000 },
  {   ScytheFilterControls_fDisablePromotingLow ,  0x2f84,   0x0000 },
-@@ -1924,6 +2402,29 @@ struct nomadik_vpip_param vpip_default_p
+ {   ScytheFilterControls_fDisablePromotingHigh ,  0x2f86,   0x0000 },
+ {   ScytheFilterControls_bMaxWeightLow ,  0x2f88,   0x0010 },
+@@ -1922,10 +2400,33 @@ struct nomadik_vpip_param vpip_default_p
+ {   ScytheFilterControls_fpDamperHighThresholdHigh_MSByte ,  0x2f99,   0x68dc },
+ {   ScytheFilterControls_fpMinimumDamperOutputLow_LSByte ,  0x2f9e,   0x0000 },
  {   ScytheFilterControls_fpMinimumDamperOutputLow_MSByte ,  0x2f9d,   0x3a00 },
  {   ScytheFilterControls_fpMinimumDamperOutputHigh_LSByte ,  0x2fa2,   0x0000 },
  {   ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte ,  0x2fa1,   0x3a00 },
@@ -1263,7 +1418,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   JackFilterControls_fDisableFilter ,  0x3000,   0x0000 },
  {   JackFilterControls_fSquareLaw ,  0x3002,   0x0000 },
  {   JackFilterControls_fDisablePromotingLow ,  0x3004,   0x0000 },
-@@ -1942,10 +2443,25 @@ struct nomadik_vpip_param vpip_default_p
+ {   JackFilterControls_fDisablePromotingHigh ,  0x3006,   0x0000 },
+ {   JackFilterControls_bMaxWeightLow ,  0x3008,   0x0010 },
+@@ -1940,103 +2441,208 @@ struct nomadik_vpip_param vpip_default_p
+ {   JackFilterControls_fpDamperHighThresholdHigh_MSByte ,  0x3019,   0x68dc },
+ {   JackFilterControls_fpMinimumDamperOutputLow_LSByte ,  0x301e,   0x0000 },
  {   JackFilterControls_fpMinimumDamperOutputLow_MSByte ,  0x301d,   0x0000 },
  {   JackFilterControls_fpMinimumDamperOutputHigh_LSByte ,  0x3022,   0x0000 },
  {   JackFilterControls_fpMinimumDamperOutputHigh_MSByte ,  0x3021,   0x0000 },
@@ -1289,7 +1448,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VfpnControls_fEnableCorrection ,  0x3100,   0x0000 },
  {   VfpnControls_uwMaximumPixelValue_LSByte ,  0x3104,   0x0000 },
  {   VfpnControls_uwMaximumPixelValue_MSByte ,  0x3103,   0x03ff },
-@@ -1954,15 +2470,61 @@ struct nomadik_vpip_param vpip_default_p
+ {   VfpnControls_uwMinimumPixelValue_LSByte ,  0x3108,   0x0000 },
+ {   VfpnControls_uwMinimumPixelValue_MSByte ,  0x3107,   0x0000 },
  {   VfpnControls_uwPixelSaturationLevel_LSByte ,  0x310c,   0x0000 },
  {   VfpnControls_uwPixelSaturationLevel_MSByte ,  0x310b,   0x03ff },
  {   VfpnControls_bLogThreshLog ,  0x310e,   0x0004 },
@@ -1354,7 +1514,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControls_bFilterCoeff_R2_b ,  0x3208,   0x0000 },
  {   AntiVignetteControls_bFilterCoeff_R4_r ,  0x320a,   0x0000 },
  {   AntiVignetteControls_bFilterCoeff_R4_gr ,  0x320c,   0x0000 },
-@@ -1972,8 +2534,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControls_bFilterCoeff_R4_gb ,  0x320e,   0x0000 },
+ {   AntiVignetteControls_bFilterCoeff_R4_b ,  0x3210,   0x0000 },
+ {   AntiVignetteControls_uwHorizontalOffset_LSByte ,  0x3214,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_MSByte ,  0x3213,   0x0000 },
  {   AntiVignetteControls_uwVerticalOffset_LSByte ,  0x3218,   0x0000 },
  {   AntiVignetteControls_uwVerticalOffset_MSByte ,  0x3217,   0x0000 },
@@ -1365,7 +1527,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControls_uwHorizontalOffset_r_LSByte ,  0x3220,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_r_MSByte ,  0x321f,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_gr_LSByte ,  0x3224,   0x0000 },
-@@ -1983,18 +2545,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControls_uwHorizontalOffset_gr_MSByte ,  0x3223,   0x0000 },
+ {   AntiVignetteControls_uwHorizontalOffset_gb_LSByte ,  0x3228,   0x0000 },
+ {   AntiVignetteControls_uwHorizontalOffset_gb_MSByte ,  0x3227,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_b_LSByte ,  0x322c,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_b_MSByte ,  0x322b,   0x0000 },
  {   AntiVignetteControls_uwVerticalOffset_r_LSByte ,  0x3230,   0x0000 },
@@ -1394,7 +1558,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteStatus_fXScaleEnabled ,  0x3280,   0x0000 },
  {   AntiVignetteStatus_bXScale ,  0x3282,   0x0000 },
  {   AntiVignetteStatus_fYScaleEnabled ,  0x3284,   0x0000 },
-@@ -2003,13 +2569,35 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteStatus_bYScale ,  0x3286,   0x0000 },
+ {   AntiVignetteStatus_uwHorizontalSize_LSByte ,  0x328a,   0x0000 },
  {   AntiVignetteStatus_uwHorizontalSize_MSByte ,  0x3289,   0x0000 },
  {   AntiVignetteStatus_uwVerticalSize_LSByte ,  0x328e,   0x0000 },
  {   AntiVignetteStatus_uwVerticalSize_MSByte ,  0x328d,   0x0000 },
@@ -1431,7 +1596,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_LSByte ,  0x3402,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_MSByte ,  0x3401,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_LSByte ,  0x3406,   0x0000 },
-@@ -2018,9 +2606,21 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_MSByte ,  0x3405,   0x0000 },
+ {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_LSByte ,  0x340a,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_MSByte ,  0x3409,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_LSByte ,  0x340e,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_MSByte ,  0x340d,   0x0000 },
@@ -1453,7 +1619,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_LSByte ,  0x3502,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte ,  0x3501,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_LSByte ,  0x3506,   0x0000 },
-@@ -2029,12 +2629,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte ,  0x3505,   0x0000 },
+ {   ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte ,  0x350a,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte ,  0x3509,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_LSByte ,  0x350e,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte ,  0x350d,   0x0000 },
@@ -1472,7 +1639,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_OutputCoderMatrix_w0_0_LSByte ,  0x3602,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w0_0_MSByte ,  0x3601,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w0_1_LSByte ,  0x3606,   0x0000 },
-@@ -2053,6 +2659,20 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_OutputCoderMatrix_w0_1_MSByte ,  0x3605,   0x0000 },
+ {   ColourEngine0_OutputCoderMatrix_w0_2_LSByte ,  0x360a,   0x0000 },
+@@ -2051,37 +2657,91 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_OutputCoderMatrix_w2_0_MSByte ,  0x3619,   0x0000 },
+ {   ColourEngine0_OutputCoderMatrix_w2_1_LSByte ,  0x361e,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w2_1_MSByte ,  0x361d,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w2_2_LSByte ,  0x3622,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w2_2_MSByte ,  0x3621,   0x0000 },
@@ -1493,7 +1664,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_FadeToBlack_fDisable ,  0x3680,   0x0001 },
  {   ColourEngine0_FadeToBlack_fpBlackValue_LSByte ,  0x3684,   0x0000 },
  {   ColourEngine0_FadeToBlack_fpBlackValue_MSByte ,  0x3683,   0x0000 },
-@@ -2062,10 +2682,48 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte ,  0x3688,   0x0000 },
+ {   ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte ,  0x3687,   0x63d1 },
+ {   ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte ,  0x368c,   0x0000 },
  {   ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte ,  0x368b,   0x656f },
  {   ColourEngine0_FadeToBlack_fpDamperOutput_LSByte ,  0x3690,   0x0000 },
  {   ColourEngine0_FadeToBlack_fpDamperOutput_MSByte ,  0x368f,   0x0000 },
@@ -1542,7 +1715,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrParams_fAntiZip ,  0x3780,   0x0000 },
  {   ZoomMgrParams_bFilterCrispness0 ,  0x3782,   0x0000 },
  {   ZoomMgrParams_bFilterCrispness1 ,  0x3784,   0x0000 },
-@@ -2074,12 +2732,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrParams_fInFromOutARLock ,  0x3786,   0x0000 },
+ {   ZoomMgrParams_bPrescaleFactor ,  0x3788,   0x0000 },
  {   ZoomMgrParams_bPrescaleType ,  0x378a,   0x0000 },
  {   ZoomMgrParams_fp16ZoomRange_LSByte ,  0x378e,   0x0000 },
  {   ZoomMgrParams_fp16ZoomRange_MSByte ,  0x378d,   0x100 },
@@ -1558,7 +1732,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrCtrl_bChgOverMarginShift ,  0x380c,   0x0000 },
  {   ZoomMgrCtrl_fCheckDataRate ,  0x380e,   0x0000 },
  {   ZoomMgrCtrl_fSetAlternateInitWOI ,  0x3810,   0x0000 },
-@@ -2091,6 +2751,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrCtrl_fSetX_Byte0 ,  0x3812,   0x0000 },
+ {   ZoomMgrCtrl_fSetX_Byte1 ,  0x3814,   0x0000 },
+@@ -2089,10 +2749,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrCtrl_fSetX_Byte3 ,  0x3818,   0x0000 },
+ {   ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte ,  0x381c,   0x0000 },
  {   ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte ,  0x381b,   0x0000 },
  {   ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte ,  0x3820,   0x0000 },
  {   ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte ,  0x381f,   0x0000 },
@@ -1568,7 +1746,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrStatus_fReady ,  0x3880,   0x0000 },
  {   ZoomMgrStatus_bDeviceTestCoin ,  0x3882,   0x0000 },
  {   ZoomMgrStatus_bNextCmd ,  0x3884,   0x0000 },
-@@ -2124,6 +2787,24 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrStatus_bLastCmd ,  0x3886,   0x0000 },
+ {   ZoomMgrStatus_bCommandStatus ,  0x3888,   0x0000 },
+@@ -2122,10 +2785,28 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrStatus_fMinFOVX_Byte3 ,  0x38b8,   0x0000 },
+ {   ZoomMgrStatus_uwXOrigin_LSByte ,  0x38bc,   0x0000 },
  {   ZoomMgrStatus_uwXOrigin_MSByte ,  0x38bb,   0x0000 },
  {   ZoomMgrStatus_uwYOrigin_LSByte ,  0x38c0,   0x0000 },
  {   ZoomMgrStatus_uwYOrigin_MSByte ,  0x38bf,   0x0000 },
@@ -1593,7 +1775,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceConstrainerControls_fpRedA_LSByte ,  0x3902,   0x0000 },
  {   WhiteBalanceConstrainerControls_fpRedA_MSByte ,  0x3901,   0x0000 },
  {   WhiteBalanceConstrainerControls_fpBlueA_LSByte ,  0x3906,   0x0000 },
-@@ -2135,6 +2816,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerControls_fpBlueA_MSByte ,  0x3905,   0x0000 },
+ {   WhiteBalanceConstrainerControls_fpRedB_LSByte ,  0x390a,   0x0000 },
+@@ -2133,25 +2814,34 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerControls_fpBlueB_LSByte ,  0x390e,   0x0000 },
+ {   WhiteBalanceConstrainerControls_fpBlueB_MSByte ,  0x390d,   0x3acf },
  {   WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_LSByte ,  0x3912,   0x0000 },
  {   WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte ,  0x3911,   0x2e8e },
  {   WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance ,  0x3914,   0x0001 },
@@ -1603,7 +1789,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceConstrainerOutput_fpOutputRedGain_LSByte ,  0x3982,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputRedGain_MSByte ,  0x3981,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputGreenGain_LSByte ,  0x3986,   0x0000 },
-@@ -2142,6 +2826,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerOutput_fpOutputGreenGain_MSByte ,  0x3985,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputBlueGain_LSByte ,  0x398a,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputBlueGain_MSByte ,  0x3989,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fAreGainsConstrained ,  0x398c,   0x0000 },
@@ -1613,7 +1799,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_LSByte ,  0x3a02,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_MSByte ,  0x3a01,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_LSByte ,  0x3a06,   0x0000 },
-@@ -2150,6 +2837,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_MSByte ,  0x3a05,   0x0000 },
+ {   WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_LSByte ,  0x3a0a,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_MSByte ,  0x3a09,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_LSByte ,  0x3a0e,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_MSByte ,  0x3a0d,   0x0000 },
@@ -1623,7 +1810,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeSetupBank1_uwInputImageSize_X_LSByte ,  0x3a82,   0x0000 },
  {   ModeSetupBank1_uwInputImageSize_X_MSByte ,  0x3a81,   0x0000 },
  {   ModeSetupBank1_uwInputImageSize_Y_LSByte ,  0x3a86,   0x0000 },
-@@ -2162,7 +2852,7 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_uwInputImageSize_Y_MSByte ,  0x3a85,   0x0000 },
+ {   ModeSetupBank1_uwMaxImageSize_X_LSByte ,  0x3a8a,   0x0000 },
+@@ -2160,11 +2850,11 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_uwMaxImageSize_Y_MSByte ,  0x3a8d,   0x0000 },
+ {   ModeSetupBank1_uwMinImageSize_X_LSByte ,  0x3a92,   0x0000 },
  {   ModeSetupBank1_uwMinImageSize_X_MSByte ,  0x3a91,   0x0000 },
  {   ModeSetupBank1_uwMinImageSize_Y_LSByte ,  0x3a96,   0x0000 },
  {   ModeSetupBank1_uwMinImageSize_Y_MSByte ,  0x3a95,   0x0000 },
@@ -1632,7 +1823,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeSetupBank1_fLowPowerStreaming ,  0x3a9a,   0x0000 },
  {   ModeSetupBank1_bTestMode ,  0x3a9c,   0x0000 },
  {   ModeSetupBank1_bNumberOfStatusLines ,  0x3a9e,   0x0000 },
-@@ -2175,9 +2865,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_bNumberOfDarkLines ,  0x3aa0,   0x0000 },
+ {   ModeSetupBank1_bNumberOfBlackLines ,  0x3aa2,   0x0000 },
+@@ -2173,13 +2863,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_uwNumberOfInterFrameLines_LSByte ,  0x3aaa,   0x0000 },
+ {   ModeSetupBank1_uwNumberOfInterFrameLines_MSByte ,  0x3aa9,   0x0000 },
  {   ModeSetupBank1_bNumberOfDummyColumns ,  0x3aac,   0x0000 },
  {   ModeSetupBank1_bInputImageSource ,  0x3aae,   0x0000 },
  {   ModeSetupBank1_bOutputImageDestination ,  0x3ab0,   0x0000 },
@@ -1652,7 +1847,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControlsFar_bFilterCoeff_R2_r ,  0x3c02,   0x0000 },
  {   AntiVignetteControlsFar_bFilterCoeff_R2_gr ,  0x3c04,   0x0000 },
  {   AntiVignetteControlsFar_bFilterCoeff_R2_gb ,  0x3c06,   0x0000 },
-@@ -2213,7 +2912,10 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsFar_bFilterCoeff_R2_b ,  0x3c08,   0x0000 },
+ {   AntiVignetteControlsFar_bFilterCoeff_R4_r ,  0x3c0a,   0x0000 },
+@@ -2211,11 +2910,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsFar_bUnityOffset_r ,  0x3c3e,   0x0000 },
+ {   AntiVignetteControlsFar_bUnityOffset_gr ,  0x3c40,   0x0000 },
  {   AntiVignetteControlsFar_bUnityOffset_gb ,  0x3c42,   0x0000 },
  {   AntiVignetteControlsFar_bUnityOffset_b ,  0x3c44,   0x0000 },
  {   AntiVignetteControlsFar_fAdaptiveAntiVignetteEnable ,  0x3c46,   0x0000 },
@@ -1664,7 +1863,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControlsNear_bFilterCoeff_R2_r ,  0x3c82,   0x0000 },
  {   AntiVignetteControlsNear_bFilterCoeff_R2_gr ,  0x3c84,   0x0000 },
  {   AntiVignetteControlsNear_bFilterCoeff_R2_gb ,  0x3c86,   0x0000 },
-@@ -2249,6 +2951,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsNear_bFilterCoeff_R2_b ,  0x3c88,   0x0000 },
+ {   AntiVignetteControlsNear_bFilterCoeff_R4_r ,  0x3c8a,   0x0000 },
+@@ -2247,19 +2949,25 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsNear_bUnityOffset_r ,  0x3cbe,   0x0000 },
+ {   AntiVignetteControlsNear_bUnityOffset_gr ,  0x3cc0,   0x0000 },
  {   AntiVignetteControlsNear_bUnityOffset_gb ,  0x3cc2,   0x0000 },
  {   AntiVignetteControlsNear_bUnityOffset_b ,  0x3cc4,   0x0000 },
  {   AntiVignetteControlsNear_fAdaptiveAntiVignetteEnable ,  0x3cc6,   0x0000 },
@@ -1674,7 +1877,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFStatsControls_fAbsSquareEnabled ,  0x3d00,   0x0000 },
  {   AFStatsControls_bCoringValue ,  0x3d02,   0x0000 },
  {   AFStatsControls_bWindowsSystem ,  0x3d04,   0x0000 },
-@@ -2258,6 +2963,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFStatsControls_bHRatio_Num ,  0x3d06,   0x0000 },
+ {   AFStatsControls_bHRatio_Den ,  0x3d08,   0x0000 },
+ {   AFStatsControls_bVRatio_Num ,  0x3d0a,   0x0000 },
  {   AFStatsControls_bVRatio_Den ,  0x3d0c,   0x0000 },
  {   AFStatsControls_bHostActiveZonesCounter ,  0x3d0e,   0x0000 },
  {   AFStatsControls_fAutoRefresh ,  0x3d10,   0x0000 },
@@ -1684,7 +1889,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFStatsStatus_bAFStats_Error ,  0x3d80,   0x0000 },
  {   AFStatsStatus_fAbsSquareEnabled ,  0x3d82,   0x0000 },
  {   AFStatsStatus_bCoringValue ,  0x3d84,   0x0000 },
-@@ -2282,6 +2990,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFStatsStatus_bWindowsSystem ,  0x3d86,   0x0000 },
+ {   AFStatsStatus_bActiveZonesCounter ,  0x3d88,   0x0000 },
+@@ -2280,10 +2988,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte1 ,  0x3da6,   0x0000 },
+ {   AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte2 ,  0x3da8,   0x0000 },
  {   AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte3 ,  0x3daa,   0x0000 },
  {   AFStatsStatus_uwStartingAFZoneLine_LSByte ,  0x3dae,   0x0000 },
  {   AFStatsStatus_uwStartingAFZoneLine_MSByte ,  0x3dad,   0x0000 },
@@ -1694,7 +1903,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFFocusStats_udwStatsValue_0_Byte0 ,  0x3e00,   0x0000 },
  {   AFFocusStats_udwStatsValue_0_Byte1 ,  0x3e02,   0x0000 },
  {   AFFocusStats_udwStatsValue_0_Byte2 ,  0x3e04,   0x0000 },
-@@ -2310,6 +3021,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFFocusStats_udwStatsValue_0_Byte3 ,  0x3e06,   0x0000 },
+ {   AFFocusStats_udwStatsValue_1_Byte0 ,  0x3e08,   0x0000 },
+@@ -2308,17 +3019,52 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFFocusStats_udwStatsValue_5_Byte3 ,  0x3e2e,   0x0000 },
+ {   AFFocusStats_udwStatsValue_6_Byte0 ,  0x3e30,   0x0000 },
  {   AFFocusStats_udwStatsValue_6_Byte1 ,  0x3e32,   0x0000 },
  {   AFFocusStats_udwStatsValue_6_Byte2 ,  0x3e34,   0x0000 },
  {   AFFocusStats_udwStatsValue_6_Byte3 ,  0x3e36,   0x0000 },
@@ -1704,7 +1917,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFLightStats_bStatsValue_0 ,  0x3e80,   0x0000 },
  {   AFLightStats_bStatsValue_1 ,  0x3e82,   0x0000 },
  {   AFLightStats_bStatsValue_2 ,  0x3e84,   0x0000 },
-@@ -2317,6 +3031,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFLightStats_bStatsValue_3 ,  0x3e86,   0x0000 },
  {   AFLightStats_bStatsValue_4 ,  0x3e88,   0x0000 },
  {   AFLightStats_bStatsValue_5 ,  0x3e8a,   0x0000 },
  {   AFLightStats_bStatsValue_6 ,  0x3e8c,   0x0000 },
@@ -1743,7 +1956,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FLADriverLowLevelParameters_wMinPosition_LSByte ,  0x3f02,   0x0000 },
  {   FLADriverLowLevelParameters_wMinPosition_MSByte ,  0x3f01,   0x0000 },
  {   FLADriverLowLevelParameters_wMaxPosition_LSByte ,  0x3f06,   0x0000 },
-@@ -2344,6 +3090,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverLowLevelParameters_wMaxPosition_MSByte ,  0x3f05,   0x0000 },
+ {   FLADriverLowLevelParameters_wHomePosition_LSByte ,  0x3f0a,   0x0000 },
+@@ -2342,20 +3088,26 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverLowLevelParameters_bNVM_PS_IBias ,  0x3f2c,   0x0000 },
+ {   FLADriverLowLevelParameters_bNVM_PS_RampGain ,  0x3f2e,   0x0000 },
  {   FLADriverLowLevelParameters_bNVM_PS_Type ,  0x3f30,   0x0000 },
  {   FLADriverLowLevelParameters_uwNVM_minidriver_m_c_LSByte ,  0x3f34,   0x0000 },
  {   FLADriverLowLevelParameters_uwNVM_minidriver_m_c_MSByte ,  0x3f33,   0x0000 },
@@ -1753,7 +1970,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FLADriverControls_bMMode ,  0x3f80,   0x0000 },
  {   FLADriverControls_wTargetPosition_LSByte ,  0x3f84,   0x0000 },
  {   FLADriverControls_wTargetPosition_MSByte ,  0x3f83,   0x0000 },
-@@ -2354,6 +3103,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverControls_wPositionTolerance_LSByte ,  0x3f88,   0x0000 },
+ {   FLADriverControls_wPositionTolerance_MSByte ,  0x3f87,   0x0000 },
+ {   FLADriverControls_uwTimeLimit_ms_LSByte ,  0x3f8c,   0x0000 },
+ {   FLADriverControls_uwTimeLimit_ms_MSByte ,  0x3f8b,   0x0000 },
  {   FLADriverControls_bTrigger ,  0x3f8e,   0x0000 },
  {   FLADriverControls_bSlewMode ,  0x3f90,   0x0000 },
  {   FLADriverControls_bSlewRate ,  0x3f92,   0x0000 },
@@ -1763,7 +1983,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FLADriverStatus_wLensPosition_LSByte ,  0x4002,   0x0000 },
  {   FLADriverStatus_wLensPosition_MSByte ,  0x4001,   0x0000 },
  {   FLADriverStatus_fLensIsMoving ,  0x4004,   0x0000 },
-@@ -2365,6 +3117,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverStatus_fLimitsExceeded ,  0x4006,   0x0000 },
+ {   FLADriverStatus_fLensIsAtHome ,  0x4008,   0x0000 },
+@@ -2363,10 +3115,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverStatus_bSkippedFrames ,  0x400c,   0x0000 },
+ {   FLADriverStatus_bCycles ,  0x400e,   0x0000 },
  {   FLADriverStatus_bMiniDriverTimeoutError ,  0x4010,   0x0000 },
  {   FLADriverStatus_wTargetPosition ,  0x4012,   0x0000 },
  {   FLADriverStatus_bLowLevelPosition ,  0x4014,   0x0000 },
@@ -1773,7 +1997,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FocusControls_fErrorReset ,  0x4080,   0x0000 },
  {   FocusControls_bRange ,  0x4082,   0x0000 },
  {   FocusControls_bMode ,  0x4084,   0x0000 },
-@@ -2376,6 +3131,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusControls_bAFCommand ,  0x4086,   0x0000 },
+ {   FocusControls_bLensCommand ,  0x4088,   0x0000 },
+@@ -2374,10 +3129,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusControls_fTestCoinEnabled ,  0x408c,   0x0000 },
+ {   FocusControls_bControlCoin ,  0x408e,   0x0000 },
  {   FocusControls_fInternalStats_Disable ,  0x4090,   0x0000 },
  {   FocusControls_bActuator_Disable ,  0x4092,   0x0000 },
  {   FocusControls_fInhibitAutoMetering ,  0x4094,   0x0000 },
@@ -1783,7 +2011,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FocusStatus_bModeStatus ,  0x4100,   0x0000 },
  {   FocusStatus_bAFCommandStatus ,  0x4102,   0x0000 },
  {   FocusStatus_bLensCommandStatus ,  0x4104,   0x0000 },
-@@ -2391,6 +3149,30 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusStatus_fAutoFocusEnabled ,  0x4106,   0x0000 },
+ {   FocusStatus_bRange ,  0x4108,   0x0000 },
+@@ -2389,10 +3147,34 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusStatus_fRunForTest ,  0x4114,   0x0000 },
+ {   FocusStatus_bStatusCoin ,  0x4116,   0x0000 },
  {   FocusStatus_fInternalStats_Disabled ,  0x4118,   0x0000 },
  {   FocusStatus_bActuator_Disabled ,  0x411a,   0x0000 },
  {   FocusStatus_bLastUsedAFSensor ,  0x411c,   0x0000 },
@@ -1814,7 +2046,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FocusRangeConstants_wFullRange_LensMinPosition_LSByte ,  0x4182,   0x0000 },
  {   FocusRangeConstants_wFullRange_LensMinPosition_MSByte ,  0x4181,   0x0000 },
  {   FocusRangeConstants_wFullRange_LensMaxPosition_LSByte ,  0x4186,   0x0000 },
-@@ -2409,6 +3191,34 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusRangeConstants_wFullRange_LensMaxPosition_MSByte ,  0x4185,   0x03ff },
+ {   FocusRangeConstants_wFullRange_LensRecoveryPosition_LSByte ,  0x418a,   0x0000 },
+@@ -2407,10 +3189,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusRangeConstants_wMacro_LensMinPosition_MSByte ,  0x4199,   0x0000 },
+ {   FocusRangeConstants_wMacro_LensMaxPosition_LSByte ,  0x419e,   0x0000 },
  {   FocusRangeConstants_wMacro_LensMaxPosition_MSByte ,  0x419d,   0x03ff },
  {   FocusRangeConstants_wMacro_LensRecoveryPosition_LSByte ,  0x41a2,   0x0000 },
  {   FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte ,  0x41a1,   0x01ff },
@@ -1849,7 +2085,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusControls_bHostCmd ,  0x4200,   0x0000 },
  {   AutoFocusControls_fFreezeIfStable ,  0x4202,   0x0000 },
  {   AutoFocusControls_fFMTesting_AutoDisable ,  0x4204,   0x0001 },
-@@ -2432,6 +3242,35 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusControls_fFastAFAlgoStart ,  0x4206,   0x0000 },
+ {   AutoFocusControls_fBackLight_Enable ,  0x4208,   0x0000 },
+@@ -2430,10 +3240,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusControls_fEnableTrakingZoneVariation ,  0x4224,   0x0000 },
+ {   AutoFocusControls_fEnableFunctionThresholdTest ,  0x4226,   0x0001 },
  {   AutoFocusControls_fForceTestState ,  0x4228,   0x0000 },
  {   AutoFocusControls_bManualAFNextState ,  0x422a,   0x0000 },
  {   AutoFocusControls_fResetHCSPos ,  0x422c,   0x0001 },
@@ -1885,7 +2125,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusConstants_bCoarseStep ,  0x4280,   0x0078 },
  {   AutoFocusConstants_bFineStep ,  0x4282,   0x0014 },
  {   AutoFocusConstants_bFullSearchStep ,  0x4284,   0x0000 },
-@@ -2456,11 +3295,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusConstants_bLeakyIntegratorConstant ,  0x4286,   0x0000 },
+ {   AutoFocusConstants_uwFineThreshold_LSByte ,  0x428a,   0x0000 },
+@@ -2454,15 +3293,21 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusConstants_bLightGap ,  0x42a6,   0x0000 },
+ {   AutoFocusConstants_uwDeltaValue_LSByte ,  0x42aa,   0x0000 },
  {   AutoFocusConstants_uwDeltaValue_MSByte ,  0x42a9,   0x0000 },
  {   AutoFocusConstants_uwMaxFineTh_LSByte ,  0x42ae,   0x0000 },
  {   AutoFocusConstants_uwMaxFineTh_MSByte ,  0x42ad,   0x0000 },
@@ -1903,7 +2147,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusStatus_bCycles ,  0x4380,   0x0000 },
  {   AutoFocusStatus_bHostCmd ,  0x4382,   0x0000 },
  {   AutoFocusStatus_bAF_PrevState ,  0x4384,   0x0000 },
-@@ -2495,10 +3340,16 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusStatus_bAF_State ,  0x4386,   0x0000 },
+ {   AutoFocusStatus_bAF_NextState ,  0x4388,   0x0000 },
+@@ -2493,14 +3338,20 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusStatus_uwTotalCoarseVariation_LSByte ,  0x43bc,   0x0000 },
+ {   AutoFocusStatus_uwTotalCoarseVariation_MSByte ,  0x43bb,   0x0000 },
  {   AutoFocusStatus_uwTotalFineVariation_LSByte ,  0x43c0,   0x0000 },
  {   AutoFocusStatus_uwTotalFineVariation_MSByte ,  0x43bf,   0x0000 },
  {   AutoFocusStatus_bCountVariationRegion ,  0x43c2,   0x0000 },
@@ -1920,7 +2168,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusMeasureData_udwFocusMeasure_Byte0 ,  0x4480,   0x0000 },
  {   AutoFocusMeasureData_udwFocusMeasure_Byte1 ,  0x4482,   0x0000 },
  {   AutoFocusMeasureData_udwFocusMeasure_Byte2 ,  0x4484,   0x0000 },
-@@ -2555,6 +3406,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusMeasureData_udwFocusMeasure_Byte3 ,  0x4486,   0x0000 },
+ {   AutoFocusMeasureData_udwPrevFocusMeasure_Byte0 ,  0x4488,   0x0000 },
+@@ -2553,24 +3404,33 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte3 ,  0x44e6,   0x0000 },
+ {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte0 ,  0x44e8,   0x0000 },
  {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte1 ,  0x44ea,   0x0000 },
  {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte2 ,  0x44ec,   0x0000 },
  {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte3 ,  0x44ee,   0x0000 },
@@ -1930,7 +2182,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusWeightControls_bWeight_0 ,  0x4500,   0x0000 },
  {   AutoFocusWeightControls_bWeight_1 ,  0x4502,   0x0000 },
  {   AutoFocusWeightControls_bWeight_2 ,  0x4504,   0x0000 },
-@@ -2562,6 +3416,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusWeightControls_bWeight_3 ,  0x4506,   0x0000 },
  {   AutoFocusWeightControls_bWeight_4 ,  0x4508,   0x0000 },
  {   AutoFocusWeightControls_bWeight_5 ,  0x450a,   0x0000 },
  {   AutoFocusWeightControls_bWeight_6 ,  0x450c,   0x0000 },
@@ -1940,7 +2192,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusDynamicWeight_bWeight_0 ,  0x4580,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_1 ,  0x4582,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_2 ,  0x4584,   0x0000 },
-@@ -2569,6 +3426,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusDynamicWeight_bWeight_3 ,  0x4586,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_4 ,  0x4588,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_5 ,  0x458a,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_6 ,  0x458c,   0x0000 },
@@ -1950,7 +2202,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusThresholds_uwCoarseThreshold_LSByte ,  0x4602,   0x0000 },
  {   AutoFocusThresholds_uwCoarseThreshold_MSByte ,  0x4601,   0x0000 },
  {   AutoFocusThresholds_uwFineThreshold_LSByte ,  0x4606,   0x0000 },
-@@ -2585,6 +3445,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThresholds_uwFineThreshold_MSByte ,  0x4605,   0x0000 },
+ {   AutoFocusThresholds_uwBeforeMotionBlur_LSByte ,  0x460a,   0x0000 },
+@@ -2583,10 +3443,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThresholds_udwCurrentVariation_Byte3 ,  0x4616,   0x0000 },
+ {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte0 ,  0x4618,   0x0000 },
  {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte1 ,  0x461a,   0x0000 },
  {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte2 ,  0x461c,   0x0000 },
  {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte3 ,  0x461e,   0x0000 },
@@ -1960,7 +2216,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusHeuristicConstants_uwLensPositionInputMax_LSByte ,  0x4682,   0x0000 },
  {   AutoFocusHeuristicConstants_uwLensPositionInputMax_MSByte ,  0x4681,   0x0000 },
  {   AutoFocusHeuristicConstants_uwLensPositionInputMin_LSByte ,  0x4686,   0x0000 },
-@@ -2601,6 +3464,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusHeuristicConstants_uwLensPositionInputMin_MSByte ,  0x4685,   0x0000 },
+ {   AutoFocusHeuristicConstants_bBrightnessInputMax ,  0x4688,   0x0000 },
+@@ -2599,10 +3462,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusHeuristicConstants_uwFineToCoarseMax_MSByte ,  0x4695,   0x0000 },
+ {   AutoFocusHeuristicConstants_uwFineToCoarseMin_LSByte ,  0x469a,   0x0000 },
  {   AutoFocusHeuristicConstants_uwFineToCoarseMin_MSByte ,  0x4699,   0x0000 },
  {   AutoFocusHeuristicConstants_bHighToMaxFMShiftFactor ,  0x469c,   0x0000 },
  {   AutoFocusHeuristicConstants_bLowToHighFMShiftFactor ,  0x469e,   0x0000 },
@@ -1970,7 +2230,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte0 ,  0x4700,   0x0000 },
  {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte1 ,  0x4702,   0x0000 },
  {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte2 ,  0x4704,   0x0000 },
-@@ -2616,19 +3482,31 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte3 ,  0x4706,   0x0000 },
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte0 ,  0x4708,   0x0000 },
+@@ -2614,23 +3480,35 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte2 ,  0x4714,   0x0000 },
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte3 ,  0x4716,   0x0000 },
  {   AutoFocusThHeuristicInput_uwLensPositionInput_LSByte ,  0x471a,   0x0000 },
  {   AutoFocusThHeuristicInput_uwLensPositionInput_MSByte ,  0x4719,   0x0000 },
  {   AutoFocusThHeuristicInput_bBrightnessInput ,  0x471c,   0x0000 },
@@ -2004,7 +2268,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MiscPageElements_fEnableIntelligentFlash ,  0x4904,   0x0000 },
  {   MiscPageElements_fEligibleFrameForMetering ,  0x4906,   0x0000 },
  {   MiscPageElements_fFlashGunIlluminatedFrameStreamed ,  0x4908,   0x0000 },
-@@ -2642,7 +3520,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   MiscPageElements_VpipCut ,  0x490a,   0x0000 },
+ {   MiscPageElements_bGPIOClockFrequency_Mhz ,  0x490c,   0x0000 },
+@@ -2640,42 +3518,60 @@ struct nomadik_vpip_param vpip_default_p
+ {   MiscPageElements_fEnableDelayWhenStoppingSensor ,  0x4914,   0x0000 },
+ {   MiscPageElements_fTriggerFlashOnStreaming ,  0x4916,   0x0000 },
  {   MiscPageElements_fDoNotOutputFrameInIntelligentFlash ,  0x4918,   0x0000 },
  {   MiscPageElements_fDisableToshibaInit ,  0x491a,   0x0000 },
  {   MiscPageElements_bNumberofFramesTobeSkippedByRx ,  0x491c,   0x0000 },
@@ -2018,7 +2286,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MasterI2cClockControl_bCountFall ,  0x4a00,   0x0000 },
  {   MasterI2cClockControl_bCountRise ,  0x4a02,   0x0000 },
  {   MasterI2cClockControl_bCountHigh ,  0x4a04,   0x0000 },
-@@ -2652,6 +3536,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   MasterI2cClockControl_bCountBuffer ,  0x4a06,   0x0000 },
+ {   MasterI2cClockControl_bCountHoldData ,  0x4a08,   0x0000 },
+ {   MasterI2cClockControl_bCountSetupData ,  0x4a0a,   0x0000 },
  {   MasterI2cClockControl_bCountHoldStart ,  0x4a0c,   0x0000 },
  {   MasterI2cClockControl_bCountSetupStart ,  0x4a0e,   0x0000 },
  {   MasterI2cClockControl_bCountSetupStop ,  0x4a10,   0x0000 },
@@ -2028,7 +2298,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrFOVCtrl_bShiftCenter ,  0x4a80,   0x0000 },
  {   ZoomMgrFOVCtrl_uwXOrigin_LSByte ,  0x4a84,   0x0000 },
  {   ZoomMgrFOVCtrl_uwXOrigin_MSByte ,  0x4a83,   0x0000 },
-@@ -2660,11 +3547,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrFOVCtrl_uwYOrigin_LSByte ,  0x4a88,   0x0000 },
+ {   ZoomMgrFOVCtrl_uwYOrigin_MSByte ,  0x4a87,   0x0000 },
  {   ZoomMgrFOVCtrl_fRestrictMaxFOVToChosenFOV ,  0x4a8a,   0x0000 },
  {   ZoomMgrFOVCtrl_fCalculateMinFOVAlways ,  0x4a8c,   0x0000 },
  {   ZoomMgrFOVCtrl_fInhibitMaxFOVAtModeStaticChange ,  0x4a8e,   0x0000 },
@@ -2046,7 +2317,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrStripeCtrl_bStripeControl ,  0x4b80,   0x0000 },
  {   ZoomMgrStripeCtrl_uwStripeStartAddr_LSByte ,  0x4b84,   0x0000 },
  {   ZoomMgrStripeCtrl_uwStripeStartAddr_MSByte ,  0x4b83,   0x0000 },
-@@ -2674,6 +3567,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrStripeCtrl_uwStripeSize_LSByte ,  0x4b88,   0x0000 },
+ {   ZoomMgrStripeCtrl_uwStripeSize_MSByte ,  0x4b87,   0x0000 },
+ {   ZoomMgrStripeCtrl_uwStripeInMinLineSize_LSByte ,  0x4b8c,   0x0000 },
  {   ZoomMgrStripeCtrl_uwStripeInMinLineSize_MSByte ,  0x4b8b,   0x0000 },
  {   ZoomMgrStripeCtrl_uwBmsFrameLength_LSByte ,  0x4b90,   0x0000 },
  {   ZoomMgrStripeCtrl_uwBmsFrameLength_MSByte ,  0x4b8f,   0x0000 },
@@ -2056,7 +2329,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   LftStripeParam_uwGPSISize_LSByte ,  0x4c02,   0x0000 },
  {   LftStripeParam_uwGPSISize_MSByte ,  0x4c01,   0x0000 },
  {   LftStripeParam_uwGPSOSize_LSByte ,  0x4c06,   0x0000 },
-@@ -2694,6 +3590,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   LftStripeParam_uwGPSOSize_MSByte ,  0x4c05,   0x0000 },
+ {   LftStripeParam_uwRightBorder_LSByte ,  0x4c0a,   0x0000 },
+@@ -2692,10 +3588,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   LftStripeParam_uwStripeInCropSize_MSByte ,  0x4c1d,   0x0000 },
+ {   LftStripeParam_uwStripeOutCropStart_LSByte ,  0x4c22,   0x0000 },
  {   LftStripeParam_uwStripeOutCropStart_MSByte ,  0x4c21,   0x0000 },
  {   LftStripeParam_uwStripeOutCropSize_LSByte ,  0x4c26,   0x0000 },
  {   LftStripeParam_uwStripeOutCropSize_MSByte ,  0x4c25,   0x0000 },
@@ -2066,7 +2343,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   RgtStripeParam_uwGPSISize_LSByte ,  0x4c82,   0x0000 },
  {   RgtStripeParam_uwGPSISize_MSByte ,  0x4c81,   0x0000 },
  {   RgtStripeParam_uwGPSOSize_LSByte ,  0x4c86,   0x0000 },
-@@ -2714,6 +3613,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   RgtStripeParam_uwGPSOSize_MSByte ,  0x4c85,   0x0000 },
+ {   RgtStripeParam_uwRightBorder_LSByte ,  0x4c8a,   0x0000 },
+@@ -2712,34 +3611,70 @@ struct nomadik_vpip_param vpip_default_p
+ {   RgtStripeParam_uwStripeInCropSize_MSByte ,  0x4c9d,   0x0000 },
+ {   RgtStripeParam_uwStripeOutCropStart_LSByte ,  0x4ca2,   0x0000 },
  {   RgtStripeParam_uwStripeOutCropStart_MSByte ,  0x4ca1,   0x0000 },
  {   RgtStripeParam_uwStripeOutCropSize_LSByte ,  0x4ca6,   0x0000 },
  {   RgtStripeParam_uwStripeOutCropSize_MSByte ,  0x4ca5,   0x0000 },
@@ -2076,7 +2357,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   DigitalGainStatus_uwCodedGreen1Gain_LSByte ,  0x4d02,   0x0000 },
  {   DigitalGainStatus_uwCodedGreen1Gain_MSByte ,  0x4d01,   0x0000 },
  {   DigitalGainStatus_uwCodedRedGain_LSByte ,  0x4d06,   0x0000 },
-@@ -2722,10 +3624,16 @@ struct nomadik_vpip_param vpip_default_p
+ {   DigitalGainStatus_uwCodedRedGain_MSByte ,  0x4d05,   0x0000 },
+ {   DigitalGainStatus_uwCodedBlueGain_LSByte ,  0x4d0a,   0x0000 },
  {   DigitalGainStatus_uwCodedBlueGain_MSByte ,  0x4d09,   0x0000 },
  {   DigitalGainStatus_uwCodedGreen2Gain_LSByte ,  0x4d0e,   0x0000 },
  {   DigitalGainStatus_uwCodedGreen2Gain_MSByte ,  0x4d0d,   0x0000 },
@@ -2093,7 +2375,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiFlickerExposureStatus_fpFlickerFreePeriod_us_LSByte ,  0x4e02,   0x0000 },
  {   AntiFlickerExposureStatus_fpFlickerFreePeriod_us_MSByte ,  0x4e01,   0x0000 },
  {   AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_LSByte ,  0x4e06,   0x0000 },
-@@ -2734,10 +3642,37 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_MSByte ,  0x4e05,   0x0000 },
+ {   AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_LSByte ,  0x4e0a,   0x0000 },
  {   AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_MSByte ,  0x4e09,   0x0000 },
  {   AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_LSByte ,  0x4e0e,   0x0000 },
  {   AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_MSByte ,  0x4e0d,   0x0000 },
@@ -2131,7 +2414,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_LSByte ,  0x5002,   0x0000 },
  {   SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte ,  0x5001,   0x043f },
  {   SensorSetupFarSensor_uwMinimumSensorRxPixelValue_LSByte ,  0x5006,   0x0000 },
-@@ -2751,6 +3686,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte ,  0x5005,   0x0004 },
+ {   SensorSetupFarSensor_uwMaximumSensorRxPixelValue_LSByte ,  0x500a,   0x0000 },
+@@ -2749,10 +3684,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupFarSensor_fpGreenTiltGain_LSByte ,  0x5012,   0x0000 },
+ {   SensorSetupFarSensor_fpGreenTiltGain_MSByte ,  0x5011,   0x3e00 },
  {   SensorSetupFarSensor_fpBlueTiltGain_LSByte ,  0x5016,   0x0000 },
  {   SensorSetupFarSensor_fpBlueTiltGain_MSByte ,  0x5015,   0x3e00 },
  {   SensorSetupFarSensor_BlackCorrectionOffset ,  0x5018,   0x0000 },
@@ -2141,7 +2428,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_LSByte ,  0x5082,   0x0000 },
  {   SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_MSByte ,  0x5081,   0x0000 },
  {   SensorSetupNearSensor_uwMinimumSensorRxPixelValue_LSByte ,  0x5086,   0x0000 },
-@@ -2764,6 +3702,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupNearSensor_uwMinimumSensorRxPixelValue_MSByte ,  0x5085,   0x0000 },
+ {   SensorSetupNearSensor_uwMaximumSensorRxPixelValue_LSByte ,  0x508a,   0x0000 },
+@@ -2762,10 +3700,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupNearSensor_fpGreenTiltGain_LSByte ,  0x5092,   0x0000 },
+ {   SensorSetupNearSensor_fpGreenTiltGain_MSByte ,  0x5091,   0x0000 },
  {   SensorSetupNearSensor_fpBlueTiltGain_LSByte ,  0x5096,   0x0000 },
  {   SensorSetupNearSensor_fpBlueTiltGain_MSByte ,  0x5095,   0x0000 },
  {   SensorSetupNearSensor_BlackCorrectionOffset ,  0x5098,   0x0000 },
@@ -2151,7 +2442,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ToshibaOtpRead_otp_inf_2 ,  0x5100,   0x0000 },
  {   ToshibaOtpRead_otp_inf_1 ,  0x5102,   0x0000 },
  {   ToshibaOtpRead_otp_inf_0 ,  0x5104,   0x0000 },
-@@ -2775,8 +3716,24 @@ struct nomadik_vpip_param vpip_default_p
+ {   ToshibaOtpRead_otp_mac_2 ,  0x5106,   0x0000 },
+ {   ToshibaOtpRead_otp_mac_1 ,  0x5108,   0x0000 },
+@@ -2773,20 +3714,71 @@ struct nomadik_vpip_param vpip_default_p
+ {   ToshibaOtpRead_otp_posA_1 ,  0x510c,   0x0000 },
+ {   ToshibaOtpRead_otp_posA_0 ,  0x510e,   0x0000 },
  {   ToshibaOtpRead_otp_posB_1 ,  0x5110,   0x0000 },
  {   ToshibaOtpRead_otp_posB_0 ,  0x5112,   0x0000 },
  {   ToshibaOtpRead_otp_register_map_ver ,  0x5114,   0x0000 },
@@ -2176,7 +2471,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ReferenceIlluminantCasts_fpCAST0_LSByte ,  0x5202,   0x0000 },
  {   ReferenceIlluminantCasts_fpCAST0_MSByte ,  0x5201,   0x38b8 },
  {   ReferenceIlluminantCasts_fpCAST1_LSByte ,  0x5206,   0x0000 },
-@@ -2785,6 +3742,41 @@ struct nomadik_vpip_param vpip_default_p
+ {   ReferenceIlluminantCasts_fpCAST1_MSByte ,  0x5205,   0x396d },
+ {   ReferenceIlluminantCasts_fpCAST2_LSByte ,  0x520a,   0x0000 },
  {   ReferenceIlluminantCasts_fpCAST2_MSByte ,  0x5209,   0x3a1b },
  {   ReferenceIlluminantCasts_fpCAST3_LSByte ,  0x520e,   0x0000 },
  {   ReferenceIlluminantCasts_fpCAST3_MSByte ,  0x520d,   0x3af2 },
@@ -2218,7 +2514,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_B_bAvUnityOffset_Day ,  0x5280,   0x0040 },
  {   AdaptiveAVParameter_B_bAvCoeffR2_Day ,  0x5282,   0x003e },
  {   AdaptiveAVParameter_B_bAvCoeffR4_Day ,  0x5284,   0x00e8 },
-@@ -2813,6 +3805,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_B_wAvHOffset_Day_LSByte ,  0x5288,   0x0000 },
+ {   AdaptiveAVParameter_B_wAvHOffset_Day_MSByte ,  0x5287,   0x0003 },
+@@ -2811,10 +3803,42 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_B_bAvCoeffR4_HOR ,  0x52ae,   0x00f0 },
+ {   AdaptiveAVParameter_B_wAvHOffset_HOR_LSByte ,  0x52b2,   0x0000 },
  {   AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte ,  0x52b1,   0x000b },
  {   AdaptiveAVParameter_B_wAvVOffset_HOR_LSByte ,  0x52b6,   0x0000 },
  {   AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte ,  0x52b5,   0x001d },
@@ -2257,7 +2557,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_GB_bAvUnityOffset_Day ,  0x5300,   0x0040 },
  {   AdaptiveAVParameter_GB_bAvCoeffR2_Day ,  0x5302,   0x0047 },
  {   AdaptiveAVParameter_GB_bAvCoeffR4_Day ,  0x5304,   0x00ec },
-@@ -2841,6 +3865,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GB_wAvHOffset_Day_LSByte ,  0x5308,   0x0000 },
+ {   AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte ,  0x5307,   0x000a },
+@@ -2839,10 +3863,43 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GB_bAvCoeffR4_HOR ,  0x532e,   0x00f0 },
+ {   AdaptiveAVParameter_GB_wAvHOffset_HOR_LSByte ,  0x5332,   0x0000 },
  {   AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte ,  0x5331,   0x000c },
  {   AdaptiveAVParameter_GB_wAvVOffset_HOR_LSByte ,  0x5336,   0x0000 },
  {   AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte ,  0x5335,   0x0014 },
@@ -2297,7 +2601,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_GR_bAvUnityOffset_Day ,  0x5380,   0x0040 },
  {   AdaptiveAVParameter_GR_bAvCoeffR2_Day ,  0x5382,   0x0048 },
  {   AdaptiveAVParameter_GR_bAvCoeffR4_Day ,  0x5384,   0x00e8 },
-@@ -2869,6 +3926,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GR_wAvHOffset_Day_LSByte ,  0x5388,   0x0000 },
+ {   AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte ,  0x5387,   0x0009 },
+@@ -2867,10 +3924,42 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GR_bAvCoeffR4_HOR ,  0x53ae,   0x00ef },
+ {   AdaptiveAVParameter_GR_wAvHOffset_HOR_LSByte ,  0x53b2,   0x0000 },
  {   AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte ,  0x53b1,   0x000c },
  {   AdaptiveAVParameter_GR_wAvVOffset_HOR_LSByte ,  0x53b6,   0x0000 },
  {   AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte ,  0x53b5,   0x0001 },
@@ -2336,7 +2644,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_R_bAvUnityOffset_Day ,  0x5400,   0x0040 },
  {   AdaptiveAVParameter_R_bAvCoeffR2_Day ,  0x5402,   0x0067 },
  {   AdaptiveAVParameter_R_bAvCoeffR4_Day ,  0x5404,   0x00f6 },
-@@ -2897,17 +3986,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_R_wAvHOffset_Day_LSByte ,  0x5408,   0x0000 },
+ {   AdaptiveAVParameter_R_wAvHOffset_Day_MSByte ,  0x5407,   0x000a },
+@@ -2895,21 +3984,43 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_R_bAvCoeffR4_HOR ,  0x542e,   0x00f7 },
+ {   AdaptiveAVParameter_R_wAvHOffset_HOR_LSByte ,  0x5432,   0x0000 },
  {   AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte ,  0x5431,   0x000a },
  {   AdaptiveAVParameter_R_wAvVOffset_HOR_LSByte ,  0x5436,   0x0000 },
  {   AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte ,  0x5435,   0x0004 },
@@ -2376,7 +2688,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   DynamicConstrainedWBControls_fpRedA_LSByte ,  0x5582,   0x0000 },
  {   DynamicConstrainedWBControls_fpRedA_MSByte ,  0x5581,   0x3881 },
  {   DynamicConstrainedWBControls_fpBlueA_LSByte ,  0x5586,   0x0000 },
-@@ -2919,6 +4030,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   DynamicConstrainedWBControls_fpBlueA_MSByte ,  0x5585,   0x3c68 },
+ {   DynamicConstrainedWBControls_fpDamperLowThreshold_LSByte ,  0x558a,   0x0000 },
+@@ -2917,10 +4028,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   DynamicConstrainedWBControls_fpMinimumDamperOutput_LSByte ,  0x558e,   0x0000 },
+ {   DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte ,  0x558d,   0x3a66 },
  {   DynamicConstrainedWBControls_fpDamperHighThreshold_LSByte ,  0x5592,   0x0000 },
  {   DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte ,  0x5591,   0x5a71 },
  {   DynamicConstrainedWBControls_fDamperDisable ,  0x5594,   0x0000 },
@@ -2385,7 +2701,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   Toshiba_AF_NVM_Read_NVM_Far2Near_inf_LSByte ,  0x5602,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Far2Near_inf_MSByte ,  0x5601,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Near2Far_inf_LSByte ,  0x5606,   0x0000 },
-@@ -2931,6 +4044,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   Toshiba_AF_NVM_Read_NVM_Near2Far_inf_MSByte ,  0x5605,   0x0000 },
+ {   Toshiba_AF_NVM_Read_NVM_Far2Near_mac_LSByte ,  0x560a,   0x0000 },
+@@ -2929,27 +4042,81 @@ struct nomadik_vpip_param vpip_default_p
+ {   Toshiba_AF_NVM_Read_NVM_Near2Far_mac_MSByte ,  0x560d,   0x0000 },
+ {   Toshiba_AF_NVM_Read_NVM_Pos_A_LSByte ,  0x5612,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Pos_A_MSByte ,  0x5611,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Pos_B_LSByte ,  0x5616,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Pos_B_MSByte ,  0x5615,   0x0000 },
@@ -2409,7 +2729,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   Toshiba_Vcm_Parameters_wLowLevelMacroPos_LSByte ,  0x5682,   0x0000 },
  {   Toshiba_Vcm_Parameters_wLowLevelMacroPos_MSByte ,  0x5681,   0x0000 },
  {   Toshiba_Vcm_Parameters_wLowLevelInfinityPos_LSByte ,  0x5686,   0x0000 },
-@@ -2941,13 +4071,50 @@ struct nomadik_vpip_param vpip_default_p
+ {   Toshiba_Vcm_Parameters_wLowLevelInfinityPos_MSByte ,  0x5685,   0x0000 },
+ {   Toshiba_Vcm_Parameters_bSlewControlModeEnable ,  0x5688,   0x0000 },
+ {   Toshiba_Vcm_Parameters_bSlewModeForSmallerStep ,  0x568a,   0x0001 },
+ {   Toshiba_Vcm_Parameters_bSlewRateForSmallerStep ,  0x568c,   0x0004 },
  {   Toshiba_Vcm_Parameters_bSlewModeForLargerStep ,  0x568e,   0x0008 },
  {   Toshiba_Vcm_Parameters_bSlewRateForLargerStep ,  0x5690,   0x0007 },
  {   Toshiba_Vcm_Parameters_bThresholdStepSize ,  0x5692,   0x00b0 },
@@ -2460,7 +2783,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine1_ColourMatrixFarSensor_fpRInR_LSByte ,  0x5802,   0x0000 },
  {   ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte ,  0x5801,   0x3f0c },
  {   ColourEngine1_ColourMatrixFarSensor_fpGInR_LSByte ,  0x5806,   0x0000 },
-@@ -2966,6 +4133,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte ,  0x5805,   0xb887 },
+ {   ColourEngine1_ColourMatrixFarSensor_fpBInR_LSByte ,  0x580a,   0x0000 },
+@@ -2964,10 +4131,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte ,  0x5819,   0xbc6e },
+ {   ColourEngine1_ColourMatrixFarSensor_fpGInB_LSByte ,  0x581e,   0x0000 },
  {   ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte ,  0x581d,   0xc01b },
  {   ColourEngine1_ColourMatrixFarSensor_fpBInB_LSByte ,  0x5822,   0x0000 },
  {   ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte ,  0x5821,   0x41b7 },
@@ -2469,7 +2796,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine1_ColourMatrixNearSensor_fpRInR_LSByte ,  0x5882,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpRInR_MSByte ,  0x5881,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpGInR_LSByte ,  0x5886,   0x0000 },
-@@ -2984,24 +4153,50 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixNearSensor_fpGInR_MSByte ,  0x5885,   0x0000 },
+ {   ColourEngine1_ColourMatrixNearSensor_fpBInR_LSByte ,  0x588a,   0x0000 },
+@@ -2982,106 +4151,155 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixNearSensor_fpRInB_MSByte ,  0x5899,   0x0000 },
+ {   ColourEngine1_ColourMatrixNearSensor_fpGInB_LSByte ,  0x589e,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpGInB_MSByte ,  0x589d,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpBInB_LSByte ,  0x58a2,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpBInB_MSByte ,  0x58a1,   0x0000 },
@@ -2523,7 +2854,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeSetupBank3_bActiveSensor ,                     0x3b98,0x2},
  
  
-@@ -3011,20 +4206,25 @@ EXPORT_SYMBOL(vpip_default_params);
+       };
+ EXPORT_SYMBOL(vpip_default_params);
  
  struct nomadik_vpip_param vpip_default_params_orig[2700]=
  
@@ -2552,7 +2885,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeManagerStatus_bThisLoLevelState ,  0x0100,   0x0000 },
  {   ModeManagerStatus_bNextLoLevelState ,  0x0102,   0x0000 },
  {   ModeManagerStatus_bHiLevelState ,  0x0104,   0x0000 },
-@@ -3034,52 +4234,70 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeManagerStatus_bCycles ,  0x0106,   0x0000 },
+ {   ModeManagerStatus_fModeStaticSetupsChanged ,  0x0108,   0x0000 },
+ {   ModeManagerStatus_bTestCoin ,  0x010a,   0x0000 },
  {   ModeManagerStatus_fCycleForTest ,  0x010c,   0x0000 },
  {   ModeManagerStatus_bNumberOfFramesStreamed ,  0x010e,   0x0000 },
  {   ModeManagerStatus_bPrevFrameCountForExposure ,  0x0110,   0x0000 },
@@ -2649,7 +2984,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   PipeSetupBankB_uwPipeOutputSize_X_LSByte ,  0x0402,   0x0000 },
  {   PipeSetupBankB_uwPipeOutputSize_X_MSByte ,  0x0401,   0x0000 },
  {   PipeSetupBankB_uwPipeOutputSize_Y_LSByte ,  0x0406,   0x0000 },
-@@ -3092,22 +4310,37 @@ struct nomadik_vpip_param vpip_default_p
+ {   PipeSetupBankB_uwPipeOutputSize_Y_MSByte ,  0x0405,   0x0000 },
+ {   PipeSetupBankB_bPipeOutputFormat ,  0x0408,   0x0000 },
+@@ -3090,26 +4308,41 @@ struct nomadik_vpip_param vpip_default_p
+ {   PipeSetupBankB_fEnableItuEmbeddedCodes ,  0x040e,   0x0000 },
+ {   PipeSetupBankB_bPixValidLineTypes ,  0x0410,   0x0000 },
  {   PipeSetupBankB_fGenerateVSync ,  0x0412,   0x0000 },
  {   PipeSetupBankB_fCb_Cr_Flip ,  0x0414,   0x0000 },
  {   PipeSetupBankB_fY_CbCr_Flip ,  0x0416,   0x0000 },
@@ -2688,7 +3027,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   LocalPipe0SetupBank_uwPipeOutputSize_X_LSByte ,  0x0682,   0x0000 },
  {   LocalPipe0SetupBank_uwPipeOutputSize_X_MSByte ,  0x0681,   0x0000 },
  {   LocalPipe0SetupBank_uwPipeOutputSize_Y_LSByte ,  0x0686,   0x0000 },
-@@ -3120,13 +4353,19 @@ struct nomadik_vpip_param vpip_default_p
+ {   LocalPipe0SetupBank_uwPipeOutputSize_Y_MSByte ,  0x0685,   0x0000 },
+ {   LocalPipe0SetupBank_bPipeOutputFormat ,  0x0688,   0x0000 },
+@@ -3118,83 +4351,119 @@ struct nomadik_vpip_param vpip_default_p
+ {   LocalPipe0SetupBank_fEnableItuEmbeddedCodes ,  0x068e,   0x0000 },
+ {   LocalPipe0SetupBank_bPixValidLineTypes ,  0x0690,   0x0000 },
  {   LocalPipe0SetupBank_fGenerateVSync ,  0x0692,   0x0000 },
  {   LocalPipe0SetupBank_fCb_Cr_Flip ,  0x0694,   0x0000 },
  {   LocalPipe0SetupBank_fY_CbCr_Flip ,  0x0696,   0x0000 },
@@ -2708,7 +3051,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   Pipe0Control_fOverrideOFCropRegisters ,  0x070e,   0x0000 },
  {   Pipe0Control_uwHCropRising_LSByte ,  0x0712,   0x0000 },
  {   Pipe0Control_uwHCropRising_MSByte ,  0x0711,   0x0000 },
-@@ -3136,27 +4375,45 @@ struct nomadik_vpip_param vpip_default_p
+ {   Pipe0Control_uwHCropFalling_LSByte ,  0x0716,   0x0000 },
+ {   Pipe0Control_uwHCropFalling_MSByte ,  0x0715,   0x0000 },
+ {   Pipe0Control_uwVCropRisingCrse_LSByte ,  0x071a,   0x0000 },
  {   Pipe0Control_uwVCropRisingCrse_MSByte ,  0x0719,   0x0000 },
  {   Pipe0Control_uwVCropFallingCrse_LSByte ,  0x071e,   0x0000 },
  {   Pipe0Control_uwVCropFallingCrse_MSByte ,  0x071d,   0x0000 },
@@ -2757,7 +3102,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MasterI2cStatus_bResourceStatus ,  0x0a00,   0x0000 },
  {   MasterI2cStatus_uwI2CClkDiv_LSByte ,  0x0a04,   0x0000 },
  {   MasterI2cStatus_uwI2CClkDiv_MSByte ,  0x0a03,   0x0000 },
-@@ -3164,24 +4421,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   MasterI2cStatus_fTransactionError ,  0x0a06,   0x0000 },
  {   MasterI2cStatus_bNumberOfTransactionFailures ,  0x0a08,   0x0000 },
  {   MasterI2cStatus_bNumberOfConsecutiveGrabFailures ,  0x0a0a,   0x0000 },
  {   MasterI2cStatus_bNumberOfForcedReleases ,  0x0a0c,   0x0000 },
@@ -2797,7 +3142,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_LSByte ,  0x0c02,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumPrePllClockDiv_MSByte ,  0x0c01,   0x0000 },
  {   VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_LSByte ,  0x0c06,   0x0000 },
-@@ -3192,7 +4461,7 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingSensorConstraints_uwMaximumPrePllClockDiv_MSByte ,  0x0c05,   0x0000 },
+ {   VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte ,  0x0c0a,   0x0000 },
+ {   VideoTimingSensorConstraints_fpMinimumPllInputFrequency_Mhz_MSByte ,  0x0c09,   0x0000 },
+ {   VideoTimingSensorConstraints_uwMinimumPllMultiplier_LSByte ,  0x0c0e,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumPllMultiplier_MSByte ,  0x0c0d,   0x0000 },
  {   VideoTimingSensorConstraints_uwMaximumPllMultiplier_LSByte ,  0x0c12,   0x0000 },
  {   VideoTimingSensorConstraints_uwMaximumPllMultiplier_MSByte ,  0x0c11,   0x0000 },
@@ -2806,7 +3154,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingSensorConstraints_fpMaximumPllOutputFrequency_Mhz_MSByte ,  0x0c15,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_LSByte ,  0x0c1a,   0x0000 },
  {   VideoTimingSensorConstraints_uwMinimumVTSysClockDiv_MSByte ,  0x0c19,   0x0000 },
-@@ -3214,6 +4483,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_LSByte ,  0x0c1e,   0x0000 },
+ {   VideoTimingSensorConstraints_uwMaximumVTSysClockDiv_MSByte ,  0x0c1d,   0x0000 },
+@@ -3212,17 +4481,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingSensorConstraints_uwMaximumOPSysClockDiv_MSByte ,  0x0c35,   0x0000 },
+ {   VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte ,  0x0c3a,   0x0000 },
  {   VideoTimingSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte ,  0x0c39,   0x0000 },
  {   VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte ,  0x0c3e,   0x0000 },
  {   VideoTimingSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte ,  0x0c3d,   0x0000 },
@@ -2816,7 +3168,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorScalingSubSamplingCapabilities_bSensorScalingMode ,  0x0c80,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwScalerMMin_LSByte ,  0x0c84,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwScalerMMin_MSByte ,  0x0c83,   0x0000 },
-@@ -3221,6 +4493,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorScalingSubSamplingCapabilities_uwScalerMMax_LSByte ,  0x0c88,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwScalerMMax_MSByte ,  0x0c87,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwMaxOddInc_LSByte ,  0x0c8c,   0x0000 },
  {   SensorScalingSubSamplingCapabilities_uwMaxOddInc_MSByte ,  0x0c8b,   0x0000 },
@@ -2826,7 +3178,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingOutput_uwPrePllClockDiv_LSByte ,  0x0d02,   0x0000 },
  {   VideoTimingOutput_uwPrePllClockDiv_MSByte ,  0x0d01,   0x0000 },
  {   VideoTimingOutput_fpPllInputFrequency_Mhz_LSByte ,  0x0d06,   0x0000 },
-@@ -3249,7 +4524,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingOutput_fpPllInputFrequency_Mhz_MSByte ,  0x0d05,   0x0000 },
+ {   VideoTimingOutput_uwPllMultiplier_LSByte ,  0x0d0a,   0x0000 },
+@@ -3247,24 +4522,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingOutput_uwOPPixelClockDiv_MSByte ,  0x0d2d,   0x0000 },
+ {   VideoTimingOutput_fpOPPixelClockFrequency_Mhz_LSByte ,  0x0d32,   0x0000 },
  {   VideoTimingOutput_fpOPPixelClockFrequency_Mhz_MSByte ,  0x0d31,   0x0000 },
  {   VideoTimingOutput_fpOutputTimingClockDerating_LSByte ,  0x0d36,   0x0000 },
  {   VideoTimingOutput_fpOutputTimingClockDerating_MSByte ,  0x0d35,   0x0000 },
@@ -2840,7 +3196,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingInputsFarSensor_VideoTimingMode ,  0x0e00,   0x0001 },
  {   VideoTimingInputsFarSensor_bSensorBitsPerSystemClock ,  0x0e02,   0x0002 },
  {   VideoTimingInputsFarSensor_uwCsiRawFormat_LSByte ,  0x0e06,   0x0000 },
-@@ -3258,11 +4539,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingInputsFarSensor_uwCsiRawFormat_MSByte ,  0x0e05,   0x0808 },
+ {   VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_LSByte ,  0x0e0a,   0x0000 },
  {   VideoTimingInputsFarSensor_fpHostRxMaxDataRate_Mbps_MSByte ,  0x0e09,   0x508a },
  {   VideoTimingInputsFarSensor_VsyncPolarity ,  0x0e0c,   0x0000 },
  {   VideoTimingInputsFarSensor_HsyncPolarity ,  0x0e0e,   0x0000 },
@@ -2858,7 +3215,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_LSByte ,  0x0f02,   0x0000 },
  {   VideoTimingFarSensorConstraints_uwMinimumPrePllClockDiv_MSByte ,  0x0f01,   0x0000 },
  {   VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_LSByte ,  0x0f06,   0x0000 },
-@@ -3295,6 +4582,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarSensorConstraints_uwMaximumPrePllClockDiv_MSByte ,  0x0f05,   0x0000 },
+ {   VideoTimingFarSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte ,  0x0f0a,   0x0000 },
+@@ -3293,17 +4580,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarSensorConstraints_uwMaximumOPSysClockDiv_MSByte ,  0x0f35,   0x0000 },
+ {   VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte ,  0x0f3a,   0x0000 },
  {   VideoTimingFarSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte ,  0x0f39,   0x0000 },
  {   VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte ,  0x0f3e,   0x0000 },
  {   VideoTimingFarSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte ,  0x0f3d,   0x0000 },
@@ -2868,7 +3229,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFarScalingSubSamplingCapabilities_bSensorScalingMode ,  0x0f80,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwScalerMMin_LSByte ,  0x0f84,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwScalerMMin_MSByte ,  0x0f83,   0x0000 },
-@@ -3302,6 +4592,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFarScalingSubSamplingCapabilities_uwScalerMMax_LSByte ,  0x0f88,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwScalerMMax_MSByte ,  0x0f87,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_LSByte ,  0x0f8c,   0x0000 },
  {   SensorFarScalingSubSamplingCapabilities_uwMaxOddInc_MSByte ,  0x0f8b,   0x0000 },
@@ -2878,7 +3239,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingFarOutput_uwPrePllClockDiv_LSByte ,  0x1002,   0x0000 },
  {   VideoTimingFarOutput_uwPrePllClockDiv_MSByte ,  0x1001,   0x0000 },
  {   VideoTimingFarOutput_fpPllInputFrequency_Mhz_LSByte ,  0x1006,   0x0000 },
-@@ -3330,7 +4623,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarOutput_fpPllInputFrequency_Mhz_MSByte ,  0x1005,   0x0000 },
+ {   VideoTimingFarOutput_uwPllMultiplier_LSByte ,  0x100a,   0x0000 },
+@@ -3328,24 +4621,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingFarOutput_uwOPPixelClockDiv_MSByte ,  0x102d,   0x0000 },
+ {   VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_LSByte ,  0x1032,   0x0000 },
  {   VideoTimingFarOutput_fpOPPixelClockFrequency_Mhz_MSByte ,  0x1031,   0x0000 },
  {   VideoTimingFarOutput_fpOutputTimingClockDerating_LSByte ,  0x1036,   0x0000 },
  {   VideoTimingFarOutput_fpOutputTimingClockDerating_MSByte ,  0x1035,   0x0000 },
@@ -2892,7 +3257,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingInputsNearSensor_VideoTimingMode ,  0x1100,   0x0001 },
  {   VideoTimingInputsNearSensor_bSensorBitsPerSystemClock ,  0x1102,   0x0002 },
  {   VideoTimingInputsNearSensor_uwCsiRawFormat_LSByte ,  0x1106,   0x0000 },
-@@ -3339,11 +4638,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingInputsNearSensor_uwCsiRawFormat_MSByte ,  0x1105,   0x0808 },
+ {   VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_LSByte ,  0x110a,   0x0000 },
  {   VideoTimingInputsNearSensor_fpHostRxMaxDataRate_Mbps_MSByte ,  0x1109,   0x508a },
  {   VideoTimingInputsNearSensor_VsyncPolarity ,  0x110c,   0x0000 },
  {   VideoTimingInputsNearSensor_HsyncPolarity ,  0x110e,   0x0000 },
@@ -2910,7 +3276,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_LSByte ,  0x1202,   0x0000 },
  {   VideoTimingNearSensorConstraints_uwMinimumPrePllClockDiv_MSByte ,  0x1201,   0x0000 },
  {   VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_LSByte ,  0x1206,   0x0000 },
-@@ -3376,6 +4681,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearSensorConstraints_uwMaximumPrePllClockDiv_MSByte ,  0x1205,   0x0000 },
+ {   VideoTimingNearSensorConstraints_fpMinimumPllInputFrequency_Mhz_LSByte ,  0x120a,   0x0000 },
+@@ -3374,17 +4679,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearSensorConstraints_uwMaximumOPSysClockDiv_MSByte ,  0x1235,   0x0000 },
+ {   VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_LSByte ,  0x123a,   0x0000 },
  {   VideoTimingNearSensorConstraints_fpMaximumOPSystemClockFrequency_Mhz_MSByte ,  0x1239,   0x0000 },
  {   VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_LSByte ,  0x123e,   0x0000 },
  {   VideoTimingNearSensorConstraints_fpMaximumOPPixelClockFrequency_Mhz_MSByte ,  0x123d,   0x0000 },
@@ -2920,7 +3290,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorNearScalingSubSamplingCapabilities_bSensorScalingMode ,  0x1280,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwScalerMMin_LSByte ,  0x1284,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwScalerMMin_MSByte ,  0x1283,   0x0000 },
-@@ -3383,6 +4691,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorNearScalingSubSamplingCapabilities_uwScalerMMax_LSByte ,  0x1288,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwScalerMMax_MSByte ,  0x1287,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_LSByte ,  0x128c,   0x0000 },
  {   SensorNearScalingSubSamplingCapabilities_uwMaxOddInc_MSByte ,  0x128b,   0x0000 },
@@ -2930,7 +3300,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VideoTimingNearOutput_uwPrePllClockDiv_LSByte ,  0x1302,   0x0000 },
  {   VideoTimingNearOutput_uwPrePllClockDiv_MSByte ,  0x1301,   0x0000 },
  {   VideoTimingNearOutput_fpPllInputFrequency_Mhz_LSByte ,  0x1306,   0x0000 },
-@@ -3411,35 +4722,47 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearOutput_fpPllInputFrequency_Mhz_MSByte ,  0x1305,   0x0000 },
+ {   VideoTimingNearOutput_uwPllMultiplier_LSByte ,  0x130a,   0x0000 },
+@@ -3409,39 +4720,51 @@ struct nomadik_vpip_param vpip_default_p
+ {   VideoTimingNearOutput_uwOPPixelClockDiv_MSByte ,  0x132d,   0x0000 },
+ {   VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_LSByte ,  0x1332,   0x0000 },
  {   VideoTimingNearOutput_fpOPPixelClockFrequency_Mhz_MSByte ,  0x1331,   0x0000 },
  {   VideoTimingNearOutput_fpOutputTimingClockDerating_LSByte ,  0x1336,   0x0000 },
  {   VideoTimingNearOutput_fpOutputTimingClockDerating_MSByte ,  0x1335,   0x0000 },
@@ -2987,7 +3361,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_LSByte ,  0x1502,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorIntegrationTimeCapability_MSByte ,  0x1501,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_LSByte ,  0x1506,   0x0000 },
-@@ -3451,8 +4774,10 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorMinimumCoarseIntegrationLines_MSByte ,  0x1505,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte ,  0x150a,   0x0000 },
+@@ -3449,12 +4772,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_LSByte ,  0x150e,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorMinimumFineIntegrationPixels_MSByte ,  0x150d,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte ,  0x1512,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte ,  0x1511,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainMinimum_LSByte ,  0x1516,   0x0000 },
@@ -2998,7 +3376,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte ,  0x1519,   0x0080 },
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_LSByte ,  0x151e,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorAnalogGainCodeStep_MSByte ,  0x151d,   0x0000 },
-@@ -3486,7 +4811,11 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorAnalogGainType_LSByte ,  0x1522,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorAnalogGainType_MSByte ,  0x1521,   0x0000 },
+@@ -3484,11 +4809,15 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_LSByte ,  0x1554,   0x0000 },
+ {   SensorCapabilitiesFarSensor_uwSensorDigitalGainCapability_MSByte ,  0x1553,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_LSByte ,  0x1558,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorDigitalGainMinimum_MSByte ,  0x1557,   0x0000 },
  {   SensorCapabilitiesFarSensor_uwSensorDataPedestal_LSByte ,  0x155c,   0x0000 },
@@ -3010,7 +3392,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_LSByte ,  0x1582,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorIntegrationTimeCapability_MSByte ,  0x1581,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_LSByte ,  0x1586,   0x0000 },
-@@ -3499,8 +4828,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorMinimumCoarseIntegrationLines_MSByte ,  0x1585,   0x0000 },
+ {   SensorCapabilitiesNearSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte ,  0x158a,   0x0000 },
+@@ -3497,12 +4826,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorMinimumFineIntegrationPixels_MSByte ,  0x158d,   0x0000 },
+ {   SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte ,  0x1592,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte ,  0x1591,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_LSByte ,  0x1596,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainMinimum_MSByte ,  0x1595,   0x0000 },
@@ -3021,7 +3407,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_LSByte ,  0x159e,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainCodeStep_MSByte ,  0x159d,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorAnalogGainType_LSByte ,  0x15a2,   0x0000 },
-@@ -3534,6 +4863,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorAnalogGainType_MSByte ,  0x15a1,   0x0000 },
+ {   SensorCapabilitiesNearSensor_fpSensorAnalogGainConstM0_LSByte ,  0x15a6,   0x0000 },
+@@ -3532,10 +4861,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesNearSensor_uwSensorDigitalGainCapability_MSByte ,  0x15d3,   0x0000 },
+ {   SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_LSByte ,  0x15d8,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorDigitalGainMinimum_MSByte ,  0x15d7,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorDataPedestal_LSByte ,  0x15dc,   0x0000 },
  {   SensorCapabilitiesNearSensor_uwSensorDataPedestal_MSByte ,  0x15db,   0x0000 },
@@ -3031,7 +3421,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_LSByte ,  0x1602,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorIntegrationTimeCapability_MSByte ,  0x1601,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_LSByte ,  0x1606,   0x0000 },
-@@ -3545,8 +4877,10 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorMinimumCoarseIntegrationLines_MSByte ,  0x1605,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorCoarseIntegrationTimeMaxMargin_LSByte ,  0x160a,   0x0000 },
+@@ -3543,12 +4875,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_LSByte ,  0x160e,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorMinimumFineIntegrationPixels_MSByte ,  0x160d,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_LSByte ,  0x1612,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorFineIntegrationTimeMaxMargin_MSByte ,  0x1611,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_LSByte ,  0x1616,   0x0000 },
@@ -3042,7 +3436,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte ,  0x1619,   0x0080 },
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_LSByte ,  0x161e,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainCodeStep_MSByte ,  0x161d,   0x0000 },
-@@ -3581,6 +4915,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_LSByte ,  0x1622,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorAnalogGainType_MSByte ,  0x1621,   0x0000 },
+@@ -3579,10 +4913,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorCapabilitiesCurrentSensor_uwSensorDigitalGainCapability_MSByte ,  0x1653,   0x0000 },
+ {   SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_LSByte ,  0x1658,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorDigitalGainMinimum_MSByte ,  0x1657,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_LSByte ,  0x165c,   0x0000 },
  {   SensorCapabilitiesCurrentSensor_uwSensorDataPedestal_MSByte ,  0x165b,   0x0000 },
@@ -3052,7 +3450,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFrameConstraintsFar_uwVTXAddrMin_LSByte ,  0x1682,   0x0000 },
  {   SensorFrameConstraintsFar_uwVTXAddrMin_MSByte ,  0x1681,   0x0000 },
  {   SensorFrameConstraintsFar_uwVTYAddrMin_LSByte ,  0x1686,   0x0000 },
-@@ -3609,6 +4946,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsFar_uwVTYAddrMin_MSByte ,  0x1685,   0x0000 },
+ {   SensorFrameConstraintsFar_uwVTXAddrMax_LSByte ,  0x168a,   0x0000 },
+@@ -3607,10 +4944,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsFar_uwMaxVTLineLengthPck_MSByte ,  0x16ad,   0x0000 },
+ {   SensorFrameConstraintsFar_uwMinVTLineBlankingPck_LSByte ,  0x16b2,   0x0000 },
  {   SensorFrameConstraintsFar_uwMinVTLineBlankingPck_MSByte ,  0x16b1,   0x0000 },
  {   SensorFrameConstraintsFar_uwMinVTFrameBlanking_LSByte ,  0x16b6,   0x0000 },
  {   SensorFrameConstraintsFar_uwMinVTFrameBlanking_MSByte ,  0x16b5,   0x0000 },
@@ -3062,7 +3464,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFrameConstraintsNear_uwVTXAddrMin_LSByte ,  0x1702,   0x0000 },
  {   SensorFrameConstraintsNear_uwVTXAddrMin_MSByte ,  0x1701,   0x0000 },
  {   SensorFrameConstraintsNear_uwVTYAddrMin_LSByte ,  0x1706,   0x0000 },
-@@ -3637,8 +4977,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsNear_uwVTYAddrMin_MSByte ,  0x1705,   0x0000 },
+ {   SensorFrameConstraintsNear_uwVTXAddrMax_LSByte ,  0x170a,   0x0000 },
+@@ -3635,12 +4975,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraintsNear_uwMaxVTLineLengthPck_MSByte ,  0x172d,   0x0000 },
+ {   SensorFrameConstraintsNear_uwMinVTLineBlankingPck_LSByte ,  0x1732,   0x0000 },
  {   SensorFrameConstraintsNear_uwMinVTLineBlankingPck_MSByte ,  0x1731,   0x0000 },
  {   SensorFrameConstraintsNear_uwMinVTFrameBlanking_LSByte ,  0x1736,   0x0000 },
  {   SensorFrameConstraintsNear_uwMinVTFrameBlanking_MSByte ,  0x1735,   0x0000 },
@@ -3079,7 +3485,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   CurrentFrameDimension_uwVTFrameLengthLines_LSByte ,  0x1802,   0x0000 },
  {   CurrentFrameDimension_uwVTFrameLengthLines_MSByte ,  0x1801,   0x0000 },
  {   CurrentFrameDimension_uwVTLineLengthPck_LSByte ,  0x1806,   0x0000 },
-@@ -3670,6 +5016,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   CurrentFrameDimension_uwVTLineLengthPck_MSByte ,  0x1805,   0x0000 },
+ {   CurrentFrameDimension_uwVTXAddrStart_LSByte ,  0x180a,   0x0000 },
+@@ -3668,10 +5014,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   CurrentFrameDimension_bScalingMode ,  0x1834,   0x0000 },
+ {   CurrentFrameDimension_fpScaleFactor_LSByte ,  0x1838,   0x0000 },
  {   CurrentFrameDimension_fpScaleFactor_MSByte ,  0x1837,   0x0000 },
  {   CurrentFrameDimension_uwScalerM_LSByte ,  0x183c,   0x0000 },
  {   CurrentFrameDimension_uwScalerM_MSByte ,  0x183b,   0x0000 },
@@ -3089,7 +3499,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorFrameConstraints_uwVTXAddrMin_LSByte ,  0x1882,   0x0000 },
  {   SensorFrameConstraints_uwVTXAddrMin_MSByte ,  0x1881,   0x0000 },
  {   SensorFrameConstraints_uwVTYAddrMin_LSByte ,  0x1886,   0x0000 },
-@@ -3698,12 +5047,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraints_uwVTYAddrMin_MSByte ,  0x1885,   0x0000 },
+ {   SensorFrameConstraints_uwVTXAddrMax_LSByte ,  0x188a,   0x0000 },
+@@ -3696,16 +5045,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorFrameConstraints_uwMaxVTLineLengthPck_MSByte ,  0x18ad,   0x0000 },
+ {   SensorFrameConstraints_uwMinVTLineBlankingPck_LSByte ,  0x18b2,   0x0000 },
  {   SensorFrameConstraints_uwMinVTLineBlankingPck_MSByte ,  0x18b1,   0x0000 },
  {   SensorFrameConstraints_uwMinVTFrameBlanking_LSByte ,  0x18b6,   0x0000 },
  {   SensorFrameConstraints_uwMinVTFrameBlanking_MSByte ,  0x18b5,   0x0000 },
@@ -3108,7 +3522,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FrameDimensionStatus_fFrameLengthChangePending ,  0x1980,   0x0000 },
  {   FrameDimensionStatus_fFrameDimensionChangePending ,  0x1982,   0x0000 },
  {   FrameDimensionStatus_uwVTFrameLengthPending_lines_LSByte ,  0x1986,   0x0000 },
-@@ -3726,49 +5081,93 @@ struct nomadik_vpip_param vpip_default_p
+ {   FrameDimensionStatus_uwVTFrameLengthPending_lines_MSByte ,  0x1985,   0x0000 },
+ {   FrameDimensionStatus_fFrameLengthChangeInhibitedForCoarseExposure ,  0x1988,   0x0000 },
+@@ -3724,53 +5079,97 @@ struct nomadik_vpip_param vpip_default_p
+ {   FrameDimensionStatus_uwMaximumSensorFOVY_LSByte ,  0x19a4,   0x0000 },
+ {   FrameDimensionStatus_uwMaximumSensorFOVY_MSByte ,  0x19a3,   0x0000 },
  {   FrameDimensionStatus_uwOPXOutputSize_LSByte ,  0x19a8,   0x0000 },
  {   FrameDimensionStatus_uwOPXOutputSize_MSByte ,  0x19a7,   0x0000 },
  {   FrameDimensionStatus_fSensorPreScaleFactorChanged ,  0x19aa,   0x0000 },
@@ -3217,7 +3635,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FlashManagerStatus_fFlashSequencePending ,  0x1d00,   0x0000 },
  {   FlashManagerStatus_cNumberFramesRequiredForPreFlashes ,  0x1d02,   0x0000 },
  {   FlashManagerStatus_fpMainFlashPulseWidth_us_LSByte ,  0x1d06,   0x0000 },
-@@ -3792,24 +5191,29 @@ struct nomadik_vpip_param vpip_default_p
+ {   FlashManagerStatus_fpMainFlashPulseWidth_us_MSByte ,  0x1d05,   0x0000 },
+ {   FlashManagerStatus_fpPreFlashPulseWidth_us_LSByte ,  0x1d0a,   0x0000 },
+@@ -3790,46 +5189,61 @@ struct nomadik_vpip_param vpip_default_p
+ {   FlashManagerStatus_wStartPreFlashPixel_LSByte ,  0x1d26,   0x0000 },
+ {   FlashManagerStatus_wStartPreFlashPixel_MSByte ,  0x1d25,   0x0000 },
  {   FlashManagerStatus_cNumberFramesRequired ,  0x1d28,   0x0000 },
  {   FlashManagerStatus_fPreFlashPending ,  0x1d2a,   0x0000 },
  {   FlashManagerStatus_fMainFlashPending ,  0x1d2c,   0x0000 },
@@ -3251,7 +3673,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureControls_uwFlashGunModeCoarseIntegration_lines_LSByte ,  0x1da6,   0x0000 },
  {   ExposureControls_uwFlashGunModeCoarseIntegration_lines_MSByte ,  0x1da5,   0x0000 },
  {   ExposureControls_uwFlashGunModeFineIntegration_pixels_LSByte ,  0x1daa,   0x0000 },
-@@ -3820,14 +5224,24 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureControls_uwFlashGunModeFineIntegration_pixels_MSByte ,  0x1da9,   0x0000 },
+ {   ExposureControls_uwFlashGunModeCodedAnalogGain_LSByte ,  0x1dae,   0x0000 },
+ {   ExposureControls_uwFlashGunModeCodedAnalogGain_MSByte ,  0x1dad,   0x0000 },
+ {   ExposureControls_fpFlashGunModeDigitalGain_LSByte ,  0x1db2,   0x0000 },
  {   ExposureControls_fpFlashGunModeDigitalGain_MSByte ,  0x1db1,   0x0000 },
  {   ExposureControls_fFreezeAutoExposure ,  0x1db4,   0x0000 },
  {   ExposureControls_fpUserMaximumIntegrationTime_us_LSByte ,  0x1db8,   0x0000 },
@@ -3278,7 +3703,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureStatus_fWhiteBalanceGainIncludedInCurrentExposure ,  0x1e04,   0x0000 },
  {   ExposureStatus_fBadExposureForIterativeWhiteBalance ,  0x1e06,   0x0000 },
  {   ExposureStatus_uwCoarseIntegrationPending_lines_LSByte ,  0x1e0a,   0x0000 },
-@@ -3851,6 +5265,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureStatus_uwCoarseIntegrationPending_lines_MSByte ,  0x1e09,   0x0000 },
+ {   ExposureStatus_uwFineIntegrationPending_pixels_LSByte ,  0x1e0e,   0x0000 },
+@@ -3849,31 +5263,46 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureStatus_fpTotalIntegrationTimePending_us_MSByte ,  0x1e27,   0x0000 },
+ {   ExposureStatus_uwCodedAnalogGainPending_LSByte ,  0x1e2c,   0x0000 },
  {   ExposureStatus_uwCodedAnalogGainPending_MSByte ,  0x1e2b,   0x0000 },
  {   ExposureStatus_fExposureIsStableforAutoFocus ,  0x1e2e,   0x0000 },
  {   ExposureStatus_bRuntimeExposureTarget ,  0x1e30,   0x0000 },
@@ -3288,7 +3717,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureParametersApplied_uwCoarseIntegration_lines_LSByte ,  0x1e82,   0x0000 },
  {   ExposureParametersApplied_uwCoarseIntegration_lines_MSByte ,  0x1e81,   0x0000 },
  {   ExposureParametersApplied_uwFineIntegration_pixels_LSByte ,  0x1e86,   0x0000 },
-@@ -3859,8 +5276,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureParametersApplied_uwFineIntegration_pixels_MSByte ,  0x1e85,   0x0000 },
+ {   ExposureParametersApplied_uwCodedAnalogGain_LSByte ,  0x1e8a,   0x0000 },
  {   ExposureParametersApplied_uwCodedAnalogGain_MSByte ,  0x1e89,   0x0000 },
  {   ExposureParametersApplied_fpDigitalGain_LSByte ,  0x1e8e,   0x0000 },
  {   ExposureParametersApplied_fpDigitalGain_MSByte ,  0x1e8d,   0x0000 },
@@ -3303,7 +3733,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureCycleTest_fpInitialDesiredExposureTime_LSByte ,  0x1f82,   0x0000 },
  {   ExposureCycleTest_fpInitialDesiredExposureTime_MSByte ,  0x1f81,   0x0000 },
  {   ExposureCycleTest_fpFinalDesiredExposureTime_LSByte ,  0x1f86,   0x0000 },
-@@ -3868,10 +5291,16 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureCycleTest_fpFinalDesiredExposureTime_MSByte ,  0x1f85,   0x0000 },
  {   ExposureCycleTest_fpExposureStep_LSByte ,  0x1f8a,   0x0000 },
  {   ExposureCycleTest_fpExposureStep_MSByte ,  0x1f89,   0x0000 },
  {   ExposureCycleTest_bStepDirection ,  0x1f8c,   0x0000 },
@@ -3320,7 +3750,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureAlgorithmControls_fpMaximumStep_LSByte ,  0x2082,   0x0000 },
  {   ExposureAlgorithmControls_fpMaximumStep_MSByte ,  0x2081,   0x0000 },
  {   ExposureAlgorithmControls_fpMinimumStep_LSByte ,  0x2086,   0x0000 },
-@@ -3885,9 +5314,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpMinimumStep_MSByte ,  0x2085,   0x0000 },
+ {   ExposureAlgorithmControls_fpMinimumDesiredExposureTime_us_LSByte ,  0x208a,   0x0000 },
+@@ -3883,13 +5312,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_LSByte ,  0x2092,   0x0000 },
+ {   ExposureAlgorithmControls_fpMaximumNegativeStepThreshold_MSByte ,  0x2091,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_LSByte ,  0x2096,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeOnTargetStabilityThreshold_MSByte ,  0x2095,   0x0000 },
  {   ExposureAlgorithmControls_fpDigitalGainFloor_LSByte ,  0x209a,   0x0000 },
@@ -3335,7 +3769,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_LSByte ,  0x20a2,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeIntTimeHysThreshold_MSByte ,  0x20a1,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_LSByte ,  0x20a6,   0x0000 },
-@@ -3903,34 +5337,61 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpRelativeDigitalGainHysThreshold_MSByte ,  0x20a5,   0x0000 },
+ {   ExposureAlgorithmControls_fpRelativeCompilationProblemThreshold_LSByte ,  0x20aa,   0x0000 },
+@@ -3901,53 +5335,103 @@ struct nomadik_vpip_param vpip_default_p
+ {   ExposureAlgorithmControls_fpMaximumManualExposureTime_s_LSByte ,  0x20b6,   0x0000 },
+ {   ExposureAlgorithmControls_fpMaximumManualExposureTime_s_MSByte ,  0x20b5,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_LSByte ,  0x20ba,   0x0000 },
  {   ExposureAlgorithmControls_fpRelativeStabilityThresholdForAutoFocus_MSByte ,  0x20b9,   0x0000 },
  {   ExposureAlgorithmControls_bLeakShift ,  0x20bc,   0x0000 },
@@ -3402,7 +3840,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceStatus_bStatus ,  0x2380,   0x0000 },
  {   WhiteBalanceStatus_fUnityGainsUsed ,  0x2382,   0x0000 },
  {   WhiteBalanceStatus_fpRedGain_LSByte ,  0x2386,   0x0000 },
-@@ -3939,13 +5400,36 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceStatus_fpRedGain_MSByte ,  0x2385,   0x0000 },
+ {   WhiteBalanceStatus_fpGreenGain_LSByte ,  0x238a,   0x0000 },
  {   WhiteBalanceStatus_fpGreenGain_MSByte ,  0x2389,   0x0000 },
  {   WhiteBalanceStatus_fpBlueGain_LSByte ,  0x238e,   0x0000 },
  {   WhiteBalanceStatus_fpBlueGain_MSByte ,  0x238d,   0x0000 },
@@ -3439,7 +3878,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MinWeightedWBControls_fDisable ,  0x2500,   0x0000 },
  {   MinWeightedWBControls_uwSaturationThreshold_LSByte ,  0x2504,   0x0000 },
  {   MinWeightedWBControls_uwSaturationThreshold_MSByte ,  0x2503,   0x0300 },
-@@ -3958,6 +5442,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   MinWeightedWBControls_fpRedTiltGain_LSByte ,  0x2508,   0x0000 },
+ {   MinWeightedWBControls_fpRedTiltGain_MSByte ,  0x2507,   0x3e00 },
+@@ -3956,38 +5440,56 @@ struct nomadik_vpip_param vpip_default_p
+ {   MinWeightedWBControls_fpGreen2TiltGain_LSByte ,  0x2510,   0x0000 },
+ {   MinWeightedWBControls_fpGreen2TiltGain_MSByte ,  0x250f,   0x3e40 },
  {   MinWeightedWBControls_fpBlueTiltGain_LSByte ,  0x2514,   0x0000 },
  {   MinWeightedWBControls_fpBlueTiltGain_MSByte ,  0x2513,   0x3e40 },
  {   MinWeightedWBControls_GreenChannelToAccumulate ,  0x2516,   0x0000 },
@@ -3449,7 +3892,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MinWeightedWBStatus_uwZone_X_Offset_LSByte ,  0x2582,   0x0000 },
  {   MinWeightedWBStatus_uwZone_X_Offset_MSByte ,  0x2581,   0x0000 },
  {   MinWeightedWBStatus_uwZone_Y_Offset_LSByte ,  0x2586,   0x0000 },
-@@ -3968,24 +5455,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   MinWeightedWBStatus_uwZone_Y_Offset_MSByte ,  0x2585,   0x0000 },
+ {   MinWeightedWBStatus_uwZone_X_Size_LSByte ,  0x258a,   0x0000 },
+ {   MinWeightedWBStatus_uwZone_X_Size_MSByte ,  0x2589,   0x0000 },
+ {   MinWeightedWBStatus_uwZone_Y_Size_LSByte ,  0x258e,   0x0000 },
  {   MinWeightedWBStatus_uwZone_Y_Size_MSByte ,  0x258d,   0x0000 },
  {   MinWeightedWBStatus_fpNumberMacroPixel_LSByte ,  0x2592,   0x0000 },
  {   MinWeightedWBStatus_fpNumberMacroPixel_MSByte ,  0x2591,   0x0000 },
@@ -3499,7 +3945,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutomaticFrameRateStatus_fpImpliedGain_LSByte ,  0x2782,   0x0000 },
  {   AutomaticFrameRateStatus_fpImpliedGain_MSByte ,  0x2781,   0x0000 },
  {   AutomaticFrameRateStatus_uwMaximumFrameLength_lines_LSByte ,  0x2786,   0x0000 },
-@@ -4002,9 +5504,20 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutomaticFrameRateStatus_uwMaximumFrameLength_lines_MSByte ,  0x2785,   0x0000 },
+ {   AutomaticFrameRateStatus_uwMinimumFrameLength_lines_LSByte ,  0x278a,   0x0000 },
+@@ -4000,32 +5502,99 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutomaticFrameRateStatus_uwCurrentFrameLength_lines_MSByte ,  0x2795,   0x0000 },
+ {   AutomaticFrameRateStatus_uwDesiredFrameLength_lines_LSByte ,  0x279a,   0x0000 },
  {   AutomaticFrameRateStatus_uwDesiredFrameLength_lines_MSByte ,  0x2799,   0x0000 },
  {   AutomaticFrameRateStatus_fAutomaticFrameRateStable ,  0x279c,   0x0000 },
  {   AutomaticFrameRateStatus_fAutomaticFrameRateClip ,  0x279e,   0x0000 },
@@ -3520,7 +3970,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   StaticFrameRateStatus_uwRequestedFrameRate_Hz_LSByte ,  0x2882,   0x0000 },
  {   StaticFrameRateStatus_uwRequestedFrameRate_Hz_MSByte ,  0x2881,   0x0000 },
  {   StaticFrameRateStatus_uwMaxFrameRate_Hz_LSByte ,  0x2886,   0x0000 },
-@@ -4015,15 +5528,71 @@ struct nomadik_vpip_param vpip_default_p
+ {   StaticFrameRateStatus_uwMaxFrameRate_Hz_MSByte ,  0x2885,   0x0000 },
+ {   StaticFrameRateStatus_uwMinFrameRate_Hz_LSByte ,  0x288a,   0x0000 },
+ {   StaticFrameRateStatus_uwMinFrameRate_Hz_MSByte ,  0x2889,   0x0000 },
+ {   StaticFrameRateStatus_fChangePending ,  0x288c,   0x0000 },
  {   StaticFrameRateStatus_uwRequiredFrameLength_lines_LSByte ,  0x2890,   0x0000 },
  {   StaticFrameRateStatus_uwRequiredFrameLength_lines_MSByte ,  0x288f,   0x0000 },
  {   StaticFrameRateStatus_ClipFrameRate ,  0x2892,   0x0000 },
@@ -3592,7 +4045,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixFarSensor_fpRInR_LSByte ,  0x2b02,   0x0000 },
  {   ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte ,  0x2b01,   0x3fd3 },
  {   ColourEngine0_ColourMatrixFarSensor_fpGInR_LSByte ,  0x2b06,   0x0000 },
-@@ -4042,6 +5611,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte ,  0x2b05,   0xbce0 },
+ {   ColourEngine0_ColourMatrixFarSensor_fpBInR_LSByte ,  0x2b0a,   0x0000 },
+@@ -4040,10 +5609,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixFarSensor_fpRInB_MSByte ,  0x2b19,   0xb717 },
+ {   ColourEngine0_ColourMatrixFarSensor_fpGInB_LSByte ,  0x2b1e,   0x0000 },
  {   ColourEngine0_ColourMatrixFarSensor_fpGInB_MSByte ,  0x2b1d,   0xbd29 },
  {   ColourEngine0_ColourMatrixFarSensor_fpBInB_LSByte ,  0x2b22,   0x0000 },
  {   ColourEngine0_ColourMatrixFarSensor_fpBInB_MSByte ,  0x2b21,   0x3fc6 },
@@ -3601,7 +4058,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixNearSensor_fpRInR_LSByte ,  0x2b82,   0x0002 },
  {   ColourEngine0_ColourMatrixNearSensor_fpRInR_MSByte ,  0x2b81,   0x6400 },
  {   ColourEngine0_ColourMatrixNearSensor_fpGInR_LSByte ,  0x2b86,   0x0002 },
-@@ -4060,6 +5631,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixNearSensor_fpGInR_MSByte ,  0x2b85,   0x6400 },
+ {   ColourEngine0_ColourMatrixNearSensor_fpBInR_LSByte ,  0x2b8a,   0x0002 },
+@@ -4058,10 +5629,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixNearSensor_fpRInB_MSByte ,  0x2b99,   0xe900 },
+ {   ColourEngine0_ColourMatrixNearSensor_fpGInB_LSByte ,  0x2b9e,   0x0000 },
  {   ColourEngine0_ColourMatrixNearSensor_fpGInB_MSByte ,  0x2b9d,   0xe900 },
  {   ColourEngine0_ColourMatrixNearSensor_fpBInB_LSByte ,  0x2ba2,   0x0000 },
  {   ColourEngine0_ColourMatrixNearSensor_fpBInB_MSByte ,  0x2ba1,   0xe900 },
@@ -3611,7 +4072,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixDamped_wRInR_LSByte ,  0x2c02,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wRInR_MSByte ,  0x2c01,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wGInR_LSByte ,  0x2c06,   0x0000 },
-@@ -4078,6 +5652,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixDamped_wGInR_MSByte ,  0x2c05,   0x0000 },
+ {   ColourEngine0_ColourMatrixDamped_wBInR_LSByte ,  0x2c0a,   0x0000 },
+@@ -4076,17 +5650,53 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixDamped_wRInB_MSByte ,  0x2c19,   0x0000 },
+ {   ColourEngine0_ColourMatrixDamped_wGInB_LSByte ,  0x2c1e,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wGInB_MSByte ,  0x2c1d,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wBInB_LSByte ,  0x2c22,   0x0000 },
  {   ColourEngine0_ColourMatrixDamped_wBInB_MSByte ,  0x2c21,   0x0000 },
@@ -3630,7 +4095,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ColourMatrixDamperControl_fDisableMatrixDamping ,  0x2c80,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_LSByte ,  0x2c84,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_DamperLowThreshold_MSByte ,  0x2c83,   0x62ac },
-@@ -4085,6 +5671,30 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_LSByte ,  0x2c88,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_DamperHighThreshold_MSByte ,  0x2c87,   0x64ac },
  {   ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_LSByte ,  0x2c8c,   0x0000 },
  {   ColourEngine0_ColourMatrixDamperControl_MinimumDamperOutput_MSByte ,  0x2c8b,   0x0000 },
@@ -3661,7 +4126,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_ApertureCorrectionControls_fDisableCorrection ,  0x2d00,   0x0000 },
  {   ColourEngine0_ApertureCorrectionControls_bMaxGain ,  0x2d02,   0x0010 },
  {   ColourEngine0_ApertureCorrectionControls_fDisableGainDamping ,  0x2d04,   0x0000 },
-@@ -4103,9 +5713,25 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_LSByte ,  0x2d08,   0x0000 },
+ {   ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Gain_MSByte ,  0x2d07,   0x5871 },
+@@ -4101,21 +5711,53 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_ApertureCorrectionControls_DamperLowThreshold_Coring_MSByte ,  0x2d19,   0x5871 },
+ {   ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_LSByte ,  0x2d1e,   0x0000 },
  {   ColourEngine0_ApertureCorrectionControls_DamperHighThreshold_Coring_MSByte ,  0x2d1d,   0x63d1 },
  {   ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_LSByte ,  0x2d22,   0x0000 },
  {   ColourEngine0_ApertureCorrectionControls_MinimumDamperOutput_Coring_MSByte ,  0x2d21,   0x3a00 },
@@ -3687,7 +4156,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_GammaCorrection_fEnabled ,  0x2e00,   0x0001 },
  {   ColourEngine0_GammaCorrection_bMode ,  0x2e02,   0x0001 },
  {   ColourEngine0_GammaCorrection_SharpRed ,  0x2e04,   0x0013 },
-@@ -4114,6 +5740,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_GammaCorrection_SharpGreen ,  0x2e06,   0x0013 },
+ {   ColourEngine0_GammaCorrection_SharpBlue ,  0x2e08,   0x0013 },
  {   ColourEngine0_GammaCorrection_SoftRed ,  0x2e0a,   0x0013 },
  {   ColourEngine0_GammaCorrection_SoftGreen ,  0x2e0c,   0x0013 },
  {   ColourEngine0_GammaCorrection_SoftBlue ,  0x2e0e,   0x0013 },
@@ -3710,7 +4180,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   NoraControls_fDisable ,  0x2e80,   0x0001 },
  {   NoraControls_fDisableNoraPromoting ,  0x2e82,   0x0000 },
  {   NoraControls_bMaximumValue ,  0x2e84,   0x0001 },
-@@ -4126,7 +5768,33 @@ struct nomadik_vpip_param vpip_default_p
+ {   NoraControls_fDifferentTextureDegreeForBlue ,  0x2e86,   0x0000 },
+ {   NoraControls_fSplitNoiseLevel ,  0x2e88,   0x0000 },
+@@ -4124,11 +5766,37 @@ struct nomadik_vpip_param vpip_default_p
+ {   NoraControls_DamperLowThreshold_MSByte ,  0x2e8d,   0x4000 },
+ {   NoraControls_DamperHighThreshold_LSByte ,  0x2e92,   0x0000 },
  {   NoraControls_DamperHighThreshold_MSByte ,  0x2e91,   0x4500 },
  {   NoraControls_MinimumDamperOutput_LSByte ,  0x2e96,   0x0000 },
  {   NoraControls_MinimumDamperOutput_MSByte ,  0x2e95,   0x0000 },
@@ -3744,7 +4218,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ScytheFilterControls_fDisableFilter ,  0x2f80,   0x0000 },
  {   ScytheFilterControls_fSquareLaw ,  0x2f82,   0x0000 },
  {   ScytheFilterControls_fDisablePromotingLow ,  0x2f84,   0x0000 },
-@@ -4145,6 +5813,29 @@ struct nomadik_vpip_param vpip_default_p
+ {   ScytheFilterControls_fDisablePromotingHigh ,  0x2f86,   0x0000 },
+ {   ScytheFilterControls_bMaxWeightLow ,  0x2f88,   0x0010 },
+@@ -4143,10 +5811,33 @@ struct nomadik_vpip_param vpip_default_p
+ {   ScytheFilterControls_fpDamperHighThresholdHigh_MSByte ,  0x2f99,   0x68dc },
+ {   ScytheFilterControls_fpMinimumDamperOutputLow_LSByte ,  0x2f9e,   0x0000 },
  {   ScytheFilterControls_fpMinimumDamperOutputLow_MSByte ,  0x2f9d,   0x3a00 },
  {   ScytheFilterControls_fpMinimumDamperOutputHigh_LSByte ,  0x2fa2,   0x0000 },
  {   ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte ,  0x2fa1,   0x3a00 },
@@ -3774,7 +4252,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   JackFilterControls_fDisableFilter ,  0x3000,   0x0000 },
  {   JackFilterControls_fSquareLaw ,  0x3002,   0x0000 },
  {   JackFilterControls_fDisablePromotingLow ,  0x3004,   0x0000 },
-@@ -4163,10 +5854,25 @@ struct nomadik_vpip_param vpip_default_p
+ {   JackFilterControls_fDisablePromotingHigh ,  0x3006,   0x0000 },
+ {   JackFilterControls_bMaxWeightLow ,  0x3008,   0x0010 },
+@@ -4161,103 +5852,208 @@ struct nomadik_vpip_param vpip_default_p
+ {   JackFilterControls_fpDamperHighThresholdHigh_MSByte ,  0x3019,   0x68dc },
+ {   JackFilterControls_fpMinimumDamperOutputLow_LSByte ,  0x301e,   0x0000 },
  {   JackFilterControls_fpMinimumDamperOutputLow_MSByte ,  0x301d,   0x0000 },
  {   JackFilterControls_fpMinimumDamperOutputHigh_LSByte ,  0x3022,   0x0000 },
  {   JackFilterControls_fpMinimumDamperOutputHigh_MSByte ,  0x3021,   0x0000 },
@@ -3800,7 +4282,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   VfpnControls_fEnableCorrection ,  0x3100,   0x0000 },
  {   VfpnControls_uwMaximumPixelValue_LSByte ,  0x3104,   0x0000 },
  {   VfpnControls_uwMaximumPixelValue_MSByte ,  0x3103,   0x03ff },
-@@ -4175,15 +5881,61 @@ struct nomadik_vpip_param vpip_default_p
+ {   VfpnControls_uwMinimumPixelValue_LSByte ,  0x3108,   0x0000 },
+ {   VfpnControls_uwMinimumPixelValue_MSByte ,  0x3107,   0x0000 },
  {   VfpnControls_uwPixelSaturationLevel_LSByte ,  0x310c,   0x0000 },
  {   VfpnControls_uwPixelSaturationLevel_MSByte ,  0x310b,   0x03ff },
  {   VfpnControls_bLogThreshLog ,  0x310e,   0x0004 },
@@ -3865,7 +4348,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControls_bFilterCoeff_R2_b ,  0x3208,   0x0000 },
  {   AntiVignetteControls_bFilterCoeff_R4_r ,  0x320a,   0x0000 },
  {   AntiVignetteControls_bFilterCoeff_R4_gr ,  0x320c,   0x0000 },
-@@ -4193,8 +5945,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControls_bFilterCoeff_R4_gb ,  0x320e,   0x0000 },
+ {   AntiVignetteControls_bFilterCoeff_R4_b ,  0x3210,   0x0000 },
+ {   AntiVignetteControls_uwHorizontalOffset_LSByte ,  0x3214,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_MSByte ,  0x3213,   0x0000 },
  {   AntiVignetteControls_uwVerticalOffset_LSByte ,  0x3218,   0x0000 },
  {   AntiVignetteControls_uwVerticalOffset_MSByte ,  0x3217,   0x0000 },
@@ -3876,7 +4361,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControls_uwHorizontalOffset_r_LSByte ,  0x3220,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_r_MSByte ,  0x321f,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_gr_LSByte ,  0x3224,   0x0000 },
-@@ -4204,18 +5956,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControls_uwHorizontalOffset_gr_MSByte ,  0x3223,   0x0000 },
+ {   AntiVignetteControls_uwHorizontalOffset_gb_LSByte ,  0x3228,   0x0000 },
+ {   AntiVignetteControls_uwHorizontalOffset_gb_MSByte ,  0x3227,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_b_LSByte ,  0x322c,   0x0000 },
  {   AntiVignetteControls_uwHorizontalOffset_b_MSByte ,  0x322b,   0x0000 },
  {   AntiVignetteControls_uwVerticalOffset_r_LSByte ,  0x3230,   0x0000 },
@@ -3905,7 +4392,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteStatus_fXScaleEnabled ,  0x3280,   0x0000 },
  {   AntiVignetteStatus_bXScale ,  0x3282,   0x0000 },
  {   AntiVignetteStatus_fYScaleEnabled ,  0x3284,   0x0000 },
-@@ -4224,13 +5980,35 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteStatus_bYScale ,  0x3286,   0x0000 },
+ {   AntiVignetteStatus_uwHorizontalSize_LSByte ,  0x328a,   0x0000 },
  {   AntiVignetteStatus_uwHorizontalSize_MSByte ,  0x3289,   0x0000 },
  {   AntiVignetteStatus_uwVerticalSize_LSByte ,  0x328e,   0x0000 },
  {   AntiVignetteStatus_uwVerticalSize_MSByte ,  0x328d,   0x0000 },
@@ -3942,7 +4430,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_LSByte ,  0x3402,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHOffset_MSByte ,  0x3401,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_LSByte ,  0x3406,   0x0000 },
-@@ -4239,9 +6017,21 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVOffset_MSByte ,  0x3405,   0x0000 },
+ {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_LSByte ,  0x340a,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwHScalingFactor_MSByte ,  0x3409,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_LSByte ,  0x340e,   0x0000 },
  {   ColourEngine0_RadialApertureCorrectionApplicationInputs_uwVScalingFactor_MSByte ,  0x340d,   0x0000 },
@@ -3964,7 +4453,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_LSByte ,  0x3502,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwLumaExcursion_MSByte ,  0x3501,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_LSByte ,  0x3506,   0x0000 },
-@@ -4250,12 +6040,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_CoderOutputSignalRange_uwLumaMidpointTimes2_MSByte ,  0x3505,   0x0000 },
+ {   ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_LSByte ,  0x350a,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwChromaExcursion_MSByte ,  0x3509,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_LSByte ,  0x350e,   0x0000 },
  {   ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte ,  0x350d,   0x0000 },
@@ -3983,7 +4473,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_OutputCoderMatrix_w0_0_LSByte ,  0x3602,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w0_0_MSByte ,  0x3601,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w0_1_LSByte ,  0x3606,   0x0000 },
-@@ -4274,6 +6070,20 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_OutputCoderMatrix_w0_1_MSByte ,  0x3605,   0x0000 },
+ {   ColourEngine0_OutputCoderMatrix_w0_2_LSByte ,  0x360a,   0x0000 },
+@@ -4272,37 +6068,91 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_OutputCoderMatrix_w2_0_MSByte ,  0x3619,   0x0000 },
+ {   ColourEngine0_OutputCoderMatrix_w2_1_LSByte ,  0x361e,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w2_1_MSByte ,  0x361d,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w2_2_LSByte ,  0x3622,   0x0000 },
  {   ColourEngine0_OutputCoderMatrix_w2_2_MSByte ,  0x3621,   0x0000 },
@@ -4004,7 +4498,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine0_FadeToBlack_fDisable ,  0x3680,   0x0001 },
  {   ColourEngine0_FadeToBlack_fpBlackValue_LSByte ,  0x3684,   0x0000 },
  {   ColourEngine0_FadeToBlack_fpBlackValue_MSByte ,  0x3683,   0x0000 },
-@@ -4283,10 +6093,48 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine0_FadeToBlack_fpDamperLowThreshold_LSByte ,  0x3688,   0x0000 },
+ {   ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte ,  0x3687,   0x63d1 },
+ {   ColourEngine0_FadeToBlack_fpDamperHighThreshold_LSByte ,  0x368c,   0x0000 },
  {   ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte ,  0x368b,   0x656f },
  {   ColourEngine0_FadeToBlack_fpDamperOutput_LSByte ,  0x3690,   0x0000 },
  {   ColourEngine0_FadeToBlack_fpDamperOutput_MSByte ,  0x368f,   0x0000 },
@@ -4053,7 +4549,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrParams_fAntiZip ,  0x3780,   0x0000 },
  {   ZoomMgrParams_bFilterCrispness0 ,  0x3782,   0x0000 },
  {   ZoomMgrParams_bFilterCrispness1 ,  0x3784,   0x0000 },
-@@ -4295,12 +6143,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrParams_fInFromOutARLock ,  0x3786,   0x0000 },
+ {   ZoomMgrParams_bPrescaleFactor ,  0x3788,   0x0000 },
  {   ZoomMgrParams_bPrescaleType ,  0x378a,   0x0000 },
  {   ZoomMgrParams_fp16ZoomRange_LSByte ,  0x378e,   0x0000 },
  {   ZoomMgrParams_fp16ZoomRange_MSByte ,  0x378d,   0x100 },
@@ -4069,7 +4566,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrCtrl_bChgOverMarginShift ,  0x380c,   0x0000 },
  {   ZoomMgrCtrl_fCheckDataRate ,  0x380e,   0x0000 },
  {   ZoomMgrCtrl_fSetAlternateInitWOI ,  0x3810,   0x0000 },
-@@ -4312,6 +6162,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrCtrl_fSetX_Byte0 ,  0x3812,   0x0000 },
+ {   ZoomMgrCtrl_fSetX_Byte1 ,  0x3814,   0x0000 },
+@@ -4310,10 +6160,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrCtrl_fSetX_Byte3 ,  0x3818,   0x0000 },
+ {   ZoomMgrCtrl_fp16P0ScaleLowLimit_LSByte ,  0x381c,   0x0000 },
  {   ZoomMgrCtrl_fp16P0ScaleLowLimit_MSByte ,  0x381b,   0x0000 },
  {   ZoomMgrCtrl_fp16P1ScaleLowLimit_LSByte ,  0x3820,   0x0000 },
  {   ZoomMgrCtrl_fp16P1ScaleLowLimit_MSByte ,  0x381f,   0x0000 },
@@ -4079,7 +4580,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrStatus_fReady ,  0x3880,   0x0000 },
  {   ZoomMgrStatus_bDeviceTestCoin ,  0x3882,   0x0000 },
  {   ZoomMgrStatus_bNextCmd ,  0x3884,   0x0000 },
-@@ -4345,6 +6198,24 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrStatus_bLastCmd ,  0x3886,   0x0000 },
+ {   ZoomMgrStatus_bCommandStatus ,  0x3888,   0x0000 },
+@@ -4343,10 +6196,28 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrStatus_fMinFOVX_Byte3 ,  0x38b8,   0x0000 },
+ {   ZoomMgrStatus_uwXOrigin_LSByte ,  0x38bc,   0x0000 },
  {   ZoomMgrStatus_uwXOrigin_MSByte ,  0x38bb,   0x0000 },
  {   ZoomMgrStatus_uwYOrigin_LSByte ,  0x38c0,   0x0000 },
  {   ZoomMgrStatus_uwYOrigin_MSByte ,  0x38bf,   0x0000 },
@@ -4104,7 +4609,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceConstrainerControls_fpRedA_LSByte ,  0x3902,   0x0000 },
  {   WhiteBalanceConstrainerControls_fpRedA_MSByte ,  0x3901,   0x0000 },
  {   WhiteBalanceConstrainerControls_fpBlueA_LSByte ,  0x3906,   0x0000 },
-@@ -4356,6 +6227,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerControls_fpBlueA_MSByte ,  0x3905,   0x0000 },
+ {   WhiteBalanceConstrainerControls_fpRedB_LSByte ,  0x390a,   0x0000 },
+@@ -4354,25 +6225,34 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerControls_fpBlueB_LSByte ,  0x390e,   0x0000 },
+ {   WhiteBalanceConstrainerControls_fpBlueB_MSByte ,  0x390d,   0x3acf },
  {   WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_LSByte ,  0x3912,   0x0000 },
  {   WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte ,  0x3911,   0x2e8e },
  {   WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance ,  0x3914,   0x0001 },
@@ -4114,7 +4623,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceConstrainerOutput_fpOutputRedGain_LSByte ,  0x3982,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputRedGain_MSByte ,  0x3981,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputGreenGain_LSByte ,  0x3986,   0x0000 },
-@@ -4363,6 +6237,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerOutput_fpOutputGreenGain_MSByte ,  0x3985,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputBlueGain_LSByte ,  0x398a,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fpOutputBlueGain_MSByte ,  0x3989,   0x0000 },
  {   WhiteBalanceConstrainerOutput_fAreGainsConstrained ,  0x398c,   0x0000 },
@@ -4124,7 +4633,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_LSByte ,  0x3a02,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpGradientOfLocusAB_MSByte ,  0x3a01,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_LSByte ,  0x3a06,   0x0000 },
-@@ -4371,6 +6248,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   WhiteBalanceConstrainerInternal_fpDistanceOfInputPointFromLocusAB_MSByte ,  0x3a05,   0x0000 },
+ {   WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_LSByte ,  0x3a0a,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpConstrainedRedPoint_MSByte ,  0x3a09,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_LSByte ,  0x3a0e,   0x0000 },
  {   WhiteBalanceConstrainerInternal_fpConstrainedBluePoint_MSByte ,  0x3a0d,   0x0000 },
@@ -4134,7 +4644,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeSetupBank1_uwInputImageSize_X_LSByte ,  0x3a82,   0x0000 },
  {   ModeSetupBank1_uwInputImageSize_X_MSByte ,  0x3a81,   0x0000 },
  {   ModeSetupBank1_uwInputImageSize_Y_LSByte ,  0x3a86,   0x0000 },
-@@ -4383,7 +6263,7 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_uwInputImageSize_Y_MSByte ,  0x3a85,   0x0000 },
+ {   ModeSetupBank1_uwMaxImageSize_X_LSByte ,  0x3a8a,   0x0000 },
+@@ -4381,11 +6261,11 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_uwMaxImageSize_Y_MSByte ,  0x3a8d,   0x0000 },
+ {   ModeSetupBank1_uwMinImageSize_X_LSByte ,  0x3a92,   0x0000 },
  {   ModeSetupBank1_uwMinImageSize_X_MSByte ,  0x3a91,   0x0000 },
  {   ModeSetupBank1_uwMinImageSize_Y_LSByte ,  0x3a96,   0x0000 },
  {   ModeSetupBank1_uwMinImageSize_Y_MSByte ,  0x3a95,   0x0000 },
@@ -4143,7 +4657,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ModeSetupBank1_fLowPowerStreaming ,  0x3a9a,   0x0000 },
  {   ModeSetupBank1_bTestMode ,  0x3a9c,   0x0000 },
  {   ModeSetupBank1_bNumberOfStatusLines ,  0x3a9e,   0x0000 },
-@@ -4396,9 +6276,18 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_bNumberOfDarkLines ,  0x3aa0,   0x0000 },
+ {   ModeSetupBank1_bNumberOfBlackLines ,  0x3aa2,   0x0000 },
+@@ -4394,13 +6274,22 @@ struct nomadik_vpip_param vpip_default_p
+ {   ModeSetupBank1_uwNumberOfInterFrameLines_LSByte ,  0x3aaa,   0x0000 },
+ {   ModeSetupBank1_uwNumberOfInterFrameLines_MSByte ,  0x3aa9,   0x0000 },
  {   ModeSetupBank1_bNumberOfDummyColumns ,  0x3aac,   0x0000 },
  {   ModeSetupBank1_bInputImageSource ,  0x3aae,   0x0000 },
  {   ModeSetupBank1_bOutputImageDestination ,  0x3ab0,   0x0000 },
@@ -4163,7 +4681,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControlsFar_bFilterCoeff_R2_r ,  0x3c02,   0x0000 },
  {   AntiVignetteControlsFar_bFilterCoeff_R2_gr ,  0x3c04,   0x0000 },
  {   AntiVignetteControlsFar_bFilterCoeff_R2_gb ,  0x3c06,   0x0000 },
-@@ -4434,7 +6323,10 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsFar_bFilterCoeff_R2_b ,  0x3c08,   0x0000 },
+ {   AntiVignetteControlsFar_bFilterCoeff_R4_r ,  0x3c0a,   0x0000 },
+@@ -4432,11 +6321,14 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsFar_bUnityOffset_r ,  0x3c3e,   0x0000 },
+ {   AntiVignetteControlsFar_bUnityOffset_gr ,  0x3c40,   0x0000 },
  {   AntiVignetteControlsFar_bUnityOffset_gb ,  0x3c42,   0x0000 },
  {   AntiVignetteControlsFar_bUnityOffset_b ,  0x3c44,   0x0000 },
  {   AntiVignetteControlsFar_fAdaptiveAntiVignetteEnable ,  0x3c46,   0x0000 },
@@ -4175,7 +4697,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiVignetteControlsNear_bFilterCoeff_R2_r ,  0x3c82,   0x0000 },
  {   AntiVignetteControlsNear_bFilterCoeff_R2_gr ,  0x3c84,   0x0000 },
  {   AntiVignetteControlsNear_bFilterCoeff_R2_gb ,  0x3c86,   0x0000 },
-@@ -4470,6 +6362,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsNear_bFilterCoeff_R2_b ,  0x3c88,   0x0000 },
+ {   AntiVignetteControlsNear_bFilterCoeff_R4_r ,  0x3c8a,   0x0000 },
+@@ -4468,19 +6360,25 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiVignetteControlsNear_bUnityOffset_r ,  0x3cbe,   0x0000 },
+ {   AntiVignetteControlsNear_bUnityOffset_gr ,  0x3cc0,   0x0000 },
  {   AntiVignetteControlsNear_bUnityOffset_gb ,  0x3cc2,   0x0000 },
  {   AntiVignetteControlsNear_bUnityOffset_b ,  0x3cc4,   0x0000 },
  {   AntiVignetteControlsNear_fAdaptiveAntiVignetteEnable ,  0x3cc6,   0x0000 },
@@ -4185,7 +4711,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFStatsControls_fAbsSquareEnabled ,  0x3d00,   0x0000 },
  {   AFStatsControls_bCoringValue ,  0x3d02,   0x0000 },
  {   AFStatsControls_bWindowsSystem ,  0x3d04,   0x0000 },
-@@ -4479,6 +6374,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFStatsControls_bHRatio_Num ,  0x3d06,   0x0000 },
+ {   AFStatsControls_bHRatio_Den ,  0x3d08,   0x0000 },
+ {   AFStatsControls_bVRatio_Num ,  0x3d0a,   0x0000 },
  {   AFStatsControls_bVRatio_Den ,  0x3d0c,   0x0000 },
  {   AFStatsControls_bHostActiveZonesCounter ,  0x3d0e,   0x0000 },
  {   AFStatsControls_fAutoRefresh ,  0x3d10,   0x0000 },
@@ -4195,7 +4723,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFStatsStatus_bAFStats_Error ,  0x3d80,   0x0000 },
  {   AFStatsStatus_fAbsSquareEnabled ,  0x3d82,   0x0000 },
  {   AFStatsStatus_bCoringValue ,  0x3d84,   0x0000 },
-@@ -4503,6 +6401,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFStatsStatus_bWindowsSystem ,  0x3d86,   0x0000 },
+ {   AFStatsStatus_bActiveZonesCounter ,  0x3d88,   0x0000 },
+@@ -4501,10 +6399,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte1 ,  0x3da6,   0x0000 },
+ {   AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte2 ,  0x3da8,   0x0000 },
  {   AFStatsStatus_udwMaxFocusMeasurePerPixel_Byte3 ,  0x3daa,   0x0000 },
  {   AFStatsStatus_uwStartingAFZoneLine_LSByte ,  0x3dae,   0x0000 },
  {   AFStatsStatus_uwStartingAFZoneLine_MSByte ,  0x3dad,   0x0000 },
@@ -4205,7 +4737,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFFocusStats_udwStatsValue_0_Byte0 ,  0x3e00,   0x0000 },
  {   AFFocusStats_udwStatsValue_0_Byte1 ,  0x3e02,   0x0000 },
  {   AFFocusStats_udwStatsValue_0_Byte2 ,  0x3e04,   0x0000 },
-@@ -4531,6 +6432,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFFocusStats_udwStatsValue_0_Byte3 ,  0x3e06,   0x0000 },
+ {   AFFocusStats_udwStatsValue_1_Byte0 ,  0x3e08,   0x0000 },
+@@ -4529,17 +6430,52 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFFocusStats_udwStatsValue_5_Byte3 ,  0x3e2e,   0x0000 },
+ {   AFFocusStats_udwStatsValue_6_Byte0 ,  0x3e30,   0x0000 },
  {   AFFocusStats_udwStatsValue_6_Byte1 ,  0x3e32,   0x0000 },
  {   AFFocusStats_udwStatsValue_6_Byte2 ,  0x3e34,   0x0000 },
  {   AFFocusStats_udwStatsValue_6_Byte3 ,  0x3e36,   0x0000 },
@@ -4215,7 +4751,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AFLightStats_bStatsValue_0 ,  0x3e80,   0x0000 },
  {   AFLightStats_bStatsValue_1 ,  0x3e82,   0x0000 },
  {   AFLightStats_bStatsValue_2 ,  0x3e84,   0x0000 },
-@@ -4538,6 +6442,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   AFLightStats_bStatsValue_3 ,  0x3e86,   0x0000 },
  {   AFLightStats_bStatsValue_4 ,  0x3e88,   0x0000 },
  {   AFLightStats_bStatsValue_5 ,  0x3e8a,   0x0000 },
  {   AFLightStats_bStatsValue_6 ,  0x3e8c,   0x0000 },
@@ -4254,7 +4790,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FLADriverLowLevelParameters_wMinPosition_LSByte ,  0x3f02,   0x0000 },
  {   FLADriverLowLevelParameters_wMinPosition_MSByte ,  0x3f01,   0x0000 },
  {   FLADriverLowLevelParameters_wMaxPosition_LSByte ,  0x3f06,   0x0000 },
-@@ -4565,6 +6501,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverLowLevelParameters_wMaxPosition_MSByte ,  0x3f05,   0x0000 },
+ {   FLADriverLowLevelParameters_wHomePosition_LSByte ,  0x3f0a,   0x0000 },
+@@ -4563,20 +6499,26 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverLowLevelParameters_bNVM_PS_IBias ,  0x3f2c,   0x0000 },
+ {   FLADriverLowLevelParameters_bNVM_PS_RampGain ,  0x3f2e,   0x0000 },
  {   FLADriverLowLevelParameters_bNVM_PS_Type ,  0x3f30,   0x0000 },
  {   FLADriverLowLevelParameters_uwNVM_minidriver_m_c_LSByte ,  0x3f34,   0x0000 },
  {   FLADriverLowLevelParameters_uwNVM_minidriver_m_c_MSByte ,  0x3f33,   0x0000 },
@@ -4264,7 +4804,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FLADriverControls_bMMode ,  0x3f80,   0x0000 },
  {   FLADriverControls_wTargetPosition_LSByte ,  0x3f84,   0x0000 },
  {   FLADriverControls_wTargetPosition_MSByte ,  0x3f83,   0x0000 },
-@@ -4575,6 +6514,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverControls_wPositionTolerance_LSByte ,  0x3f88,   0x0000 },
+ {   FLADriverControls_wPositionTolerance_MSByte ,  0x3f87,   0x0000 },
+ {   FLADriverControls_uwTimeLimit_ms_LSByte ,  0x3f8c,   0x0000 },
+ {   FLADriverControls_uwTimeLimit_ms_MSByte ,  0x3f8b,   0x0000 },
  {   FLADriverControls_bTrigger ,  0x3f8e,   0x0000 },
  {   FLADriverControls_bSlewMode ,  0x3f90,   0x0000 },
  {   FLADriverControls_bSlewRate ,  0x3f92,   0x0000 },
@@ -4274,7 +4817,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FLADriverStatus_wLensPosition_LSByte ,  0x4002,   0x0000 },
  {   FLADriverStatus_wLensPosition_MSByte ,  0x4001,   0x0000 },
  {   FLADriverStatus_fLensIsMoving ,  0x4004,   0x0000 },
-@@ -4586,6 +6528,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverStatus_fLimitsExceeded ,  0x4006,   0x0000 },
+ {   FLADriverStatus_fLensIsAtHome ,  0x4008,   0x0000 },
+@@ -4584,10 +6526,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   FLADriverStatus_bSkippedFrames ,  0x400c,   0x0000 },
+ {   FLADriverStatus_bCycles ,  0x400e,   0x0000 },
  {   FLADriverStatus_bMiniDriverTimeoutError ,  0x4010,   0x0000 },
  {   FLADriverStatus_wTargetPosition ,  0x4012,   0x0000 },
  {   FLADriverStatus_bLowLevelPosition ,  0x4014,   0x0000 },
@@ -4284,7 +4831,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FocusControls_fErrorReset ,  0x4080,   0x0000 },
  {   FocusControls_bRange ,  0x4082,   0x0000 },
  {   FocusControls_bMode ,  0x4084,   0x0000 },
-@@ -4597,6 +6542,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusControls_bAFCommand ,  0x4086,   0x0000 },
+ {   FocusControls_bLensCommand ,  0x4088,   0x0000 },
+@@ -4595,10 +6540,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusControls_fTestCoinEnabled ,  0x408c,   0x0000 },
+ {   FocusControls_bControlCoin ,  0x408e,   0x0000 },
  {   FocusControls_fInternalStats_Disable ,  0x4090,   0x0000 },
  {   FocusControls_bActuator_Disable ,  0x4092,   0x0000 },
  {   FocusControls_fInhibitAutoMetering ,  0x4094,   0x0000 },
@@ -4294,7 +4845,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FocusStatus_bModeStatus ,  0x4100,   0x0000 },
  {   FocusStatus_bAFCommandStatus ,  0x4102,   0x0000 },
  {   FocusStatus_bLensCommandStatus ,  0x4104,   0x0000 },
-@@ -4612,6 +6560,30 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusStatus_fAutoFocusEnabled ,  0x4106,   0x0000 },
+ {   FocusStatus_bRange ,  0x4108,   0x0000 },
+@@ -4610,10 +6558,34 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusStatus_fRunForTest ,  0x4114,   0x0000 },
+ {   FocusStatus_bStatusCoin ,  0x4116,   0x0000 },
  {   FocusStatus_fInternalStats_Disabled ,  0x4118,   0x0000 },
  {   FocusStatus_bActuator_Disabled ,  0x411a,   0x0000 },
  {   FocusStatus_bLastUsedAFSensor ,  0x411c,   0x0000 },
@@ -4325,7 +4880,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   FocusRangeConstants_wFullRange_LensMinPosition_LSByte ,  0x4182,   0x0000 },
  {   FocusRangeConstants_wFullRange_LensMinPosition_MSByte ,  0x4181,   0x0000 },
  {   FocusRangeConstants_wFullRange_LensMaxPosition_LSByte ,  0x4186,   0x0000 },
-@@ -4630,6 +6602,34 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusRangeConstants_wFullRange_LensMaxPosition_MSByte ,  0x4185,   0x03ff },
+ {   FocusRangeConstants_wFullRange_LensRecoveryPosition_LSByte ,  0x418a,   0x0000 },
+@@ -4628,10 +6600,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   FocusRangeConstants_wMacro_LensMinPosition_MSByte ,  0x4199,   0x0000 },
+ {   FocusRangeConstants_wMacro_LensMaxPosition_LSByte ,  0x419e,   0x0000 },
  {   FocusRangeConstants_wMacro_LensMaxPosition_MSByte ,  0x419d,   0x03ff },
  {   FocusRangeConstants_wMacro_LensRecoveryPosition_LSByte ,  0x41a2,   0x0000 },
  {   FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte ,  0x41a1,   0x01ff },
@@ -4360,7 +4919,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusControls_bHostCmd ,  0x4200,   0x0000 },
  {   AutoFocusControls_fFreezeIfStable ,  0x4202,   0x0000 },
  {   AutoFocusControls_fFMTesting_AutoDisable ,  0x4204,   0x0001 },
-@@ -4653,6 +6653,35 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusControls_fFastAFAlgoStart ,  0x4206,   0x0000 },
+ {   AutoFocusControls_fBackLight_Enable ,  0x4208,   0x0000 },
+@@ -4651,10 +6651,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusControls_fEnableTrakingZoneVariation ,  0x4224,   0x0000 },
+ {   AutoFocusControls_fEnableFunctionThresholdTest ,  0x4226,   0x0001 },
  {   AutoFocusControls_fForceTestState ,  0x4228,   0x0000 },
  {   AutoFocusControls_bManualAFNextState ,  0x422a,   0x0000 },
  {   AutoFocusControls_fResetHCSPos ,  0x422c,   0x0001 },
@@ -4396,7 +4959,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusConstants_bCoarseStep ,  0x4280,   0x0078 },
  {   AutoFocusConstants_bFineStep ,  0x4282,   0x0014 },
  {   AutoFocusConstants_bFullSearchStep ,  0x4284,   0x0000 },
-@@ -4677,11 +6706,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusConstants_bLeakyIntegratorConstant ,  0x4286,   0x0000 },
+ {   AutoFocusConstants_uwFineThreshold_LSByte ,  0x428a,   0x0000 },
+@@ -4675,15 +6704,21 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusConstants_bLightGap ,  0x42a6,   0x0000 },
+ {   AutoFocusConstants_uwDeltaValue_LSByte ,  0x42aa,   0x0000 },
  {   AutoFocusConstants_uwDeltaValue_MSByte ,  0x42a9,   0x0000 },
  {   AutoFocusConstants_uwMaxFineTh_LSByte ,  0x42ae,   0x0000 },
  {   AutoFocusConstants_uwMaxFineTh_MSByte ,  0x42ad,   0x0000 },
@@ -4414,7 +4981,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusStatus_bCycles ,  0x4380,   0x0000 },
  {   AutoFocusStatus_bHostCmd ,  0x4382,   0x0000 },
  {   AutoFocusStatus_bAF_PrevState ,  0x4384,   0x0000 },
-@@ -4716,10 +6751,16 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusStatus_bAF_State ,  0x4386,   0x0000 },
+ {   AutoFocusStatus_bAF_NextState ,  0x4388,   0x0000 },
+@@ -4714,14 +6749,20 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusStatus_uwTotalCoarseVariation_LSByte ,  0x43bc,   0x0000 },
+ {   AutoFocusStatus_uwTotalCoarseVariation_MSByte ,  0x43bb,   0x0000 },
  {   AutoFocusStatus_uwTotalFineVariation_LSByte ,  0x43c0,   0x0000 },
  {   AutoFocusStatus_uwTotalFineVariation_MSByte ,  0x43bf,   0x0000 },
  {   AutoFocusStatus_bCountVariationRegion ,  0x43c2,   0x0000 },
@@ -4431,7 +5002,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusMeasureData_udwFocusMeasure_Byte0 ,  0x4480,   0x0000 },
  {   AutoFocusMeasureData_udwFocusMeasure_Byte1 ,  0x4482,   0x0000 },
  {   AutoFocusMeasureData_udwFocusMeasure_Byte2 ,  0x4484,   0x0000 },
-@@ -4776,6 +6817,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusMeasureData_udwFocusMeasure_Byte3 ,  0x4486,   0x0000 },
+ {   AutoFocusMeasureData_udwPrevFocusMeasure_Byte0 ,  0x4488,   0x0000 },
+@@ -4774,24 +6815,33 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusMeasureData_udwCurrentFocusMeasureDifference_Byte3 ,  0x44e6,   0x0000 },
+ {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte0 ,  0x44e8,   0x0000 },
  {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte1 ,  0x44ea,   0x0000 },
  {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte2 ,  0x44ec,   0x0000 },
  {   AutoFocusMeasureData_udwOldTrackingFocusMeasure_Byte3 ,  0x44ee,   0x0000 },
@@ -4441,7 +5016,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusWeightControls_bWeight_0 ,  0x4500,   0x0000 },
  {   AutoFocusWeightControls_bWeight_1 ,  0x4502,   0x0000 },
  {   AutoFocusWeightControls_bWeight_2 ,  0x4504,   0x0000 },
-@@ -4783,6 +6827,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusWeightControls_bWeight_3 ,  0x4506,   0x0000 },
  {   AutoFocusWeightControls_bWeight_4 ,  0x4508,   0x0000 },
  {   AutoFocusWeightControls_bWeight_5 ,  0x450a,   0x0000 },
  {   AutoFocusWeightControls_bWeight_6 ,  0x450c,   0x0000 },
@@ -4451,7 +5026,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusDynamicWeight_bWeight_0 ,  0x4580,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_1 ,  0x4582,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_2 ,  0x4584,   0x0000 },
-@@ -4790,6 +6837,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusDynamicWeight_bWeight_3 ,  0x4586,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_4 ,  0x4588,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_5 ,  0x458a,   0x0000 },
  {   AutoFocusDynamicWeight_bWeight_6 ,  0x458c,   0x0000 },
@@ -4461,7 +5036,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusThresholds_uwCoarseThreshold_LSByte ,  0x4602,   0x0000 },
  {   AutoFocusThresholds_uwCoarseThreshold_MSByte ,  0x4601,   0x0000 },
  {   AutoFocusThresholds_uwFineThreshold_LSByte ,  0x4606,   0x0000 },
-@@ -4806,6 +6856,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThresholds_uwFineThreshold_MSByte ,  0x4605,   0x0000 },
+ {   AutoFocusThresholds_uwBeforeMotionBlur_LSByte ,  0x460a,   0x0000 },
+@@ -4804,10 +6854,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThresholds_udwCurrentVariation_Byte3 ,  0x4616,   0x0000 },
+ {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte0 ,  0x4618,   0x0000 },
  {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte1 ,  0x461a,   0x0000 },
  {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte2 ,  0x461c,   0x0000 },
  {   AutoFocusThresholds_udwLowFocusMeasureValue_Byte3 ,  0x461e,   0x0000 },
@@ -4471,7 +5050,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusHeuristicConstants_uwLensPositionInputMax_LSByte ,  0x4682,   0x0000 },
  {   AutoFocusHeuristicConstants_uwLensPositionInputMax_MSByte ,  0x4681,   0x0000 },
  {   AutoFocusHeuristicConstants_uwLensPositionInputMin_LSByte ,  0x4686,   0x0000 },
-@@ -4822,6 +6875,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusHeuristicConstants_uwLensPositionInputMin_MSByte ,  0x4685,   0x0000 },
+ {   AutoFocusHeuristicConstants_bBrightnessInputMax ,  0x4688,   0x0000 },
+@@ -4820,10 +6873,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusHeuristicConstants_uwFineToCoarseMax_MSByte ,  0x4695,   0x0000 },
+ {   AutoFocusHeuristicConstants_uwFineToCoarseMin_LSByte ,  0x469a,   0x0000 },
  {   AutoFocusHeuristicConstants_uwFineToCoarseMin_MSByte ,  0x4699,   0x0000 },
  {   AutoFocusHeuristicConstants_bHighToMaxFMShiftFactor ,  0x469c,   0x0000 },
  {   AutoFocusHeuristicConstants_bLowToHighFMShiftFactor ,  0x469e,   0x0000 },
@@ -4481,7 +5064,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte0 ,  0x4700,   0x0000 },
  {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte1 ,  0x4702,   0x0000 },
  {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte2 ,  0x4704,   0x0000 },
-@@ -4837,19 +6893,31 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInputMax_Byte3 ,  0x4706,   0x0000 },
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInputMin_Byte0 ,  0x4708,   0x0000 },
+@@ -4835,23 +6891,35 @@ struct nomadik_vpip_param vpip_default_p
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte2 ,  0x4714,   0x0000 },
+ {   AutoFocusThHeuristicInput_udwFocusMeasureInput_Byte3 ,  0x4716,   0x0000 },
  {   AutoFocusThHeuristicInput_uwLensPositionInput_LSByte ,  0x471a,   0x0000 },
  {   AutoFocusThHeuristicInput_uwLensPositionInput_MSByte ,  0x4719,   0x0000 },
  {   AutoFocusThHeuristicInput_bBrightnessInput ,  0x471c,   0x0000 },
@@ -4515,7 +5102,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MiscPageElements_fEnableIntelligentFlash ,  0x4904,   0x0000 },
  {   MiscPageElements_fEligibleFrameForMetering ,  0x4906,   0x0000 },
  {   MiscPageElements_fFlashGunIlluminatedFrameStreamed ,  0x4908,   0x0000 },
-@@ -4863,7 +6931,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   MiscPageElements_VpipCut ,  0x490a,   0x0000 },
+ {   MiscPageElements_bGPIOClockFrequency_Mhz ,  0x490c,   0x0000 },
+@@ -4861,42 +6929,60 @@ struct nomadik_vpip_param vpip_default_p
+ {   MiscPageElements_fEnableDelayWhenStoppingSensor ,  0x4914,   0x0000 },
+ {   MiscPageElements_fTriggerFlashOnStreaming ,  0x4916,   0x0000 },
  {   MiscPageElements_fDoNotOutputFrameInIntelligentFlash ,  0x4918,   0x0000 },
  {   MiscPageElements_fDisableToshibaInit ,  0x491a,   0x0000 },
  {   MiscPageElements_bNumberofFramesTobeSkippedByRx ,  0x491c,   0x0000 },
@@ -4529,7 +5120,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   MasterI2cClockControl_bCountFall ,  0x4a00,   0x0000 },
  {   MasterI2cClockControl_bCountRise ,  0x4a02,   0x0000 },
  {   MasterI2cClockControl_bCountHigh ,  0x4a04,   0x0000 },
-@@ -4873,6 +6947,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   MasterI2cClockControl_bCountBuffer ,  0x4a06,   0x0000 },
+ {   MasterI2cClockControl_bCountHoldData ,  0x4a08,   0x0000 },
+ {   MasterI2cClockControl_bCountSetupData ,  0x4a0a,   0x0000 },
  {   MasterI2cClockControl_bCountHoldStart ,  0x4a0c,   0x0000 },
  {   MasterI2cClockControl_bCountSetupStart ,  0x4a0e,   0x0000 },
  {   MasterI2cClockControl_bCountSetupStop ,  0x4a10,   0x0000 },
@@ -4539,7 +5132,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrFOVCtrl_bShiftCenter ,  0x4a80,   0x0000 },
  {   ZoomMgrFOVCtrl_uwXOrigin_LSByte ,  0x4a84,   0x0000 },
  {   ZoomMgrFOVCtrl_uwXOrigin_MSByte ,  0x4a83,   0x0000 },
-@@ -4881,11 +6958,17 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrFOVCtrl_uwYOrigin_LSByte ,  0x4a88,   0x0000 },
+ {   ZoomMgrFOVCtrl_uwYOrigin_MSByte ,  0x4a87,   0x0000 },
  {   ZoomMgrFOVCtrl_fRestrictMaxFOVToChosenFOV ,  0x4a8a,   0x0000 },
  {   ZoomMgrFOVCtrl_fCalculateMinFOVAlways ,  0x4a8c,   0x0000 },
  {   ZoomMgrFOVCtrl_fInhibitMaxFOVAtModeStaticChange ,  0x4a8e,   0x0000 },
@@ -4557,7 +5151,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ZoomMgrStripeCtrl_bStripeControl ,  0x4b80,   0x0000 },
  {   ZoomMgrStripeCtrl_uwStripeStartAddr_LSByte ,  0x4b84,   0x0000 },
  {   ZoomMgrStripeCtrl_uwStripeStartAddr_MSByte ,  0x4b83,   0x0000 },
-@@ -4895,6 +6978,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   ZoomMgrStripeCtrl_uwStripeSize_LSByte ,  0x4b88,   0x0000 },
+ {   ZoomMgrStripeCtrl_uwStripeSize_MSByte ,  0x4b87,   0x0000 },
+ {   ZoomMgrStripeCtrl_uwStripeInMinLineSize_LSByte ,  0x4b8c,   0x0000 },
  {   ZoomMgrStripeCtrl_uwStripeInMinLineSize_MSByte ,  0x4b8b,   0x0000 },
  {   ZoomMgrStripeCtrl_uwBmsFrameLength_LSByte ,  0x4b90,   0x0000 },
  {   ZoomMgrStripeCtrl_uwBmsFrameLength_MSByte ,  0x4b8f,   0x0000 },
@@ -4567,7 +5163,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   LftStripeParam_uwGPSISize_LSByte ,  0x4c02,   0x0000 },
  {   LftStripeParam_uwGPSISize_MSByte ,  0x4c01,   0x0000 },
  {   LftStripeParam_uwGPSOSize_LSByte ,  0x4c06,   0x0000 },
-@@ -4915,6 +7001,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   LftStripeParam_uwGPSOSize_MSByte ,  0x4c05,   0x0000 },
+ {   LftStripeParam_uwRightBorder_LSByte ,  0x4c0a,   0x0000 },
+@@ -4913,10 +6999,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   LftStripeParam_uwStripeInCropSize_MSByte ,  0x4c1d,   0x0000 },
+ {   LftStripeParam_uwStripeOutCropStart_LSByte ,  0x4c22,   0x0000 },
  {   LftStripeParam_uwStripeOutCropStart_MSByte ,  0x4c21,   0x0000 },
  {   LftStripeParam_uwStripeOutCropSize_LSByte ,  0x4c26,   0x0000 },
  {   LftStripeParam_uwStripeOutCropSize_MSByte ,  0x4c25,   0x0000 },
@@ -4577,7 +5177,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   RgtStripeParam_uwGPSISize_LSByte ,  0x4c82,   0x0000 },
  {   RgtStripeParam_uwGPSISize_MSByte ,  0x4c81,   0x0000 },
  {   RgtStripeParam_uwGPSOSize_LSByte ,  0x4c86,   0x0000 },
-@@ -4935,6 +7024,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   RgtStripeParam_uwGPSOSize_MSByte ,  0x4c85,   0x0000 },
+ {   RgtStripeParam_uwRightBorder_LSByte ,  0x4c8a,   0x0000 },
+@@ -4933,34 +7022,70 @@ struct nomadik_vpip_param vpip_default_p
+ {   RgtStripeParam_uwStripeInCropSize_MSByte ,  0x4c9d,   0x0000 },
+ {   RgtStripeParam_uwStripeOutCropStart_LSByte ,  0x4ca2,   0x0000 },
  {   RgtStripeParam_uwStripeOutCropStart_MSByte ,  0x4ca1,   0x0000 },
  {   RgtStripeParam_uwStripeOutCropSize_LSByte ,  0x4ca6,   0x0000 },
  {   RgtStripeParam_uwStripeOutCropSize_MSByte ,  0x4ca5,   0x0000 },
@@ -4587,7 +5191,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   DigitalGainStatus_uwCodedGreen1Gain_LSByte ,  0x4d02,   0x0000 },
  {   DigitalGainStatus_uwCodedGreen1Gain_MSByte ,  0x4d01,   0x0000 },
  {   DigitalGainStatus_uwCodedRedGain_LSByte ,  0x4d06,   0x0000 },
-@@ -4943,10 +7035,16 @@ struct nomadik_vpip_param vpip_default_p
+ {   DigitalGainStatus_uwCodedRedGain_MSByte ,  0x4d05,   0x0000 },
+ {   DigitalGainStatus_uwCodedBlueGain_LSByte ,  0x4d0a,   0x0000 },
  {   DigitalGainStatus_uwCodedBlueGain_MSByte ,  0x4d09,   0x0000 },
  {   DigitalGainStatus_uwCodedGreen2Gain_LSByte ,  0x4d0e,   0x0000 },
  {   DigitalGainStatus_uwCodedGreen2Gain_MSByte ,  0x4d0d,   0x0000 },
@@ -4604,7 +5209,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AntiFlickerExposureStatus_fpFlickerFreePeriod_us_LSByte ,  0x4e02,   0x0000 },
  {   AntiFlickerExposureStatus_fpFlickerFreePeriod_us_MSByte ,  0x4e01,   0x0000 },
  {   AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_LSByte ,  0x4e06,   0x0000 },
-@@ -4955,10 +7053,37 @@ struct nomadik_vpip_param vpip_default_p
+ {   AntiFlickerExposureStatus_fpGainedFlickerFreeTimePeriod_us_MSByte ,  0x4e05,   0x0000 },
+ {   AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_LSByte ,  0x4e0a,   0x0000 },
  {   AntiFlickerExposureStatus_uwMaxFlickerFreeBunches_MSByte ,  0x4e09,   0x0000 },
  {   AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_LSByte ,  0x4e0e,   0x0000 },
  {   AntiFlickerExposureStatus_fpConstrainedFlickerFreePeriod_us_MSByte ,  0x4e0d,   0x0000 },
@@ -4642,7 +5248,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_LSByte ,  0x5002,   0x0000 },
  {   SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte ,  0x5001,   0x043f },
  {   SensorSetupFarSensor_uwMinimumSensorRxPixelValue_LSByte ,  0x5006,   0x0000 },
-@@ -4972,6 +7097,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte ,  0x5005,   0x0004 },
+ {   SensorSetupFarSensor_uwMaximumSensorRxPixelValue_LSByte ,  0x500a,   0x0000 },
+@@ -4970,10 +7095,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupFarSensor_fpGreenTiltGain_LSByte ,  0x5012,   0x0000 },
+ {   SensorSetupFarSensor_fpGreenTiltGain_MSByte ,  0x5011,   0x3e00 },
  {   SensorSetupFarSensor_fpBlueTiltGain_LSByte ,  0x5016,   0x0000 },
  {   SensorSetupFarSensor_fpBlueTiltGain_MSByte ,  0x5015,   0x3e00 },
  {   SensorSetupFarSensor_BlackCorrectionOffset ,  0x5018,   0x0000 },
@@ -4652,7 +5262,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_LSByte ,  0x5082,   0x0000 },
  {   SensorSetupNearSensor_uwGuaranteedDataSaturationLevel_MSByte ,  0x5081,   0x0000 },
  {   SensorSetupNearSensor_uwMinimumSensorRxPixelValue_LSByte ,  0x5086,   0x0000 },
-@@ -4985,6 +7113,9 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupNearSensor_uwMinimumSensorRxPixelValue_MSByte ,  0x5085,   0x0000 },
+ {   SensorSetupNearSensor_uwMaximumSensorRxPixelValue_LSByte ,  0x508a,   0x0000 },
+@@ -4983,10 +7111,13 @@ struct nomadik_vpip_param vpip_default_p
+ {   SensorSetupNearSensor_fpGreenTiltGain_LSByte ,  0x5092,   0x0000 },
+ {   SensorSetupNearSensor_fpGreenTiltGain_MSByte ,  0x5091,   0x0000 },
  {   SensorSetupNearSensor_fpBlueTiltGain_LSByte ,  0x5096,   0x0000 },
  {   SensorSetupNearSensor_fpBlueTiltGain_MSByte ,  0x5095,   0x0000 },
  {   SensorSetupNearSensor_BlackCorrectionOffset ,  0x5098,   0x0000 },
@@ -4662,7 +5276,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ToshibaOtpRead_otp_inf_2 ,  0x5100,   0x0000 },
  {   ToshibaOtpRead_otp_inf_1 ,  0x5102,   0x0000 },
  {   ToshibaOtpRead_otp_inf_0 ,  0x5104,   0x0000 },
-@@ -4996,8 +7127,24 @@ struct nomadik_vpip_param vpip_default_p
+ {   ToshibaOtpRead_otp_mac_2 ,  0x5106,   0x0000 },
+ {   ToshibaOtpRead_otp_mac_1 ,  0x5108,   0x0000 },
+@@ -4994,20 +7125,71 @@ struct nomadik_vpip_param vpip_default_p
+ {   ToshibaOtpRead_otp_posA_1 ,  0x510c,   0x0000 },
+ {   ToshibaOtpRead_otp_posA_0 ,  0x510e,   0x0000 },
  {   ToshibaOtpRead_otp_posB_1 ,  0x5110,   0x0000 },
  {   ToshibaOtpRead_otp_posB_0 ,  0x5112,   0x0000 },
  {   ToshibaOtpRead_otp_register_map_ver ,  0x5114,   0x0000 },
@@ -4687,7 +5305,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ReferenceIlluminantCasts_fpCAST0_LSByte ,  0x5202,   0x0000 },
  {   ReferenceIlluminantCasts_fpCAST0_MSByte ,  0x5201,   0x38b8 },
  {   ReferenceIlluminantCasts_fpCAST1_LSByte ,  0x5206,   0x0000 },
-@@ -5006,6 +7153,41 @@ struct nomadik_vpip_param vpip_default_p
+ {   ReferenceIlluminantCasts_fpCAST1_MSByte ,  0x5205,   0x396d },
+ {   ReferenceIlluminantCasts_fpCAST2_LSByte ,  0x520a,   0x0000 },
  {   ReferenceIlluminantCasts_fpCAST2_MSByte ,  0x5209,   0x3a1b },
  {   ReferenceIlluminantCasts_fpCAST3_LSByte ,  0x520e,   0x0000 },
  {   ReferenceIlluminantCasts_fpCAST3_MSByte ,  0x520d,   0x3af2 },
@@ -4729,7 +5348,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_B_bAvUnityOffset_Day ,  0x5280,   0x0040 },
  {   AdaptiveAVParameter_B_bAvCoeffR2_Day ,  0x5282,   0x003e },
  {   AdaptiveAVParameter_B_bAvCoeffR4_Day ,  0x5284,   0x00e8 },
-@@ -5034,6 +7216,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_B_wAvHOffset_Day_LSByte ,  0x5288,   0x0000 },
+ {   AdaptiveAVParameter_B_wAvHOffset_Day_MSByte ,  0x5287,   0x0003 },
+@@ -5032,10 +7214,42 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_B_bAvCoeffR4_HOR ,  0x52ae,   0x00f0 },
+ {   AdaptiveAVParameter_B_wAvHOffset_HOR_LSByte ,  0x52b2,   0x0000 },
  {   AdaptiveAVParameter_B_wAvHOffset_HOR_MSByte ,  0x52b1,   0x000b },
  {   AdaptiveAVParameter_B_wAvVOffset_HOR_LSByte ,  0x52b6,   0x0000 },
  {   AdaptiveAVParameter_B_wAvVOffset_HOR_MSByte ,  0x52b5,   0x001d },
@@ -4768,7 +5391,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_GB_bAvUnityOffset_Day ,  0x5300,   0x0040 },
  {   AdaptiveAVParameter_GB_bAvCoeffR2_Day ,  0x5302,   0x0047 },
  {   AdaptiveAVParameter_GB_bAvCoeffR4_Day ,  0x5304,   0x00ec },
-@@ -5062,6 +7276,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GB_wAvHOffset_Day_LSByte ,  0x5308,   0x0000 },
+ {   AdaptiveAVParameter_GB_wAvHOffset_Day_MSByte ,  0x5307,   0x000a },
+@@ -5060,10 +7274,43 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GB_bAvCoeffR4_HOR ,  0x532e,   0x00f0 },
+ {   AdaptiveAVParameter_GB_wAvHOffset_HOR_LSByte ,  0x5332,   0x0000 },
  {   AdaptiveAVParameter_GB_wAvHOffset_HOR_MSByte ,  0x5331,   0x000c },
  {   AdaptiveAVParameter_GB_wAvVOffset_HOR_LSByte ,  0x5336,   0x0000 },
  {   AdaptiveAVParameter_GB_wAvVOffset_HOR_MSByte ,  0x5335,   0x0014 },
@@ -4808,7 +5435,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_GR_bAvUnityOffset_Day ,  0x5380,   0x0040 },
  {   AdaptiveAVParameter_GR_bAvCoeffR2_Day ,  0x5382,   0x0048 },
  {   AdaptiveAVParameter_GR_bAvCoeffR4_Day ,  0x5384,   0x00e8 },
-@@ -5090,6 +7337,38 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GR_wAvHOffset_Day_LSByte ,  0x5388,   0x0000 },
+ {   AdaptiveAVParameter_GR_wAvHOffset_Day_MSByte ,  0x5387,   0x0009 },
+@@ -5088,10 +7335,42 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_GR_bAvCoeffR4_HOR ,  0x53ae,   0x00ef },
+ {   AdaptiveAVParameter_GR_wAvHOffset_HOR_LSByte ,  0x53b2,   0x0000 },
  {   AdaptiveAVParameter_GR_wAvHOffset_HOR_MSByte ,  0x53b1,   0x000c },
  {   AdaptiveAVParameter_GR_wAvVOffset_HOR_LSByte ,  0x53b6,   0x0000 },
  {   AdaptiveAVParameter_GR_wAvVOffset_HOR_MSByte ,  0x53b5,   0x0001 },
@@ -4847,7 +5478,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   AdaptiveAVParameter_R_bAvUnityOffset_Day ,  0x5400,   0x0040 },
  {   AdaptiveAVParameter_R_bAvCoeffR2_Day ,  0x5402,   0x0067 },
  {   AdaptiveAVParameter_R_bAvCoeffR4_Day ,  0x5404,   0x00f6 },
-@@ -5118,17 +7397,39 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_R_wAvHOffset_Day_LSByte ,  0x5408,   0x0000 },
+ {   AdaptiveAVParameter_R_wAvHOffset_Day_MSByte ,  0x5407,   0x000a },
+@@ -5116,21 +7395,43 @@ struct nomadik_vpip_param vpip_default_p
+ {   AdaptiveAVParameter_R_bAvCoeffR4_HOR ,  0x542e,   0x00f7 },
+ {   AdaptiveAVParameter_R_wAvHOffset_HOR_LSByte ,  0x5432,   0x0000 },
  {   AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte ,  0x5431,   0x000a },
  {   AdaptiveAVParameter_R_wAvVOffset_HOR_LSByte ,  0x5436,   0x0000 },
  {   AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte ,  0x5435,   0x0004 },
@@ -4887,7 +5522,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   DynamicConstrainedWBControls_fpRedA_LSByte ,  0x5582,   0x0000 },
  {   DynamicConstrainedWBControls_fpRedA_MSByte ,  0x5581,   0x3881 },
  {   DynamicConstrainedWBControls_fpBlueA_LSByte ,  0x5586,   0x0000 },
-@@ -5140,6 +7441,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   DynamicConstrainedWBControls_fpBlueA_MSByte ,  0x5585,   0x3c68 },
+ {   DynamicConstrainedWBControls_fpDamperLowThreshold_LSByte ,  0x558a,   0x0000 },
+@@ -5138,10 +7439,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   DynamicConstrainedWBControls_fpMinimumDamperOutput_LSByte ,  0x558e,   0x0000 },
+ {   DynamicConstrainedWBControls_fpMinimumDamperOutput_MSByte ,  0x558d,   0x3a66 },
  {   DynamicConstrainedWBControls_fpDamperHighThreshold_LSByte ,  0x5592,   0x0000 },
  {   DynamicConstrainedWBControls_fpDamperHighThreshold_MSByte ,  0x5591,   0x5a71 },
  {   DynamicConstrainedWBControls_fDamperDisable ,  0x5594,   0x0000 },
@@ -4896,7 +5535,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   Toshiba_AF_NVM_Read_NVM_Far2Near_inf_LSByte ,  0x5602,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Far2Near_inf_MSByte ,  0x5601,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Near2Far_inf_LSByte ,  0x5606,   0x0000 },
-@@ -5152,6 +7455,23 @@ struct nomadik_vpip_param vpip_default_p
+ {   Toshiba_AF_NVM_Read_NVM_Near2Far_inf_MSByte ,  0x5605,   0x0000 },
+ {   Toshiba_AF_NVM_Read_NVM_Far2Near_mac_LSByte ,  0x560a,   0x0000 },
+@@ -5150,27 +7453,81 @@ struct nomadik_vpip_param vpip_default_p
+ {   Toshiba_AF_NVM_Read_NVM_Near2Far_mac_MSByte ,  0x560d,   0x0000 },
+ {   Toshiba_AF_NVM_Read_NVM_Pos_A_LSByte ,  0x5612,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Pos_A_MSByte ,  0x5611,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Pos_B_LSByte ,  0x5616,   0x0000 },
  {   Toshiba_AF_NVM_Read_NVM_Pos_B_MSByte ,  0x5615,   0x0000 },
@@ -4920,7 +5563,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   Toshiba_Vcm_Parameters_wLowLevelMacroPos_LSByte ,  0x5682,   0x0000 },
  {   Toshiba_Vcm_Parameters_wLowLevelMacroPos_MSByte ,  0x5681,   0x0000 },
  {   Toshiba_Vcm_Parameters_wLowLevelInfinityPos_LSByte ,  0x5686,   0x0000 },
-@@ -5162,13 +7482,50 @@ struct nomadik_vpip_param vpip_default_p
+ {   Toshiba_Vcm_Parameters_wLowLevelInfinityPos_MSByte ,  0x5685,   0x0000 },
+ {   Toshiba_Vcm_Parameters_bSlewControlModeEnable ,  0x5688,   0x0000 },
+ {   Toshiba_Vcm_Parameters_bSlewModeForSmallerStep ,  0x568a,   0x0001 },
+ {   Toshiba_Vcm_Parameters_bSlewRateForSmallerStep ,  0x568c,   0x0004 },
  {   Toshiba_Vcm_Parameters_bSlewModeForLargerStep ,  0x568e,   0x0008 },
  {   Toshiba_Vcm_Parameters_bSlewRateForLargerStep ,  0x5690,   0x0007 },
  {   Toshiba_Vcm_Parameters_bThresholdStepSize ,  0x5692,   0x00b0 },
@@ -4971,7 +5617,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine1_ColourMatrixFarSensor_fpRInR_LSByte ,  0x5802,   0x0000 },
  {   ColourEngine1_ColourMatrixFarSensor_fpRInR_MSByte ,  0x5801,   0x3f0c },
  {   ColourEngine1_ColourMatrixFarSensor_fpGInR_LSByte ,  0x5806,   0x0000 },
-@@ -5187,6 +7544,8 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixFarSensor_fpGInR_MSByte ,  0x5805,   0xb887 },
+ {   ColourEngine1_ColourMatrixFarSensor_fpBInR_LSByte ,  0x580a,   0x0000 },
+@@ -5185,10 +7542,12 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixFarSensor_fpRInB_MSByte ,  0x5819,   0xbc6e },
+ {   ColourEngine1_ColourMatrixFarSensor_fpGInB_LSByte ,  0x581e,   0x0000 },
  {   ColourEngine1_ColourMatrixFarSensor_fpGInB_MSByte ,  0x581d,   0xc01b },
  {   ColourEngine1_ColourMatrixFarSensor_fpBInB_LSByte ,  0x5822,   0x0000 },
  {   ColourEngine1_ColourMatrixFarSensor_fpBInB_MSByte ,  0x5821,   0x41b7 },
@@ -4980,7 +5630,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ColourEngine1_ColourMatrixNearSensor_fpRInR_LSByte ,  0x5882,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpRInR_MSByte ,  0x5881,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpGInR_LSByte ,  0x5886,   0x0000 },
-@@ -5205,8 +7564,30 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixNearSensor_fpGInR_MSByte ,  0x5885,   0x0000 },
+ {   ColourEngine1_ColourMatrixNearSensor_fpBInR_LSByte ,  0x588a,   0x0000 },
+@@ -5203,31 +7562,63 @@ struct nomadik_vpip_param vpip_default_p
+ {   ColourEngine1_ColourMatrixNearSensor_fpRInB_MSByte ,  0x5899,   0x0000 },
+ {   ColourEngine1_ColourMatrixNearSensor_fpGInB_LSByte ,  0x589e,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpGInB_MSByte ,  0x589d,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpBInB_LSByte ,  0x58a2,   0x0000 },
  {   ColourEngine1_ColourMatrixNearSensor_fpBInB_MSByte ,  0x58a1,   0x0000 },
@@ -5011,7 +5665,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  {   ToshibaTechnicalParamTuner_uwHostLevelMacroPos_LSByte ,  0x5982,   0x0000 },
  {   ToshibaTechnicalParamTuner_uwHostLevelMacroPos_MSByte ,  0x5981,   0x0000 },
  {   ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_LSByte ,  0x5986,   0x0000 },
-@@ -5216,16 +7597,26 @@ struct nomadik_vpip_param vpip_default_p
+ {   ToshibaTechnicalParamTuner_uwHostLevelInfinityPos_MSByte ,  0x5985,   0x0000 },
+ {   ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_LSByte ,  0x598a,   0x0000 },
+ {   ToshibaTechnicalParamTuner_uwDefAFMaxStandardRange_um_MSByte ,  0x5989,   0x012c },
  {   ToshibaTechnicalParamTuner_bDefFineStepParam_um ,  0x598c,   0x0008 },
  {   ToshibaTechnicalParamTuner_bDefCoarseStepParam_um ,  0x598e,   0x0030 },
  {   ToshibaTechnicalParamTuner_fHostDefTechParam ,  0x5990,   0x0002 },
@@ -5040,7 +5696,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  int sva_vpip_auto_focus(struct sva_device_open *open, struct vpip_autofocus_id *mode)
  {
  
-@@ -6234,63 +8625,12 @@ static int irp_start_fw(struct sva_servi
+ struct sva_service_open *srv_open;
+ u16 vpip_state=0;
+@@ -6232,67 +8623,16 @@ static int irp_start_fw(struct sva_servi
+       IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[VfpnControls_bLogThreshLog].addr,vpip_default_params[VfpnControls_bLogThreshLog].val));// 0x4));
+       IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[AntiFlickerExposureControls_bMainsFrequency_Hz].addr,vpip_default_params[AntiFlickerExposureControls_bMainsFrequency_Hz].val));// 0x32));
  
  
  
@@ -5105,7 +5765,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
  
                        /**
                        Update only configuration registers
-@@ -6310,6 +8650,7 @@ static int irp_start_fw(struct sva_servi
+                       */
+                                 case    PipeSetupBankB_fCb_Cr_Flip                                                        :
+@@ -6308,10 +8648,11 @@ static int irp_start_fw(struct sva_servi
+                                 case    SensorCapabilitiesFarSensor_uwSensorAnalogGainMaximum_MSByte                      :
+                                 case    SensorCapabilitiesFarSensor_uwSensorDataPedestal_MSByte                                                                                                                                                                                                                                                                     :
                                  case    SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMinimum_MSByte                  :
                                  case    SensorCapabilitiesCurrentSensor_uwSensorAnalogGainMaximum_MSByte                                                                                                                                                                                                                                              :
                                  case    FlashManagerControl_bMode                                                         :
@@ -5113,7 +5777,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    FlashManagerControl_bFlashType                                                    :
                                  case    FlashManagerControl_fOrMainAndPreFlashPulse                                       :
                                  case    FlashManagerControl_RefPointCalcMode                                              :
-@@ -6327,8 +8668,6 @@ static int irp_start_fw(struct sva_servi
+                                 case    FlashManagerControl_wIntegrationStartPosition_MSByte                              :
+                                 case    FlashManagerControl_fOverrideIntegrationStartPosition                             :
+@@ -6325,12 +8666,10 @@ static int irp_start_fw(struct sva_servi
+                                 case    FlashManagerControl_wMainFlashStartLine_MSByte                                    :
+                                 case    FlashManagerControl_wMainFlashStartPixel_MSByte                                   :
                                  case    FlashManagerControl_cPreFlashStartFrame                                           :
                                  case    FlashManagerControl_wPreFlashStartLine_MSByte                                     :
                                  case    FlashManagerControl_wPreFlashStartPixel_MSByte                                    :
@@ -5122,7 +5790,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    FlashManagerControl_bTotalFramesRequired                                                                                                                                                                                                                                                       :
                                  case    ExposureControls_bMode                                                            :
                                  case    ExposureControls_bMetering                                                        :
-@@ -6348,6 +8687,8 @@ static int irp_start_fw(struct sva_servi
+                                 case    ExposureControls_fpColdStartDesiredTime_us_MSByte                                 :
+                                 case    ExposureControls_iExposureCompensation                                            :
+@@ -6346,10 +8685,12 @@ static int irp_start_fw(struct sva_servi
+                                 case    ExposureControls_fEnableHighClipForDesiredExposureTime                            :
+                                 case    ExposureControls_bAntiFlickerMode                                                 :
                                  case    ExposureControls_fInhibitExposurePresetModeForFlash                                                                                                                                                                                                                                                        :
                                  case    ExposureAlgorithmControls_fpDigitalGainFloor_MSByte                               :
                                  case    ExposureAlgorithmControls_fpDigitalGainCeiling_MSByte                                                                                                                                                                                                                                                              :
@@ -5131,7 +5803,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    WhiteBalanceControls_bMode                                                        :
                                  case    WhiteBalanceControls_bManualRedGain                                               :
                                  case    WhiteBalanceControls_bManualGreenGain                                             :
-@@ -6376,8 +8717,9 @@ static int irp_start_fw(struct sva_servi
+                                 case    WhiteBalanceControls_bManualBlueGain                                              :
+                                 case    WhiteBalanceControls_bMiscSettings                                                :
+@@ -6374,12 +8715,13 @@ static int irp_start_fw(struct sva_servi
+                                 case    AutomaticFrameRateControl_bUserMaximumFrameRate_Hz                                :
+                                 case    AutomaticFrameRateControl_bRelativeChange_num                                     :
                                  case    AutomaticFrameRateControl_bRelativeChange_den                                     :
                                  case    AutomaticFrameRateControl_fDivorceMinFrameRateFromMaxIntegration                                                                                                                                                                                                                                                 :
  
@@ -5142,7 +5818,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    ColourEngine0_ColourMatrixFarSensor_fpRInR_MSByte                                 :
                                  case    ColourEngine0_ColourMatrixFarSensor_fpGInR_MSByte                                 :
                                  case    ColourEngine0_ColourMatrixFarSensor_fpBInR_MSByte                                 :
-@@ -6421,6 +8763,7 @@ static int irp_start_fw(struct sva_servi
+                                 case    ColourEngine0_ColourMatrixFarSensor_fpRInG_MSByte                                 :
+                                 case    ColourEngine0_ColourMatrixFarSensor_fpGInG_MSByte                                 :
+@@ -6419,10 +8761,11 @@ static int irp_start_fw(struct sva_servi
+                                 case    ColourEngine0_GammaCorrection_SharpBlue                                           :
+                                 case    ColourEngine0_GammaCorrection_SoftRed                                             :
                                  case    ColourEngine0_GammaCorrection_SoftGreen                                           :
                                  case    ColourEngine0_GammaCorrection_SoftBlue                                                                                                                                                                                                                                                                     :
  
@@ -5150,7 +5830,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    NoraControls_fDisable                                                             :
                                  case    NoraControls_fDisableNoraPromoting                                                :
                                  case    NoraControls_bMaximumValue                                                        :
-@@ -6442,6 +8785,8 @@ static int irp_start_fw(struct sva_servi
+                                 case    NoraControls_fDifferentTextureDegreeForBlue                                       :
+                                 case    NoraControls_fSplitNoiseLevel                                                     :
+@@ -6440,10 +8783,12 @@ static int irp_start_fw(struct sva_servi
+                                 case    ScytheFilterControls_fpDamperLowThresholdHigh_MSByte                              :
+                                 case    ScytheFilterControls_fpDamperHighThresholdLow_MSByte                              :
                                  case    ScytheFilterControls_fpDamperHighThresholdHigh_MSByte                             :
                                  case    ScytheFilterControls_fpMinimumDamperOutputLow_MSByte                              :
                                  case    ScytheFilterControls_fpMinimumDamperOutputHigh_MSByte                                                                                                                                                                                                                                                   :
@@ -5159,7 +5843,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    JackFilterControls_fDisableFilter                                                 :
                                  case    JackFilterControls_fSquareLaw                                                     :
                                  case    JackFilterControls_fDisablePromotingLow                                           :
-@@ -6454,6 +8799,11 @@ static int irp_start_fw(struct sva_servi
+                                 case    JackFilterControls_fDisablePromotingHigh                                          :
+                                 case    JackFilterControls_bMaxWeightLow                                                  :
+@@ -6452,10 +8797,15 @@ static int irp_start_fw(struct sva_servi
+                                 case    JackFilterControls_fpDamperLowThresholdHigh_MSByte                                :
+                                 case    JackFilterControls_fpDamperHighThresholdLow_MSByte                                :
                                  case    JackFilterControls_fpDamperHighThresholdHigh_MSByte                               :
                                  case    JackFilterControls_fpMinimumDamperOutputLow_MSByte                                :
                                  case    JackFilterControls_fpMinimumDamperOutputHigh_MSByte                                                                                                                                                                                                                                                     :
@@ -5171,7 +5859,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    AntiVignetteControls_fDisableFilter                                               :
                                  case    AntiVignetteControls_bFilterCoeff_R2_r                                            :
                                  case    AntiVignetteControls_bFilterCoeff_R2_gr                                           :
-@@ -6480,6 +8830,9 @@ static int irp_start_fw(struct sva_servi
+                                 case    AntiVignetteControls_bFilterCoeff_R2_gb                                           :
+                                 case    AntiVignetteControls_bFilterCoeff_R2_b                                            :
+@@ -6478,10 +8828,13 @@ static int irp_start_fw(struct sva_servi
+                                 case    AntiVignetteControls_bUnityOffset_r                                               :
+                                 case    AntiVignetteControls_bUnityOffset_gr                                              :
                                  case    AntiVignetteControls_bUnityOffset_gb                                              :
                                  case    AntiVignetteControls_bUnityOffset_b                                               :
                                  case    AntiVignetteControls_fAdaptiveAntiVignetteEnable                                                                                                                                                                                                                                                                                                     :
@@ -5181,7 +5873,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    ColourEngine0_RadialApertureCorrectionControl_fEnableCorrection                                                                                                                                                                                                                                                                                                                  :
                                  case    ColourEngine0_RadialApertureCorrectionHostInputs_bQvec0                           :
                                  case    ColourEngine0_RadialApertureCorrectionHostInputs_bQvec1                           :
-@@ -6497,6 +8850,7 @@ static int irp_start_fw(struct sva_servi
+                                 case    ColourEngine0_RadialApertureCorrectionHostInputs_bCofShift                        :
+                                 case    ColourEngine0_RadialApertureCorrectionHostInputs_bOutShift                        :
+@@ -6495,26 +8848,30 @@ static int irp_start_fw(struct sva_servi
+                                 case    ColourEngine0_CoderOutputSignalRange_uwChromaMidpointTimes2_MSByte                                                                                                                                                                                                                                                             :
+                                 case    ColourEngine0_FadeToBlack_fDisable                                                :
                                  case    ColourEngine0_FadeToBlack_fpBlackValue_MSByte                                     :
                                  case    ColourEngine0_FadeToBlack_fpDamperLowThreshold_MSByte                             :
                                  case    ColourEngine0_FadeToBlack_fpDamperHighThreshold_MSByte                                                                                                                                                                                                                                                                    :
@@ -5189,7 +5885,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    WhiteBalanceConstrainerControls_fpRedB_MSByte                                     :
                                  case    WhiteBalanceConstrainerControls_fpBlueB_MSByte                                    :
                                  case    WhiteBalanceConstrainerControls_fpMaximumDistanceAllowedFromLocus_MSByte          :
-@@ -6504,6 +8858,8 @@ static int irp_start_fw(struct sva_servi
+                                 case    WhiteBalanceConstrainerControls_fEnableConstrainedWhiteBalance                                                                                                                                                                                                                                                        :
                                  case    WhiteBalanceGainLimit_fpWhiteBalanceGainLimit_MSByte                                                                                                                                                                                                                                                              :
                                  case    FLADriverLowLevelParameters_bFramesToSkip                                         :
  
@@ -5198,7 +5894,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    FocusRangeConstants_wFullRange_LensMinPosition_MSByte                             :
                                  case    FocusRangeConstants_wFullRange_LensMaxPosition_MSByte                             :
                                  case    FocusRangeConstants_wFullRange_LensRecoveryPosition_MSByte                        :
-@@ -6513,6 +8869,7 @@ static int irp_start_fw(struct sva_servi
+                                 case    FocusRangeConstants_wLandscape_LensMinPosition_MSByte                             :
+                                 case    FocusRangeConstants_wLandscape_LensMaxPosition_MSByte                             :
+                                 case    FocusRangeConstants_wLandscape_LensRecoveryPosition_MSByte                        :
                                  case    FocusRangeConstants_wMacro_LensMinPosition_MSByte                                 :
                                  case    FocusRangeConstants_wMacro_LensMaxPosition_MSByte                                 :
                                  case    FocusRangeConstants_wMacro_LensRecoveryPosition_MSByte                                                                                                                                                                                                                                                :
@@ -5206,7 +5904,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    AutoFocusControls_fFMTesting_AutoDisable                                          :
                                  case    AutoFocusControls_fBackLight_Enable                                               :
                                  case    AutoFocusControls_fBackupSolution                                                 :
-@@ -6533,10 +8890,14 @@ static int irp_start_fw(struct sva_servi
+                                 case    AutoFocusControls_fCheckExposureStable_Enable                                     :
+                                 case    AutoFocusControls_fEnableSimpleCoarseThEvaluation                                 :
+@@ -6531,25 +8888,33 @@ static int irp_start_fw(struct sva_servi
+                                 case    AutoFocusControls_fEnableTrakingZoneVariation                                     :
+                                 case    AutoFocusControls_fEnableFunctionThresholdTest                                    :
                                  case    AutoFocusControls_fResetHCSPos                                                                                                                                                                                                                                                                       :
                                  case    AutoFocusConstants_bCoarseStep                                                    :
                                  case    AutoFocusConstants_bFineStep                                                                                                                                                                                                                                                                                  :
@@ -5221,7 +5923,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    SensorSetupFarSensor_uwGuaranteedDataSaturationLevel_MSByte                       :
                                  case    SensorSetupFarSensor_uwMinimumSensorRxPixelValue_MSByte                           :
                                  case    SensorSetupFarSensor_uwMaximumSensorRxPixelValue_MSByte                           :
-@@ -6544,10 +8905,14 @@ static int irp_start_fw(struct sva_servi
+                                 case    SensorSetupFarSensor_fpRedTiltGain_MSByte                                         :
                                  case    SensorSetupFarSensor_fpGreenTiltGain_MSByte                                       :
                                  case    SensorSetupFarSensor_fpBlueTiltGain_MSByte                                        :
                                  case    SensorSetupFarSensor_BlackCorrectionOffset                                                                                                                                                                                                                                                                    :
@@ -5236,7 +5938,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    AdaptiveAVParameter_B_bAvUnityOffset_Day                                          :
                                  case    AdaptiveAVParameter_B_bAvCoeffR2_Day                                              :
                                  case    AdaptiveAVParameter_B_bAvCoeffR4_Day                                              :
-@@ -6628,27 +8993,33 @@ static int irp_start_fw(struct sva_servi
+                                 case    AdaptiveAVParameter_B_wAvHOffset_Day_MSByte                                       :
+                                 case    AdaptiveAVParameter_B_wAvVOffset_Day_MSByte                                       :
+@@ -6626,31 +8991,37 @@ static int irp_start_fw(struct sva_servi
+                                 case    AdaptiveAVParameter_R_bAvUnityOffset_HOR                                          :
+                                 case    AdaptiveAVParameter_R_bAvCoeffR2_HOR                                              :
                                  case    AdaptiveAVParameter_R_bAvCoeffR4_HOR                                              :
                                  case    AdaptiveAVParameter_R_wAvHOffset_HOR_MSByte                                       :
                                  case    AdaptiveAVParameter_R_wAvVOffset_HOR_MSByte                                                                                                                                                                                                                                                                  :
@@ -5270,7 +5976,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                                  case    AdaptiveColourMatrix_fpNormalisedRedGain0_MSByte                                  :
                                  case    AdaptiveColourMatrix_fpNormalisedRedGain1_MSByte                                  :
                                  case    AdaptiveColourMatrix_bChooseAdaptiveColourMatrix:
-@@ -6667,6 +9038,9 @@ static int irp_start_fw(struct sva_servi
+                               IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[vpip_update_iteration].addr,vpip_default_params[vpip_update_iteration].val));// 0));
+@@ -6665,10 +9036,13 @@ static int irp_start_fw(struct sva_servi
+                               //IRP_ASSERT(irp_write_packet(srv_open, vpip_default_params[vpip_update_iteration].addr,vpip_default_params[vpip_update_iteration].val));// 0));
+                               break;
  
  
                                }
@@ -5280,7 +5990,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                }
  
  
-@@ -6681,6 +9055,8 @@ static int irp_start_fw(struct sva_servi
+@@ -6679,10 +9053,12 @@ static int irp_start_fw(struct sva_servi
  
  
  
@@ -5289,10 +6003,13 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
                /* debug: depict whether the firmware was able to talk to sensor */
        IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_fFarSensorAvailable].addr, &vpip_state));
        dbgprintk(1,"checking for SensorInformation=%d FAR sensor state \n", vpip_state);
-diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.c ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.c
---- linux-2.6.20/drivers/media/video/v4l2-nomadik.c    2008-11-24 14:06:24.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.c     2008-12-01 17:35:51.646833000 +0530
-@@ -38,7 +38,7 @@ MODULE_PARM_DESC(v4l2_nomadik_debug,"Deb
+       IRP_ASSERT(irp_read_packet(srv_open, vpip_default_params[SensorInformation_fNearSensorAvailable].addr, &vpip_state));
+       dbgprintk(1,"checking for SensorInformation=%d NEAR sensor state \n", vpip_state);
+--- linux-2.6.20.orig/drivers/media/video/v4l2-nomadik.c
++++ linux-2.6.20/drivers/media/video/v4l2-nomadik.c
+@@ -36,11 +36,11 @@ MODULE_PARM_DESC(v4l2_nomadik_debug,"Deb
+       } while(0)
  struct v4l2_sva_dev *dev;
  extern struct sva_device sva;
  static struct semaphore driver_mutex;
@@ -5301,3 +6018,5 @@ diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.c ../new/linux-2.6.20
  
  extern struct nomadik_vpip_param vpip_default_params[];//defined in nomadik_sva_vpip.c
  extern int VPIP_VERSION;
+ int sva_vpip_auto_focus(struct sva_device_open *open, struct vpip_autofocus_id *mode);
index 40c9c43..7ee8bb8 100644 (file)
-diff -Nauprw linux-2.6.20/arch/arm/common/rtctime.c ../new/linux-2.6.20/arch/arm/common/rtctime.c
---- linux-2.6.20/arch/arm/common/rtctime.c     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/common/rtctime.c      2007-11-21 11:51:41.000000000 +0530
-@@ -201,13 +201,13 @@ static int rtc_ioctl(struct inode *inode
-               }
-               alrm.enabled = 0;
-               alrm.pending = 0;
--              alrm.time.tm_mday = -1;
-+/*            alrm.time.tm_mday = -1;
-               alrm.time.tm_mon = -1;
-               alrm.time.tm_year = -1;
-               alrm.time.tm_wday = -1;
-               alrm.time.tm_yday = -1;
-               alrm.time.tm_isdst = -1;
--              ret = rtc_arm_set_alarm(ops, &alrm);
-+*/            ret = rtc_arm_set_alarm(ops, &alrm);
-               break;
+---
+ .gitignore                                                                    |   47 
+ Documentation/DocBook/Makefile                                                |    3 
+ Documentation/DocBook/kgdb.tmpl                                               |  234 
+ Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt                          |  111 
+ Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt                               |  106 
+ Documentation/arm/STM-Nomadik/debug_strategy.txt                              |   66 
+ Documentation/arm/STM-Nomadik/dma_user_guide.txt                              |  420 
+ Documentation/arm/STM-Nomadik/faqs.txt                                        |   53 
+ Documentation/arm/STM-Nomadik/gpio_user_guide.txt                             |  140 
+ Documentation/arm/STM-Nomadik/irq_usrguide.txt                                |  171 
+ Documentation/arm/STM-Nomadik/power_management.txt                            |  122 
+ MAINTAINERS                                                                   |    9 
+ Makefile                                                                      |   18 
+ arch/arm/Kconfig                                                              |   25 
+ arch/arm/Makefile                                                             |   34 
+ arch/arm/common/rtctime.c                                                     |    4 
+ arch/arm/configs/ndk10_defconfig                                              | 1205 +
+ arch/arm/configs/ndk15_defconfig                                              | 1221 +
+ arch/arm/configs/ndk15b06_defconfig                                           | 1221 +
+ arch/arm/configs/nhk15_defconfig                                              | 1458 +
+ arch/arm/kernel/Makefile                                                      |    1 
+ arch/arm/kernel/armksyms.c                                                    |   14 
+ arch/arm/kernel/dma.c                                                         |    1 
+ arch/arm/kernel/entry-armv.S                                                  |    2 
+ arch/arm/kernel/irq.c                                                         |   12 
+ arch/arm/kernel/kgdb-jmp.S                                                    |   30 
+ arch/arm/kernel/kgdb.c                                                        |  208 
+ arch/arm/kernel/setup.c                                                       |    5 
+ arch/arm/kernel/traps.c                                                       |   11 
+ arch/arm/lib/Makefile                                                         |    2 
+ arch/arm/lib/gcclib.h                                                         |   25 
+ arch/arm/lib/longlong.h                                                       |  184 
+ arch/arm/lib/udivdi3.c                                                        |  246 
+ arch/arm/mach-nomadik/Kconfig-nomadik                                         |  267 
+ arch/arm/mach-nomadik/Makefile                                                |  166 
+ arch/arm/mach-nomadik/Makefile.boot                                           |    4 
+ arch/arm/mach-nomadik/clock.c                                                 |  127 
+ arch/arm/mach-nomadik/clock.h                                                 |   25 
+ arch/arm/mach-nomadik/cpu.c                                                   |  293 
+ arch/arm/mach-nomadik/create_kconfig.pl                                       |   55 
+ arch/arm/mach-nomadik/deep_sleep.S                                            |  655 
+ arch/arm/mach-nomadik/dfs.S                                                   |  355 
+ arch/arm/mach-nomadik/dma.c                                                   | 1337 +
+ arch/arm/mach-nomadik/fsmc.c                                                  |  113 
+ arch/arm/mach-nomadik/gpio.c                                                  |  916 +
+ arch/arm/mach-nomadik/irq.c                                                   |  231 
+ arch/arm/mach-nomadik/l2cc.c                                                  |  152 
+ arch/arm/mach-nomadik/msp.c                                                   | 2062 ++
+ arch/arm/mach-nomadik/msp.h                                                   |  383 
+ arch/arm/mach-nomadik/mtu.c                                                   |  589 
+ arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig                                    |   28 
+ arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig                                   |   35 
+ arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig                                    |   35 
+ arch/arm/mach-nomadik/ndk10_devices.c                                         | 1225 +
+ arch/arm/mach-nomadik/ndk15_devices.c                                         | 1001 +
+ arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig                                 |   37 
+ arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig                                 |   37 
+ arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig                                 |   42 
+ arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig                                 |   42 
+ arch/arm/mach-nomadik/ndk15c02_devices.c                                      | 1023 +
+ arch/arm/mach-nomadik/nhk15_Kconfig                                           |   36 
+ arch/arm/mach-nomadik/nhk15_devices.c                                         | 1009 +
+ arch/arm/mach-nomadik/normal.S                                                |  199 
+ arch/arm/mach-nomadik/pm.c                                                    |   79 
+ arch/arm/mach-nomadik/power.c                                                 | 1316 +
+ arch/arm/mach-nomadik/rtc.c                                                   |  327 
+ arch/arm/mach-nomadik/sleep.c                                                 |  280 
+ arch/arm/mach-nomadik/slow.S                                                  |  199 
+ arch/arm/mach-nomadik/soft_sleep.S                                            |  206 
+ arch/arm/mach-nomadik/ssp.c                                                   |  930 +
+ arch/arm/mach-nomadik/stn8810_devices.c                                       | 1071 +
+ arch/arm/mach-nomadik/stn8815_devices.c                                       | 1971 ++
+ arch/arm/mach-nomadik/timer.c                                                 |  366 
+ arch/arm/mm/Kconfig                                                           |   23 
+ arch/arm/mm/extable.c                                                         |    7 
+ arch/arm/mm/init.c                                                            |    1 
+ arch/arm/mm/proc-arm926.S                                                     |   30 
+ arch/arm/oprofile/common.c                                                    |    3 
+ drivers/Makefile                                                              |    2 
+ drivers/char/keyboard.c                                                       |    1 
+ drivers/cpufreq/Kconfig                                                       |    4 
+ drivers/hwmon/Kconfig                                                         |   13 
+ drivers/hwmon/Makefile                                                        |    1 
+ drivers/hwmon/lis3lv02dl.c                                                    |  489 
+ drivers/i2c/Kconfig                                                           |    1 
+ drivers/i2c/Makefile                                                          |    3 
+ drivers/i2c/busses/Kconfig                                                    |   10 
+ drivers/i2c/busses/Makefile                                                   |   22 
+ drivers/i2c/busses/i2c-nomadik.c                                              | 1250 +
+ drivers/i2c/busses/i2c-nomadik.h                                              |   93 
+ drivers/i2c/busses/i2c-stn8810.c                                              | 1723 ++
+ drivers/i2c/busses/i2c-stn8815.c                                              | 1817 ++
+ drivers/i2c/chips/Kconfig                                                     |    9 
+ drivers/i2c/chips/Makefile                                                    |    6 
+ drivers/i2c/chips/epio-nomadik.c                                              |  195 
+ drivers/input/input.c                                                         |   13 
+ drivers/input/keyboard/Kconfig                                                |   13 
+ drivers/input/keyboard/Makefile                                               |    7 
+ drivers/input/keyboard/kpd-nomadik.c                                          |  359 
+ drivers/input/touchscreen/Kconfig                                             |   20 
+ drivers/input/touchscreen/Makefile                                            |    8 
+ drivers/input/touchscreen/touchp-nomadik.c                                    |  755 +
+ drivers/input/touchscreen/touchp2003-nomadik.c                                |  566 
+ drivers/media/Kconfig                                                         |    2 
+ drivers/media/Makefile                                                        |    4 
+ drivers/media/nomadik_mm/Kconfig                                              |   23 
+ drivers/media/nomadik_mm/Makefile                                             |    8 
+ drivers/media/nomadik_mm/hcl/hloader/hloader.c                                | 3632 ++++
+ drivers/media/nomadik_mm/hcl/hloader/hloader.h                                |  170 
+ drivers/media/nomadik_mm/hcl/hloader/hloader_p.h                              |  451 
+ drivers/media/nomadik_mm/hcl/include/debug.h                                  |  316 
+ drivers/media/nomadik_mm/hcl/include/hcl_defs.h                               |  290 
+ drivers/media/nomadik_mm/hcl/include/hloader.h                                |  170 
+ drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h                          | 1761 ++
+ drivers/media/nomadik_mm/hcl/include/platform_os.h                            |   72 
+ drivers/media/nomadik_mm/hcl/include/sva.h                                    | 2148 ++
+ drivers/media/nomadik_mm/hcl/saa/audio_services.c                             |  142 
+ drivers/media/nomadik_mm/hcl/saa/audio_services.h                             |   39 
+ drivers/media/nomadik_mm/hcl/saa/ha_api_params.h                              | 1064 +
+ drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h                              |  204 
+ drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h                            |  686 
+ drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h                             |  122 
+ drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h                           | 1342 +
+ drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h                        |  163 
+ drivers/media/nomadik_mm/hcl/saa/hti.c                                        |  271 
+ drivers/media/nomadik_mm/hcl/saa/hti.h                                        |  159 
+ drivers/media/nomadik_mm/hcl/saa/hti_protocol.h                               |  134 
+ drivers/media/nomadik_mm/hcl/saa/saa.c                                        | 2538 +++
+ drivers/media/nomadik_mm/hcl/saa/saa.h                                        |  306 
+ drivers/media/nomadik_mm/hcl/saa/saa_base.c                                   |  557 
+ drivers/media/nomadik_mm/hcl/saa/saa_hwp.h                                    |  275 
+ drivers/media/nomadik_mm/hcl/saa/saa_irq.c                                    |  432 
+ drivers/media/nomadik_mm/hcl/saa/saap.h                                       |  160 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c                    |   63 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h                    |   46 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h                            |  335 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h                             |  646 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c                   |  131 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h                   |   61 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_service.h                         |  337 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c                         |  486 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h                         |   80 
+ drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h                        |   49 
+ drivers/media/nomadik_mm/hcl/sva/common/svap.h                                |  188 
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c                    | 3030 ++++
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h                    |  110 
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c                | 3101 ++++
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h                |  232 
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h               |   98 
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c           |  312 
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h           |   53 
+ drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h                   |  156 
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c                  | 2126 ++
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h                  |  181 
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c                 |  789 +
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h                 |   35 
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c                  | 2211 ++
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h                  |  170 
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c                 |  686 
+ drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h                 |   35 
+ drivers/media/nomadik_mm/hcl/sva/decode/sva.h                                 |   18 
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h                         |  135 
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c                          | 2357 +++
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h                          |   97 
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c                         |  655 
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h                         |  364 
+ drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h                        |   40 
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c                      | 2044 ++
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h                      |  194 
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c                     |  714 
+ drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h                     |   37 
+ drivers/media/nomadik_mm/hcl/sva/display/sva_display.c                        | 5661 +++++++
+ drivers/media/nomadik_mm/hcl/sva/display/sva_display.h                        |   99 
+ drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h                       |  424 
+ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c                         | 3648 ++++
+ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h                         |  112 
+ drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h                        |  262 
+ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c                    | 4739 ++++++
+ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h                    |   79 
+ drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h                   |  646 
+ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c                  | 2556 +++
+ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h                  |   69 
+ drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h                 |  246 
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h                         |  187 
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c                          | 4594 ++++++
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h                          |   90 
+ drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h                         |  340 
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c             |  896 +
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h             |   97 
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h            |   84 
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c               |  225 
+ drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h               |   42 
+ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c              | 1907 ++
+ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h              |  180 
+ drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h             |  304 
+ drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c                              | 3810 +++++
+ drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h                              |   88 
+ drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h                             |  411 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h                  |   87 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h                      |  111 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h                   |   46 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h                       |  181 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h                         |   97 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_display.h                        |   99 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h                         |   90 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h                       |   97 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h                           |  335 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h                          |  180 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h                           |   89 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h                 |  290 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h                  |   60 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h                         |   42 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h                      |  163 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h                    |   62 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h                 |   71 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_service.h                        |  337 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h                           |   89 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h                   |  111 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h                   |   96 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h                        |  403 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h                        |   80 
+ drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h                            |   89 
+ drivers/media/nomadik_mm/hcl/sva/include/svap.h                               |  193 
+ drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h               | 1725 ++
+ drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h                     |   41 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c        |  541 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h        |   87 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h       |   73 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c            | 1212 +
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h            |  111 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h           |   83 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c            | 1578 ++
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h            |  163 
+ drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h           |  105 
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h     |   62 
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c  |  620 
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h  |   71 
+ drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h |   56 
+ drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c                              | 2855 +++
+ drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h                              |   89 
+ drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h                             |  284 
+ drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c             | 1047 +
+ drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h             |   70 
+ drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h            |   74 
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h                  |   96 
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c              | 3174 ++++
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h              |  111 
+ drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h             |  267 
+ drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c             |  682 
+ drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h             |   63 
+ drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h            |   62 
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h                  |  152 
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c              | 3752 ++++
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h              |   96 
+ drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h             |  248 
+ drivers/media/nomadik_mm/hcl/sva/sva.c                                        | 1827 ++
+ drivers/media/nomadik_mm/hcl/sva/sva.h                                        | 2148 ++
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c             | 1701 ++
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h             |   93 
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h            |  134 
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c               | 3573 ++++
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h               |  403 
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h              |  359 
+ drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c              |   19 
+ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c                                | 2478 +++
+ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h                                |   89 
+ drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h                               |  278 
+ drivers/media/nomadik_mm/opengl/Makefile                                      |   18 
+ drivers/media/nomadik_mm/opengl/ogl.c                                         |  565 
+ drivers/media/nomadik_mm/opengl/ogl.h                                         |   65 
+ drivers/media/nomadik_mm/opengl/ogl_ioctl.h                                   |   56 
+ drivers/media/nomadik_mm/saa/Makefile                                         |   20 
+ drivers/media/nomadik_mm/saa/README                                           |   72 
+ drivers/media/nomadik_mm/saa/nomadik-fwload.c                                 |  229 
+ drivers/media/nomadik_mm/saa/nomadik-fwload.h                                 |   47 
+ drivers/media/nomadik_mm/saa/nomadik-saa.c                                    | 4406 +++++
+ drivers/media/nomadik_mm/saa/nomadik-saa.h                                    |  204 
+ drivers/media/nomadik_mm/saa/saaioctl.h                                       |  498 
+ drivers/media/nomadik_mm/sva/Makefile                                         |   58 
+ drivers/media/nomadik_mm/sva/nomadik_camera.h                                 |  206 
+ drivers/media/nomadik_mm/sva/nomadik_defs.h                                   |   76 
+ drivers/media/nomadik_mm/sva/nomadik_pepperpot.c                              | 1189 +
+ drivers/media/nomadik_mm/sva/nomadik_pepperpot.h                              |  153 
+ drivers/media/nomadik_mm/sva/nomadik_sva.c                                    | 4951 ++++++
+ drivers/media/nomadik_mm/sva/nomadik_sva.h                                    |  225 
+ drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c                              |  432 
+ drivers/media/nomadik_mm/sva/nomadik_sva_services.h                           | 3826 +++++
+ drivers/media/nomadik_mm/sva/nomadik_sva_utils.c                              |  964 +
+ drivers/media/nomadik_mm/sva/nomadik_sva_utils.h                              |   49 
+ drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c                               | 6984 +++++++++
+ drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h                               |  589 
+ drivers/media/video/Kconfig                                                   |    7 
+ drivers/media/video/Makefile                                                  |    8 
+ drivers/media/video/hcl_defs.h                                                |  280 
+ drivers/media/video/nomadik_camera.h                                          |  206 
+ drivers/media/video/nomadik_defs.h                                            |   76 
+ drivers/media/video/nomadik_sva.h                                             |  225 
+ drivers/media/video/nomadik_sva_services.h                                    | 3832 +++++
+ drivers/media/video/nomadik_sva_utils.h                                       |   49 
+ drivers/media/video/platform_os.h                                             |   55 
+ drivers/media/video/sva.h                                                     | 2148 ++
+ drivers/media/video/v4l2-nomadik.c                                            | 1590 ++
+ drivers/media/video/v4l2-nomadik.h                                            |   70 
+ drivers/misc/Kconfig                                                          |   27 
+ drivers/misc/Makefile                                                         |    4 
+ drivers/misc/batt-nomadik.c                                                   | 1307 +
+ drivers/misc/etm-nomadik.c                                                    |  207 
+ drivers/misc/pexp-nomadik.c                                                   | 2847 +++
+ drivers/misc/sif-nomadik.c                                                    |  560 
+ drivers/mmc/Kconfig                                                           |   27 
+ drivers/mmc/Makefile                                                          |    9 
+ drivers/mmc/mmc-nomadik.c                                                     | 1435 +
+ drivers/mtd/maps/Kconfig                                                      |    7 
+ drivers/mtd/maps/Makefile                                                     |   11 
+ drivers/mtd/maps/norflash-nomadik.c                                           |  411 
+ drivers/mtd/nand/Kconfig                                                      |    6 
+ drivers/mtd/nand/Makefile                                                     |    5 
+ drivers/mtd/nand/nandflash-nomadik.c                                          |  296 
+ drivers/mtd/onenand/Kconfig                                                   |   38 
+ drivers/mtd/onenand/Makefile                                                  |    3 
+ drivers/mtd/onenand/generic.c                                                 |   62 
+ drivers/mtd/onenand/onenand_base.c                                            | 1139 +
+ drivers/mtd/onenand/onenand_bbt.c                                             |   33 
+ drivers/mtd/onenand/onenand_sim.c                                             |  495 
+ drivers/net/Makefile                                                          |    1 
+ drivers/net/kgdboe.c                                                          |  294 
+ drivers/net/smc91x.c                                                          |  100 
+ drivers/net/smc91x.h                                                          |  133 
+ drivers/serial/amba-pl011.c                                                   |  101 
+ drivers/spi/Kconfig                                                           |    8 
+ drivers/spi/Makefile                                                          |    2 
+ drivers/spi/spi-nomadik.c                                                     | 1000 +
+ drivers/usb/Kconfig                                                           |    2 
+ drivers/usb/Makefile                                                          |    1 
+ drivers/usb/gadget/file_storage.c                                             |   15 
+ drivers/usb/nomadik/Kconfig                                                   |  176 
+ drivers/usb/nomadik/Makefile                                                  |   97 
+ drivers/usb/nomadik/board.h                                                   |   58 
+ drivers/usb/nomadik/debug.h                                                   |  104 
+ drivers/usb/nomadik/dma.h                                                     |  308 
+ drivers/usb/nomadik/g_ep0.c                                                   |  858 +
+ drivers/usb/nomadik/logx                                                      |    1 
+ drivers/usb/nomadik/musb_bus_direct.c                                         |  371 
+ drivers/usb/nomadik/musb_cross.h                                              |  131 
+ drivers/usb/nomadik/musb_debug.c                                              |  190 
+ drivers/usb/nomadik/musb_epdescriptors.h                                      |   48 
+ drivers/usb/nomadik/musb_epfifocfg.c                                          |  429 
+ drivers/usb/nomadik/musb_hcd.c                                                |  869 +
+ drivers/usb/nomadik/musb_host.c                                               | 2791 +++
+ drivers/usb/nomadik/musb_host.h                                               |  101 
+ drivers/usb/nomadik/musb_ioctl.c                                              |  321 
+ drivers/usb/nomadik/musb_ioctl.h                                              |   32 
+ drivers/usb/nomadik/musb_plat_uds.c                                           | 2306 +++
+ drivers/usb/nomadik/musb_procfs.c                                             |  413 
+ drivers/usb/nomadik/musb_virthub.c                                            |  840 +
+ drivers/usb/nomadik/musb_virthub.h                                            |  240 
+ drivers/usb/nomadik/musbdefs.h                                                |  828 +
+ drivers/usb/nomadik/musbhdrc.h                                                |  315 
+ drivers/usb/nomadik/musbhsfc.h                                                |  150 
+ drivers/usb/nomadik/nomadik_udc.c                                             | 2845 +++
+ drivers/usb/nomadik/nomadik_udc.h                                             |  663 
+ drivers/usb/nomadik/otg_func.c                                                |  196 
+ drivers/usb/nomadik/otg_pwm.c                                                 |   46 
+ drivers/usb/nomadik/plat_arc.h                                                |   92 
+ drivers/usb/nomadik/plat_cnf.h                                                |  208 
+ drivers/video/Makefile                                                        |    1 
+ drivers/video/amba-clcd.c                                                     |  115 
+ drivers/video/fbmem.c                                                         |    1 
+ drivers/video/nomadik/Makefile                                                |   15 
+ drivers/video/nomadik/hcl/debug.h                                             |  313 
+ drivers/video/nomadik/hcl/hcl_defs.h                                          |  286 
+ drivers/video/nomadik/hcl/platform_os.h                                       |   79 
+ drivers/video/nomadik/hcl/sga.c                                               | 3161 ++++
+ drivers/video/nomadik/hcl/sga.h                                               |  937 +
+ drivers/video/nomadik/hcl/sga_irq.c                                           |  206 
+ drivers/video/nomadik/hcl/sga_irq.h                                           |   99 
+ drivers/video/nomadik/hcl/sga_irqp.h                                          |  239 
+ drivers/video/nomadik/hcl/sga_p.h                                             |  175 
+ drivers/video/nomadik/sga_defs.h                                              |   87 
+ drivers/video/nomadik/sga_err.h                                               |   45 
+ drivers/video/nomadik/sga_interface.h                                         |  119 
+ drivers/video/nomadik/sga_ioctlfns.c                                          |  473 
+ drivers/video/nomadik/sga_ioctlfns.h                                          |   50 
+ drivers/video/nomadik/sga_main.c                                              |  651 
+ drivers/video/nomadik/sga_main.h                                              |  123 
+ drivers/video/nomadik/sga_typs.h                                              |   37 
+ fs/Kconfig                                                                    |    4 
+ fs/Makefile                                                                   |    3 
+ fs/proc/proc_misc.c                                                           |   42 
+ fs/yaffs2/Kconfig                                                             |  156 
+ fs/yaffs2/Makefile                                                            |   10 
+ fs/yaffs2/devextras.h                                                         |  264 
+ fs/yaffs2/moduleconfig.h                                                      |   65 
+ fs/yaffs2/yaffs_checkptrw.c                                                   |  404 
+ fs/yaffs2/yaffs_checkptrw.h                                                   |   35 
+ fs/yaffs2/yaffs_ecc.c                                                         |  331 
+ fs/yaffs2/yaffs_ecc.h                                                         |   44 
+ fs/yaffs2/yaffs_fs.c                                                          | 2297 +++
+ fs/yaffs2/yaffs_guts.c                                                        | 7532 ++++++++++
+ fs/yaffs2/yaffs_guts.h                                                        |  904 +
+ fs/yaffs2/yaffs_mtdif.c                                                       |  241 
+ fs/yaffs2/yaffs_mtdif.h                                                       |   27 
+ fs/yaffs2/yaffs_mtdif1.c                                                      |  369 
+ fs/yaffs2/yaffs_mtdif1.h                                                      |   28 
+ fs/yaffs2/yaffs_mtdif2.c                                                      |  232 
+ fs/yaffs2/yaffs_mtdif2.h                                                      |   29 
+ fs/yaffs2/yaffs_nand.c                                                        |  134 
+ fs/yaffs2/yaffs_nand.h                                                        |   44 
+ fs/yaffs2/yaffs_nandemul2k.h                                                  |   39 
+ fs/yaffs2/yaffs_packedtags1.c                                                 |   52 
+ fs/yaffs2/yaffs_packedtags1.h                                                 |   37 
+ fs/yaffs2/yaffs_packedtags2.c                                                 |  182 
+ fs/yaffs2/yaffs_packedtags2.h                                                 |   38 
+ fs/yaffs2/yaffs_qsort.c                                                       |  160 
+ fs/yaffs2/yaffs_qsort.h                                                       |   23 
+ fs/yaffs2/yaffs_tagscompat.c                                                  |  530 
+ fs/yaffs2/yaffs_tagscompat.h                                                  |   40 
+ fs/yaffs2/yaffs_tagsvalidity.c                                                |   28 
+ fs/yaffs2/yaffs_tagsvalidity.h                                                |   24 
+ fs/yaffs2/yaffsinterface.h                                                    |   21 
+ fs/yaffs2/yportenv.h                                                          |  200 
+ include/asm-arm/arch-nomadik/audiocodec.h                                     |  444 
+ include/asm-arm/arch-nomadik/bits.h                                           |   61 
+ include/asm-arm/arch-nomadik/debug-macro.S                                    |   38 
+ include/asm-arm/arch-nomadik/debug.h                                          |  148 
+ include/asm-arm/arch-nomadik/defs.h                                           |  245 
+ include/asm-arm/arch-nomadik/dma.h                                            |  362 
+ include/asm-arm/arch-nomadik/entry-macro.S                                    |  210 
+ include/asm-arm/arch-nomadik/epio.h                                           |   24 
+ include/asm-arm/arch-nomadik/fsmc.h                                           |  203 
+ include/asm-arm/arch-nomadik/gpio.h                                           |  529 
+ include/asm-arm/arch-nomadik/hardware.h                                       |  107 
+ include/asm-arm/arch-nomadik/i2c.h                                            |  419 
+ include/asm-arm/arch-nomadik/io.h                                             |   37 
+ include/asm-arm/arch-nomadik/irqs.h                                           |  137 
+ include/asm-arm/arch-nomadik/kpd.h                                            |   56 
+ include/asm-arm/arch-nomadik/memory.h                                         |   41 
+ include/asm-arm/arch-nomadik/mmc.h                                            |  234 
+ include/asm-arm/arch-nomadik/msp-spi.h                                        |  343 
+ include/asm-arm/arch-nomadik/msp.h                                            |  322 
+ include/asm-arm/arch-nomadik/mtu.h                                            |   90 
+ include/asm-arm/arch-nomadik/nandflash.h                                      |   42 
+ include/asm-arm/arch-nomadik/ndk10_devices.h                                  |  160 
+ include/asm-arm/arch-nomadik/ndk15_devices.h                                  |  248 
+ include/asm-arm/arch-nomadik/ndk15c02_devices.h                               |  169 
+ include/asm-arm/arch-nomadik/nhk15_devices.h                                  |  131 
+ include/asm-arm/arch-nomadik/param.h                                          |   19 
+ include/asm-arm/arch-nomadik/pexp.h                                           |  355 
+ include/asm-arm/arch-nomadik/power.h                                          |  180 
+ include/asm-arm/arch-nomadik/smp.h                                            |   19 
+ include/asm-arm/arch-nomadik/spi.h                                            |  521 
+ include/asm-arm/arch-nomadik/ssp-spi.h                                        |  280 
+ include/asm-arm/arch-nomadik/stn8810_devices.h                                |  120 
+ include/asm-arm/arch-nomadik/stn8815_devices.h                                |  165 
+ include/asm-arm/arch-nomadik/stw5094ap.h                                      |  176 
+ include/asm-arm/arch-nomadik/stw5095.h                                        | 1387 +
+ include/asm-arm/arch-nomadik/sva.h                                            |   43 
+ include/asm-arm/arch-nomadik/system.h                                         |   62 
+ include/asm-arm/arch-nomadik/timex.h                                          |   71 
+ include/asm-arm/arch-nomadik/touchp.h                                         |  145 
+ include/asm-arm/arch-nomadik/touchp2003.h                                     |   42 
+ include/asm-arm/arch-nomadik/udc.h                                            |  490 
+ include/asm-arm/arch-nomadik/uncompress.h                                     |   71 
+ include/asm-arm/arch-nomadik/vmalloc.h                                        |   32 
+ include/asm-arm/kgdb.h                                                        |   91 
+ include/asm-arm/system.h                                                      |   41 
+ include/asm-generic/kgdb.h                                                    |   34 
+ include/linux/amba/clcd.h                                                     |   24 
+ include/linux/dwarf2-lang.h                                                   |  300 
+ include/linux/dwarf2.h                                                        |  775 +
+ include/linux/i2c.h                                                           |   13 
+ include/linux/kgdb.h                                                          |  271 
+ include/linux/miscdevice.h                                                    |    1 
+ include/linux/module.h                                                        |   28 
+ include/linux/mtd/bbm.h                                                       |   11 
+ include/linux/mtd/mtd.h                                                       |    1 
+ include/linux/mtd/nand.h                                                      |   52 
+ include/linux/mtd/onenand.h                                                   |   31 
+ include/linux/mtd/onenand_regs.h                                              |    8 
+ include/linux/netpoll.h                                                       |    2 
+ include/linux/usb.h                                                           |    4 
+ include/linux/v4l2-nomadikdefs.h                                              |   12 
+ include/linux/videodev2.h                                                     |   11 
+ init/Kconfig                                                                  |   15 
+ kernel/Makefile                                                               |    1 
+ kernel/kgdb.c                                                                 | 1963 ++
+ kernel/module.c                                                               |  216 
+ kernel/pid.c                                                                  |   11 
+ kernel/power/main.c                                                           |    2 
+ kernel/sched.c                                                                |    6 
+ kernel/softlockup.c                                                           |    4 
+ kernel/timer.c                                                                |    8 
+ lib/Kconfig.debug                                                             |   79 
+ net/core/netpoll.c                                                            |    5 
+ net/sunrpc/xprtsock.c                                                         |    5 
+ scripts/Makefile                                                              |    1 
+ scripts/Makefile.modpost                                                      |    2 
+ scripts/dwarfh.awk                                                            |   19 
+ scripts/kconfig/Makefile                                                      |   32 
+ scripts/ksymhash/Makefile                                                     |   35 
+ scripts/ksymhash/elflib.c                                                     |  164 
+ scripts/ksymhash/elflib.h                                                     |  142 
+ scripts/ksymhash/empty.c                                                      |    1 
+ scripts/ksymhash/ksymhash.c                                                   |  126 
+ scripts/ksymhash/mk_elfconfig.c                                               |   66 
+ scripts/mod/modpost.c                                                         |   23 
+ sound/Kconfig                                                                 |   36 
+ sound/Makefile                                                                |    9 
+ sound/arm/Kconfig                                                             |   11 
+ sound/arm/Makefile                                                            |    3 
+ sound/arm/nomadik_alsa.c                                                      | 1038 +
+ sound/arm/nomadik_alsa.h                                                      |   83 
+ sound/nomadik_stw5094.c                                                       | 2280 +++
+ sound/nomadik_stw5095.c                                                       | 3529 ++++
+ 514 files changed, 244969 insertions(+), 622 deletions(-)
+
+--- linux-2.6.20.orig/.gitignore
++++ /dev/null
+@@ -1,47 +0,0 @@
+-#
+-# NOTE! Don't add files that are generated in specific
+-# subdirectories here. Add them in the ".gitignore" file
+-# in that subdirectory instead.
+-#
+-# Normal rules
+-#
+-.*
+-*.o
+-*.a
+-*.s
+-*.ko
+-*.so
+-*.mod.c
+-*.i
+-*.lst
+-*.symtypes
+-
+-#
+-# Top-level generic files
+-#
+-tags
+-TAGS
+-vmlinux*
+-System.map
+-Module.symvers
+-
+-#
+-# Generated include files
+-#
+-include/asm
+-include/asm-*/asm-offsets.h
+-include/config
+-include/linux/autoconf.h
+-include/linux/compile.h
+-include/linux/version.h
+-include/linux/utsrelease.h
+-
+-# stgit generated dirs
+-patches-*
+-
+-# quilt's files
+-patches
+-series
+-
+-# cscope files
+-cscope.*
+--- linux-2.6.20.orig/Documentation/DocBook/Makefile
++++ linux-2.6.20/Documentation/DocBook/Makefile
+@@ -9,11 +9,12 @@
+ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
+           kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
+           procfs-guide.xml writing_usb_driver.xml \
+           kernel-api.xml filesystems.xml lsm.xml usb.xml \
+           gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
+-          genericirq.xml
++          genericirq.xml \
++          kgdb.xml
  
-       case RTC_RD_TIME:
-diff -Nauprw linux-2.6.20/arch/arm/configs/ndk10_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk10_defconfig
---- linux-2.6.20/arch/arm/configs/ndk10_defconfig      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/configs/ndk10_defconfig       2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1205 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.20
-+# Thu Aug 16 17:17:58 2007
-+#
-+CONFIG_ARM=y
-+# CONFIG_GENERIC_TIME is not set
-+CONFIG_MMU=y
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ ###
+ # The build process is as follows (targets):
+ #              (xmldocs)
+ # file.tmpl --> file.xml +--> file.ps   (psdocs)
+--- /dev/null
++++ linux-2.6.20/Documentation/DocBook/kgdb.tmpl
+@@ -0,0 +1,234 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
++      "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
 +
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_LOCK_KERNEL=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
++<book id="kgdbInternals">
++ <bookinfo>
++  <title>KGDB Internals</title>
 +
-+#
-+# General setup
-+#
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_IPC_NS is not set
-+# CONFIG_POSIX_MQUEUE is not set
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+# CONFIG_TASKSTATS is not set
-+# CONFIG_UTS_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_INITRAMFS_SOURCE=""
-+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-+CONFIG_SYSCTL=y
-+CONFIG_EMBEDDED=y
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_ALL is not set
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_EPOLL=y
-+CONFIG_SHMEM=y
-+CONFIG_SLAB=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+# CONFIG_SLOB is not set
++  <authorgroup>
++   <author>
++    <firstname>Tom</firstname>
++    <surname>Rini</surname>
++    <affiliation>
++     <address>
++      <email>trini@kernel.crashing.org</email>
++     </address>
++    </affiliation>
++   </author>
++  </authorgroup>
 +
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+# CONFIG_MODULE_FORCE_UNLOAD is not set
-+# CONFIG_MODVERSIONS is not set
-+# CONFIG_MODULE_SRCVERSION_ALL is not set
-+# CONFIG_KMOD is not set
++  <authorgroup>
++   <author>
++    <firstname>Amit S.</firstname>
++    <surname>Kale</surname>
++    <affiliation>
++     <address>
++      <email>amitkale@linsyssoft.com</email>
++     </address>
++    </affiliation>
++   </author>
++  </authorgroup>
 +
-+#
-+# Block layer
-+#
-+CONFIG_BLOCK=y
-+# CONFIG_LBD is not set
-+# CONFIG_BLK_DEV_IO_TRACE is not set
-+# CONFIG_LSF is not set
++  <copyright>
++   <year>2004-2005</year>
++   <holder>MontaVista Software, Inc.</holder>
++  </copyright>
++  <copyright>
++   <year>2004</year>
++   <holder>Amit S. Kale</holder>
++  </copyright>
 +
-+#
-+# IO Schedulers
-+#
-+CONFIG_IOSCHED_NOOP=y
-+CONFIG_IOSCHED_AS=y
-+CONFIG_IOSCHED_DEADLINE=y
-+CONFIG_IOSCHED_CFQ=y
-+CONFIG_DEFAULT_AS=y
-+# CONFIG_DEFAULT_DEADLINE is not set
-+# CONFIG_DEFAULT_CFQ is not set
-+# CONFIG_DEFAULT_NOOP is not set
-+CONFIG_DEFAULT_IOSCHED="anticipatory"
++  <legalnotice>
++   <para>
++   This file is licensed under the terms of the GNU General Public License
++   version 2. This program is licensed "as is" without any warranty of any
++   kind, whether express or implied.
++   </para>
 +
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_AAEC2000 is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_REALVIEW is not set
-+# CONFIG_ARCH_VERSATILE is not set
-+# CONFIG_ARCH_AT91 is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_EP93XX is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_NETX is not set
-+CONFIG_ARCH_NOMADIK=y
-+# CONFIG_ARCH_H720X is not set
-+# CONFIG_ARCH_IMX is not set
-+# CONFIG_ARCH_IOP32X is not set
-+# CONFIG_ARCH_IOP33X is not set
-+# CONFIG_ARCH_IOP13XX is not set
-+# CONFIG_ARCH_IXP4XX is not set
-+# CONFIG_ARCH_IXP2000 is not set
-+# CONFIG_ARCH_IXP23XX is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_S3C2410 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_LH7A40X is not set
-+# CONFIG_ARCH_OMAP is not set
-+CONFIG_NOMADIK_NDK10_CUT_A1=y
-+# CONFIG_NOMADIK_NDK10_CUT_B06 is not set
-+# CONFIG_NOMADIK_NDK10_CUT_B0 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set
-+# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set
-+CONFIG_NOMADIK_TARGET="NDK10_Cut_A1"
-+CONFIG_NOMADIK_SOC="stn8810"
-+CONFIG_NOMADIK_PLATFORM="ndk10"
-+CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
-+CONFIG_NOMADIK_NDK10=y
-+CONFIG_NOMADIK_NDK10_CUTA=y
-+CONFIG_NOMADIK_GPIO=y
-+CONFIG_GPIO_PROC=y
-+CONFIG_NOMADIK_DMA=y
-+CONFIG_NOMADIK_SSP=m
-+CONFIG_NOMADIK_MSP=m
-+CONFIG_NOMADIK_MTU=m
-+CONFIG_NOMADIK_MTU_SYSTEM_TICK=y
-+CONFIG_NOMADIK_RTC=y
-+# CONFIG_NOMADIK_SVA_INIT_MEM is not set
-+CONFIG_NOMADIK_SVA_MEM_SIZE=4
-+# CONFIG_NOMADIK_SAA_INIT_MEM is not set
-+# CONFIG_FB_NOMADIK_VGA is not set
-+# CONFIG_FB_NOMADIK_CRT is not set
-+CONFIG_FB_NOMADIK_QVGA_PORTRAIT=y
-+# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set
-+# CONFIG_FB_NOMADIK_PANEL_8BPP is not set
-+CONFIG_FB_NOMADIK_PANEL_16BPP=y
-+# CONFIG_FB_NOMADIK_PANEL_24BPP is not set
-+CONFIG_SGA_INST_BUFFER_2=y
-+# CONFIG_SGA_INST_BUFFER_20 is not set
-+CONFIG_SGA_INST_BUFFER_NUM=2
-+CONFIG_FB_NOMADIK_PANEL_BPP=16
-+CONFIG_FB_NOMADIK_PANEL_NAME="QVGA_Portrait"
-+CONFIG_FB_NOMADIK_PANEL_XRES=240
-+CONFIG_FB_NOMADIK_PANEL_YRES=320
-+CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x13
-+CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x2f
-+CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x04
-+CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x0f
-+CONFIG_FB_NOMADIK_PANEL_HSLEN=0x13
-+CONFIG_FB_NOMADIK_PANEL_VSLEN=0x04
-+CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x00ef1804
++  </legalnotice>
++ </bookinfo>
 +
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_ARM920T is not set
-+CONFIG_CPU_ARM926T=y
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1022 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_V6 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
++<toc></toc>
++  <chapter id="Introduction">
++    <title>Introduction</title>
++    <para>
++    kgdb is a source level debugger for linux kernel. It is used along
++    with gdb to debug a linux kernel. Kernel developers can debug a kernel
++    similar to application programs with the use of kgdb. It makes it
++    possible to place breakpoints in kernel code, step through the code
++    and observe variables.
++    </para>
++    <para>
++    Two machines are required for using kgdb. One of these machines is a
++    development machine and the other is a test machine. The machines are
++    typically connected through a serial line, a null-modem cable which
++    connects their serial ports.  It is also possible however, to use an
++    ethernet connection between the machines.  The kernel to be debugged
++    runs on the test machine. gdb runs on the development machine. The
++    serial line or ethernet connection is used by gdb to communicate to
++    the kernel being debugged.
++    </para>
++  </chapter>
++  <chapter id="CompilingAKernel">
++    <title>Compiling a kernel</title>
++    <para>
++    To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
++    and then select "KGDB: kernel debugging with remote gdb".
++    </para>
++    <para>
++    The first choice for I/O is <symbol>CONFIG_KGDB_ONLY_MODULES</symbol>.
++    This means that you will only be able to use KGDB after loading a
++    kernel module that defines how you want to be able to talk with
++    KGDB.  There are two other choices (more on some architectures) that
++    can be enabled as modules later, if not picked here.
++    </para>
++    <para>The first of these is <symbol>CONFIG_KGDB_8250_NOMODULE</symbol>.
++    This has sub-options such as <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol>
++    which toggles choosing the serial port by ttyS number or by specifying
++    a port and IRQ number.
++    </para>
++    <para>
++    The second of these choices on most systems for I/O is
++    <symbol>CONFIG_KGDBOE</symbol>. This requires that the machine to be
++    debugged has an ethernet card which supports the netpoll API, such as
++    the cards supported by <symbol>CONFIG_E100</symbol>.  There are no
++    sub-options for this, but a kernel command line option is required.
++    </para>
++  </chapter>
++  <chapter id="BootingTheKernel">
++    <title>Booting the kernel</title>
++    <para>
++    The Kernel command line option <constant>kgdbwait</constant> makes kgdb
++    wait for gdb connection during booting of a kernel.  If the
++    <symbol>CONFIG_KGDB_8250</symbol> driver is used (or if applicable,
++    another serial driver) this breakpoint will happen very early on, before
++    console output.  If you wish to change serial port information and you
++    have enabled both <symbol>CONFIG_KGDB_8250</symbol> and
++    <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> then you must pass the option
++    <constant>kgdb8250=&lt;io or mmio&gt;,&lt;address&gt;,&lt;baud
++    rate&gt;,&lt;irq&gt;</constant> before <constant>kgdbwait</constant>.
++    The values <constant>io</constant> or <constant>mmio</constant> refer to
++    if the address being passed next needs to be memory mapped
++    (<constant>mmio</constant>) or not. The <constant>address</constant> must
++    be passed in hex and is the hardware address and will be remapped if
++    passed as <constant>mmio</constant>. The value
++    <constant>baud rate</constant> and <constant>irq</constant> are base-10.
++    The supported values for <constant>baud rate</constant> are
++    <constant>9600</constant>, <constant>19200</constant>,
++    <constant>38400</constant>, <constant>57600</constant>, and
++    <constant>115200</constant>.
++    </para>
++    <para>
++    To have KGDB stop the kernel and wait, with the compiled values for the
++    serial driver, pass in: <constant>kgdbwait</constant>.
++    </para>
++    <para>
++    To specify the values of the serial port at boot:
++    <constant>kgdb8250=io,3f8,115200,3</constant>.
++    On IA64 this could also be:
++    <constant>kgdb8250=mmio,0xff5e0000,115200,74</constant>
++    And to have KGDB also stop the kernel and wait for GDB to connect, pass in
++    <constant>kgdbwait</constant> after this arguement.
++    </para>
++    <para>
++    To configure the <symbol>CONFIG_KGDBOE</symbol> driver, pass in
++    <constant>kgdboe=[src-port]@&lt;src-ip&gt;/[dev],[tgt-port]@&lt;tgt-ip&gt;/[tgt-macaddr]</constant>
++    where:
++    <itemizedlist>
++      <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem>
++      <listitem><para>src-ip: source IP to use (interface address)</para></listitem>
++      <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem>
++      <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem>
++      <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem>
++      <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem>
++    </itemizedlist>
++    </para>
++    <para>
++    The <symbol>CONFIG_KGDBOE</symbol> driver can be reconfigured at run
++    time, if <symbol>CONFIG_SYSFS</symbol> and
++    <symbol>CONFIG_MODULES</symbol> by echo'ing a new config string to
++    <constant>/sys/module/kgdboe/parameter/kgdboe</constant>.  The
++    driver can be unconfigured with the special string
++    <constant>not_configured</constant>.
++    </para>
++  </chapter>
++  <chapter id="ConnectingGDB">
++  <title>Connecting gdb</title>
++    <para>
++    If you have used any of the methods to have KGDB stop and create
++    an initial breakpoint described in the previous chapter, kgdb prints
++    the message "Waiting for connection from remote gdb..." on the console
++    and waits for connection from gdb. At this point you connect gdb to kgdb.
++    </para>
++    <para>
++    Example (serial):
++    </para>
++    <programlisting>
++    % gdb ./vmlinux
++    (gdb) set remotebaud 115200
++    (gdb) target remote /dev/ttyS0
++    </programlisting>
++    <para>
++    Example (ethernet):
++    </para>
++    <programlisting>
++    % gdb ./vmlinux
++    (gdb) target remote udp:192.168.2.2:6443
++    </programlisting>
++    <para>
++    Once connected, you can debug a kernel the way you would debug an
++    application program.
++    </para>
++  </chapter>
++  <chapter id="CommonBackEndReq">
++    <title>The common backend (required)</title>
++      <para>
++      There are a few flags which must be set on every architecture in
++      their &lt;asm/kgdb.h&gt; file.  These are:
++      <itemizedlist>
++        <listitem>
++        <para>
++        NUMREGBYTES: The size in bytes of all of the registers, so
++        that we can ensure they will all fit into a packet.
++        </para>
++        <para>
++        BUFMAX: The size in bytes of the buffer GDB will read into.
++        This must be larger than NUMREGBYTES.
++        </para>
++        <para>
++        CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call
++        flush_cache_range or flush_icache_range.  On some architectures,
++        these functions may not be safe to call on SMP since we keep other
++        CPUs in a holding pattern.
++        </para>
++      </listitem>
++      </itemizedlist>
++      </para>
++      <para>
++      There are also the following functions for the common backend,
++      found in kernel/kgdb.c that must be supplied by the
++      architecture-specific backend.  No weak version of these is provided.
++      </para>
++!Iinclude/linux/kgdb.h
++  </chapter>
++  <chapter id="CommonBackEndOpt">
++    <title>The common backend (optional)</title>
++      <para>
++      These functions are part of the common backend, found in kernel/kgdb.c
++      and are optionally implemented.  Some functions (with _hw_ in the name)
++      end up being required on arches which use hardware breakpoints.
++      </para>
++!Ikernel/kgdb.c
++  </chapter>
++  <chapter id="DriverSpecificFunctions">
++    <title>Driver-Specific Functions</title>
++      <para>
++      Some of the I/O drivers have additional functions that can be
++      called, that are specific to the driver.  Calls from other places
++      to these functions must be wrapped in #ifdefs for the driver in
++      question.
++      </para>
++!Idrivers/serial/8250_kgdb.c
++   </chapter>
++</book>
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
+@@ -0,0 +1,111 @@
++Filename: ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
++Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner:                STMicroelectronics
++Purpose:
++              This HOWTO explains guidlines for addition of new Nomadik
++              board support to the kernel source code
++===============================================================================
 +
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+CONFIG_ICST525=y
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
 +
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+CONFIG_ISA_DMA_API=y
++Nomadik BSP kernel file naming conventions
++============================================
++It is strongly recommended to follow below filename conventions while adding
++new board support for Nomadik
++1. All the Nomadik architecture specific code must be in mach-nomadik and
++      arch-nomadik folders in a kernel tree.
++2. Generic and Nomadik specific device drives may be located into the respective
++      folder in the kernel source tree (ex. nomadik keypad driver in
++      drivers/input/keyboard/kpd-nomadik.c)
++3. all Nomadik specific files in mach-nomadik and arch-nomadik folders should
++      be named as <comp>.c/h
++      (ex. gpio.h, msp.c)
++4. all Nomadik platform specific files are named as <platform>_<purpose>.c/h
++      (ex. ndk10_devices.c, ndk15_devices.h)
++5. all Nomadik soc specific files are named as <soc>_<purpose>.c/h
++      (ex. stn8810_devices.h, stn8815_devices.c)
 +
-+#
-+# PCCARD (PCMCIA/CardBus) support
-+#
-+# CONFIG_PCCARD is not set
++Important definations
++==============================
++1. target: It is a unique identity to describe supported board with a specific
++           board version and specific SOC version.
++           target is created by combination of board (i.e. platform) and
++         Nomadik chip version (i.e. soc)
 +
-+#
-+# Kernel Features
-+#
-+CONFIG_PREEMPT=y
-+CONFIG_NO_IDLE_HZ=y
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+CONFIG_OABI_COMPAT=y
-+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
-+CONFIG_SELECT_MEMORY_MODEL=y
-+CONFIG_FLATMEM_MANUAL=y
-+# CONFIG_DISCONTIGMEM_MANUAL is not set
-+# CONFIG_SPARSEMEM_MANUAL is not set
-+CONFIG_FLATMEM=y
-+CONFIG_FLAT_NODE_MEM_MAP=y
-+# CONFIG_SPARSEMEM_STATIC is not set
-+CONFIG_SPLIT_PTLOCK_CPUS=4096
-+# CONFIG_RESOURCES_64BIT is not set
-+CONFIG_ALIGNMENT_TRAP=y
++2. platform: It is refered for board to be supported.
++         One plaform may be supported by several targets
++         One plaform may be supported by several socs
 +
-+#
-+# Boot options
-+#
-+CONFIG_ZBOOT_ROM_TEXT=0x0
-+CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
-+# CONFIG_XIP_KERNEL is not set
++3. soc: It is refered for the Nomadik chip version to be suported.
++         same soc may be supported on several platforms
 +
-+#
-+# CPU Frequency scaling
-+#
-+# CONFIG_CPU_FREQ is not set
++Hence any Nomadik borad is identified as a "target" and supported by "soc"
++   specific code and "platform" specific code well interfaced with generic
++   code.
 +
-+#
-+# Floating point emulation
-+#
++Device driver Support for Nomadik:
++====================================
++1. All the drivers suported on a target can be either SOC or platform specific
++2. A platform specific code for all supported driver will be refered from a
++   single file <platform_name>_devices.c through device specific interface.
++3. A Nomadik chip specific code for all supported driver will be refered from a
++   single file <soc_name>_devices.c through device specific interface.
++4. Each device specific header file <pltfomr_name>_devices.h and
++   <soc_name>_devices.h must be maintained to share a common hardware
++   parameters across the drivers. Those two files are included in
++   asm/arch/hardware.h which is further refered through asm/hardware.h
++   Hence any kernel code seeking for hardware specific information (like
++   base address, irqnos) can be made available by just including
++   <asm/hardware.h>
++5. Each header file described here should have relevent declaration related to
++   the scope of its usage. ex. <platform_name>_devices.h should only have
++   platforms specific declration.
 +
-+#
-+# At least one emulation must be selected
-+#
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_NWFPE_XP is not set
-+# CONFIG_FPE_FASTFPE is not set
-+# CONFIG_VFP is not set
++Any Nomadik target can be supported by following set of files:-
++      arch/arch/mach-nomadik/<soc_name>_devices.c
++      inclue/asm-arm/arch-nomadik/<soc_name>_devices.h
++      arch/arch/mach-nomadik/<platform_name>_devices.c
++      inclue/asm-arm/arch-nomadik/<platform_name>_devices.h
 +
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
++But Generally, New board support will be added for already suported SOCs
++hence, to add support for any new Nomadik target only three files need to be
++added, those are:-
++      arch/arch/mach-nomadik/<target_name>_Kconfig
++      arch/arch/mach-nomadik/<platform_name>_devices.c
++      inclue/asm-arm/arch0-nomadik/<platform_name>_devices.h
 +
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+# CONFIG_APM is not set
++Steps to follow to add new target support for Nomadik
++========================================================
++1. Add ./arch/arm/mach-nomadik/<target_name>_Kconfig file for board
++   configuration, <target_name> specified here will reflect as machine name.
 +
-+#
-+# Networking
-+#
-+CONFIG_NET=y
++      During make config/menuconfig arch/arm/mach-nomadik/Kconfig will be
++      checked, and if is not found, it will be created automatically using
++      all <target_name>_Kconfig files and Kconfig_nomadik file.
++      1. <target_name>_Kconfig file contain board specific configuration
++      2. Kconfig_nomadik contains generic configuration for all nomadik
++         platforms
++      for details refer provided ndk10_cut_a1_Kconfig file
 +
-+#
-+# Networking options
-+#
-+# CONFIG_NETDEBUG is not set
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+CONFIG_UNIX=y
-+CONFIG_XFRM=y
-+# CONFIG_XFRM_USER is not set
-+# CONFIG_XFRM_SUB_POLICY is not set
-+# CONFIG_NET_KEY is not set
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_INET_AH is not set
-+# CONFIG_INET_ESP is not set
-+# CONFIG_INET_IPCOMP is not set
-+# CONFIG_INET_XFRM_TUNNEL is not set
-+# CONFIG_INET_TUNNEL is not set
-+CONFIG_INET_XFRM_MODE_TRANSPORT=y
-+CONFIG_INET_XFRM_MODE_TUNNEL=y
-+CONFIG_INET_XFRM_MODE_BEET=y
-+CONFIG_INET_DIAG=y
-+CONFIG_INET_TCP_DIAG=y
-+# CONFIG_TCP_CONG_ADVANCED is not set
-+CONFIG_TCP_CONG_CUBIC=y
-+CONFIG_DEFAULT_TCP_CONG="cubic"
-+# CONFIG_TCP_MD5SIG is not set
-+CONFIG_IPV6=m
-+# CONFIG_IPV6_PRIVACY is not set
-+# CONFIG_IPV6_ROUTER_PREF is not set
-+# CONFIG_INET6_AH is not set
-+# CONFIG_INET6_ESP is not set
-+# CONFIG_INET6_IPCOMP is not set
-+# CONFIG_IPV6_MIP6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-+CONFIG_INET6_XFRM_MODE_TUNNEL=m
-+CONFIG_INET6_XFRM_MODE_BEET=m
-+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-+CONFIG_IPV6_SIT=m
-+# CONFIG_IPV6_TUNNEL is not set
-+# CONFIG_IPV6_MULTIPLE_TABLES is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+# CONFIG_NETFILTER is not set
++2. Add ./arch/arm/mach-nomadik/<platform_name>_devices.c file
++      This file contains all the platfrom specific functions and data
++      structures used by rest of the code. Any driver suported for Nomadik
++      platform must access all the paramters through this file
++      (for ex. base addres, irq number and other plaform specific data
++       structures and function)
++      It is recommended to refer such file for already suported platform
 +
-+#
-+# DCCP Configuration (EXPERIMENTAL)
-+#
-+# CONFIG_IP_DCCP is not set
++3. Add ./include/asm-arm/arch-nomadik/<platform_name>_devices.h file
++      This file must contain all the declarations for this platform
++      which may be refered by the other drivers and kernel code.
++      Note that this file is refered by some assembly code hence the
++      content of this files must be maintained simple, standard and
++      generic.
++      It is recommended to refer such file for already suported platform
 +
-+#
-+# SCTP Configuration (EXPERIMENTAL)
-+#
-+# CONFIG_IP_SCTP is not set
++With the above addition/modification New target support will be available.
++Select newly supported target in kernel configuration, build and execute
++the code on new target
++===============================================================================
 +
-+#
-+# TIPC Configuration (EXPERIMENTAL)
-+#
-+# CONFIG_TIPC is not set
-+# CONFIG_ATM is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_LLC2 is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt
+@@ -0,0 +1,106 @@
++This HOWTO esplains mounting the root file system via NFS on Nomadik Platform (nfsroot)
 +
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
++As you know, all of us spend lot of time in-
++1.    Unzip/mount initrd to put the modules/application under test
++2.    Copying modules/applications to initrd
++3.    Unmount/gzip operation with initrd
++4.    Then load huge initrd and kernel each time to target board
++       for execution.
 +
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+# CONFIG_HAMRADIO is not set
-+# CONFIG_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_IEEE80211 is not set
++So for each time even for a small change we need to repeat this process, and
++downloading and system re-initialization eats lot of our development time.
++Nfsroot is a good solution to overcome above issues.
 +
-+#
-+# Device Drivers
-+#
++Root file system can be mounted via NFS (nfsroot) on host and can be accessed
++from your target machin.
 +
-+#
-+# Generic Driver Options
-+#
-+CONFIG_STANDALONE=y
-+CONFIG_PREVENT_FIRMWARE_BUILD=y
-+CONFIG_FW_LOADER=y
-+# CONFIG_DEBUG_DRIVER is not set
-+# CONFIG_SYS_HYPERVISOR is not set
++Advantages of this method are:-
++===============================
++1.    No need to download ramdiks time to time (saves lot of time)
++2.    Since file system is on NFS, runtime results/logs dooes not vanishes
++       in case of nomadik-system crash
++3.    Since file system is on NFS, it is transperant to host and target
++4.    Making, updating, mounting, unmounting, zipping, unzipping activities
++       associated with ramdisk can be totally avoided (saves lot of time)
++5.    Offers comfortable and fast development environment
 +
-+#
-+# Connector - unified userspace <-> kernelspace linker
-+#
-+# CONFIG_CONNECTOR is not set
++Host configuration to enable root NFS:-
++========================================
++1.    Copy a "target" folder from toolchain at some fixed path on your Linux
++       host
++2.      Switch to the dev folder of newly created target folder and create
++       a node for console with command "mknod console c 5 1"
++3.    Then swtich to the target folder and create a symbolic link with
++       command "ln -s /bin/busybox linuxrc
++4.    FTP and TFTP should be enabled on the host system. You can check the
++       configuration by issuing the following command
 +
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_CONCAT=y
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
++#> chkconfig --list | grep ftp
 +
-+#
-+# User Modules And Translation Layers
-+#
-+CONFIG_MTD_CHAR=y
-+# CONFIG_MTD_BLKDEVS is not set
-+# CONFIG_MTD_BLOCK is not set
-+# CONFIG_MTD_BLOCK_RO is not set
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+# CONFIG_INFTL is not set
-+# CONFIG_RFD_FTL is not set
-+# CONFIG_SSFDC is not set
++Output should look like :-
++vsftpd          0:off   1:off   2:on    3:on    4:on    5:on    6:off
++              gssftp:         off
++              tftp:           on
 +
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-+CONFIG_MTD_MAP_BANK_WIDTH_1=y
-+CONFIG_MTD_MAP_BANK_WIDTH_2=y
-+CONFIG_MTD_MAP_BANK_WIDTH_4=y
-+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-+CONFIG_MTD_CFI_I1=y
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+CONFIG_MTD_CFI_STAA=y
-+CONFIG_MTD_CFI_UTIL=y
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
++Note: Method of enabling FTP can be different for different versions of Linux.
 +
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-+# CONFIG_MTD_PHYSMAP is not set
-+CONFIG_MTD_NOMADIK=y
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_PLATRAM is not set
++5.    NFS should be enabled. Same can also be checked with the following
++       command
 +
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_DATAFLASH is not set
-+# CONFIG_MTD_M25P80 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_PHRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLOCK2MTD is not set
++#> chkconfig --list | grep nfs
 +
-+#
-+# Disk-On-Chip Device Drivers
-+#
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOC2001PLUS is not set
++Output should looklike
++nfs             0:off   1:off   2:on    3:on    4:on    5:on    6:off
 +
-+#
-+# NAND Flash Device Drivers
-+#
-+CONFIG_MTD_NAND=y
-+CONFIG_MTD_NAND_NOMADIK=y
-+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-+# CONFIG_MTD_NAND_ECC_SMC is not set
-+CONFIG_MTD_NAND_IDS=y
-+# CONFIG_MTD_NAND_DISKONCHIP is not set
-+# CONFIG_MTD_NAND_NANDSIM is not set
++6.    Also, check the entries of the /etc/xinetd.d/tftp file accordingly.
++       In our case, it is :
 +
-+#
-+# OneNAND Flash Device Drivers
-+#
-+# CONFIG_MTD_ONENAND is not set
++service tftp
++{
++        disable                       = no
++        socket_type                   = dgram
++        protocol                              = udp
++        wait                                  = yes
++        user                                  = root
++        server                                = /usr/sbin/in.tftpd
++        server_args                   = -T 100000000 -v -c -s
++/local_no_backup
++#       server_args                   = -s /tftpboot
++        per_source                    = 11
++        cps                                   = 100 2
++        flags                                 = IPv4
++}
 +
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
++7.    Also make the entries in /etc/exports for the file systems that need
++       to be shared. For options used, please refer the man pages of exports.
++       In our case, it is :
 +
-+#
-+# Plug and Play support
-+#
++/rtrt *(rw,insecure,no_root_squash,async)
++/local_no_backup/target *(rw,insecure,no_root_squash,async)
 +
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+# CONFIG_BLK_DEV_LOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_COUNT=16
-+CONFIG_BLK_DEV_RAM_SIZE=46080
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+CONFIG_BLK_DEV_INITRD=y
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
++How to enable NFS feature in your development?
++===============================================
++1.    Of cource you need to work on ethernet based environment
++2.    Enable ethernet driver in your kernel image
++3.    Enable following settings in your kernel image to enable nfsroot
++a.    Networking options  --->IP: kernel level autoconfiguration
++b.    Networking options  --->IP: BOOTP support
++c.    File systems  --->Network File Systems  --->NFS file system support
++d.    File systems  --->Network File Systems  --->Provide NFSv3 client support
++e.    File systems  --->Network File Systems  --->Root file system on NFS
++4.    Then compile kernel image, prepare uimage and download into the target
++5.    Set the command line arguments as -
 +
-+#
-+# SCSI device support
-+#
-+# CONFIG_RAID_ATTRS is not set
-+# CONFIG_SCSI is not set
-+# CONFIG_SCSI_NETLINK is not set
++ "set bootargs root=/dev/nfs nfsroot=<HOST_IP_ADDR>:/<PATH>/ramdisk
++ip=<TARGET_IP_ADDR>:<HOST_IP_ADDR>:<GATWAY_IP_ADDR_FOR_TARGET>:255.255.255.0:nomadik:: console=ttyAMA1 mac=<MAC_ADDRESS> init=linuxrc"
 +
-+#
-+# Serial ATA (prod) and Parallel ATA (experimental) drivers
-+#
-+# CONFIG_ATA is not set
++for example:-
++"set bootargs root=/dev/nfs nfsroot=10.199.3.88:/local_no_backup/target
++ip=10.199.32.165:10.199.3.88:10.199.32.254:255.255.255.0:NDK10_165::
++mac=00:0D:88:45:5D:A5 console=ttyAMA1,115200n8 init=linuxrc"
 +
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
++6.    And then boot the kernel with command "bootm 0x100000"
++       (initrd address not needed since NFS)
 +
-+#
-+# Fusion MPT device support
-+#
-+# CONFIG_FUSION is not set
++Start enjoying the advantages of root NFS
 +
-+#
-+# IEEE 1394 (FireWire) support
-+#
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt
+@@ -0,0 +1,66 @@
 +
-+#
-+# I2O device support
-+#
++ * 1.1 Nomadik Development Debugging Strategy
++ * ==========================================
++ *
++ * DEBUGGING LEVELS
++ * 0 To disable all debug messages
++ * 1 To enable normal debug macro- nmdk_dbg
++ * 2 To enable flow trace debug macro- nmdk_dbg_ftrace
++ * 4 To enable interrupt and timer debug macroc- nmdk_dbg2
++ * 8 To enable any special debug messages defined by macro- nmdk_dbg3
++ *
++ *
++ * 1.2 How to use Debuggign strategy in driver development ?
++ * =========================================================
++ *
++ * 1. include debug-nomadik.h file in c code
++ *    (path: include/asm-arm/arch/nomadik/debug-nomadik.h)
++ * 2. define NMDK_DEBUG to required debug level (this can be automated
++ *    to pass build time debug levels -as done for keypad driver.
++ *    See driver/input/keypad makefile)
++ * 3. define NMDK_DEBUG_PFX to a small string to identify debug message
++ *    This is an optional setting, if you don't define NMDK_DEBUG_PFX,
++ *    by default "Nomadik" will be selected.
++ * 4. define NMDK_DBG to desired Kerlen debug level
++ *    This is an optional setting, if you don't define NMDK_DBG,
++ *    by default KERN_DEBUG will be used
++ *    This generally need to set to KERN_ERR to force debug messages to
++ *    appear on the console
++ *
++ *
++ * 1.3 How to activate debug messages?
++ *====================================
++ *
++ * Debug messages can be activated during build time by passing desired
++ * debug level either hardcoding in source file or as a make parameter
++ *
++ * 1. Enabling Debug messages by passing additional parameter to make
++ *    This is a recommended method of debug messages implimentation.
++ *    this method give flexibility to enable/disable debug messages
++ *    during build without modifying code
++ *    (a) To enable this you need to updated driver make file with:-
++ *    ex.
++ *            ifdef <DRVNAME>_DEBUG
++ *            CFLAGS += -<DRVNAME>_DEBUG=$(<DRVNAME>_DEBUG)
++ *            endif
++ *
++ *    (b) Same <DRVNAME>_DEBUG must be used to define NMDK_DEBUG as
++ *    explained in (1.2.2)
++ *    (c) Debug parameter must be passed to the make with desired debug
++ *    level as explained in (1.1)
++ *            ex. make <DRVNAME>_DEBUG=1
++ *    (d) you can AND several debug levels togather to enable respective
++ *    debug mesages
++ *    (e) even you can pass additional parameters to enable debug messages
++ *    of more than one module
++ *            ex. make <DRV1>_DEBUG=1 <DRV2>_DEBUG=4 ...
++ *
++ * 2. Enabling Debug messages by hardcoding in source file
++ *    This is simplest implimentation, just define NMDK_DEBUG to
++ *    desired debug level and compile the code, the disadvantage of this
++ *    method is, it does not offer flexibility and code with debug message
++ *    may become part of your release if not taken care properly.
++ *
++ */
 +
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
 +
-+#
-+# PHY device support
-+#
-+# CONFIG_PHYLIB is not set
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt
+@@ -0,0 +1,420 @@
++Filename:     ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
++Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner:                STMicroelectronics
++Purpose:
++              This Users Guide explains DMA implimentation and its usage
++              for client drivers on Nomadik platforms
++=============================================================================
 +
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+CONFIG_MII=m
-+CONFIG_SMC91X=m
-+# CONFIG_DM9000 is not set
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
++2. you are familier with Kernal DMA interface
++      (References: ./Documentation/DMA-API.txt)
 +
-+#
-+# Ethernet (1000 Mbit)
-+#
++DMA Configuration:
++===================
++By default Nomadik DMA driver is configured to link staticlly with kernel.
++This DMA driver provides low level interface to the kernel DMA interface.
++To use DMA APIs, client driver should only include <asm/dma.h>
 +
-+#
-+# Ethernet (10000 Mbit)
-+#
++Definations:
++============
++1. DMA Channel: The logical DMA channel can be used for a DMA transfer
++2. Pipe: the physical DMA chanel H/w that is used to a DMA transfer
++3. DMAC: Direct Memory Access Controller (Nomadik has two DMACs)
 +
-+#
-+# Token Ring devices
-+#
++Brief Architecture:
++===================
++DMA dirver is registered as amba device and will be probed only if
++matches peripharal ID, the SOC specific data/function iterface is provided
++through platfrom_data pointer to allign driver design in sync with multiboard
++strategy.
++There are two DMA controllers having 8 pipes each, there could be number of
++dma channels which will use any one available pipe for dma transfer at run time
++Kernel DMA interface defines and controls the interface, whereas the h/w
++specific APIs are mapped through methods provided by upper layer (i,e.
++arch/arm/kernel/dma.c). The configuration, usage and features provided by this
++driver is explained below.
 +
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
++This Users guide explains-
++1. Support for Standard DMA APIs for Nomadik DMA usage
++2. Additional DMA APIs to facilitate effieient/flexible DMA usage
++3. DMA Channel configuration.
++   a) Mode of operation: Transfer type
++   b) Mode of operation: flow control
++   c) Mode of operation: Double Buffered Transfer
++   d) Mode of operation: Infinite DMA Transfer
++   e) Mode of operation: Infinite DMA Transfer
++   f) Mode of operation: Pipe reservation
++   g) Mode of operation: Channel Priority
++   h) Mode of operation: Queueing DMA transfer requests
++4. DMA Interrupt hanndling for callback functions.
++5. Scatter-gather Support
++6. /proc/dma interfce.
++7. HOWTO add new DMAable peripharal device support
 +
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+# CONFIG_SHAPER is not set
-+# CONFIG_NETCONSOLE is not set
-+# CONFIG_NETPOLL is not set
-+# CONFIG_NET_POLL_CONTROLLER is not set
++1. Support for Standard DMA APIs for Nomadik DMA usage
++======================================================
++Standard kernel DMA interface exports APIs out of which request_dma, enable_dma,
++disable_dma, free_dma, dma_channel_active, set_dma_sg, __set_dma_addr, set_dma_count,
++are supported for Nomadik DMA Usage.
++For any DMA transfer you need to follow a sequence-
++  a) request_dma      : to request a DMA channel be to used for transfer,
++                        in this request you need to pass configuration
++  b) request_irq      : to register DMA callback function
++  c) __set_dma_srcaddr        : to set src DMAble address (mapped to __set_dma_addr)
++  d) __set_dma_destaddr       : to set dest DMAble address (mapped to set_dma_speed)
++  e) set_dma_count    : to set transfer size in bytes
++  f) set_dma_mode     : to set/ulter mode of operation (optional)
++  g) enable_dma               : to start transfer
++  h) dma_channel_active : to know the status of scheduled transfer (optional)
++  i) disable dma      : to stop transfer (optional)
++  j) free_irq         : to free irq used for callback (optional)
++  k) free_dma         : to free requested DMA channel
 +
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
++2. Additional DMA APIs for effieient/flexible DMA usage
++=======================================================
++Following additional APIs are provided for effieient/flexible DMA usage
++  a) request_available_dma
++                      : This is a wrapper over request_dma,
++                        this API will search, allocate and return available
++                        free DMA channel.
++  b) suspend_DMA      : to pause currently active DMA transfer
++  c) resume_DMA               : to resume previously paused DMA transfer
 +
-+#
-+# Input device support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_FF_MEMLESS is not set
++3. DMA Channel Configureation:
++==============================
++Durring request_dma system call you need to pass a pointer of pre-filled DMA
++Channel configuration structure nmdk_dma_info defined in asm/arch/dma.h
++i.e.-
++struct nmdk_dma_info {
++      u32 mode;               /* Mode of operation(xfer type/flow cntrl etc)*/
++      char *srcdevtype;       /* source device type configuration*/
++      char *destdevtype;      /* desitnation device type configuration*/
++      u32 config;             /* User programmable dmadev configuration*/
++};
 +
-+#
-+# Userland interfaces
-+#
-+CONFIG_INPUT_MOUSEDEV=m
-+CONFIG_INPUT_MOUSEDEV_PSAUX=y
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_TSDEV is not set
-+CONFIG_INPUT_EVDEV=m
-+# CONFIG_INPUT_EVBUG is not set
++Each DMA channle has source DMA device and a destination DMA device, a DMA
++channel is a hardware that connects two DMAable devices for data transfer.
++So to have a successfull DMA transfer you need to configure all these three.
++Below picture gives some idea about it-
 +
-+#
-+# Input Device Drivers
-+#
-+CONFIG_INPUT_KEYBOARD=y
-+# CONFIG_KEYBOARD_ATKBD is not set
-+# CONFIG_KEYBOARD_SUNKBD is not set
-+# CONFIG_KEYBOARD_LKKBD is not set
-+# CONFIG_KEYBOARD_XTKBD is not set
-+# CONFIG_KEYBOARD_NEWTON is not set
-+# CONFIG_KEYBOARD_STOWAWAY is not set
-+CONFIG_KEYPAD_NOMADIK=m
-+# CONFIG_INPUT_MOUSE is not set
-+# CONFIG_INPUT_JOYSTICK is not set
-+CONFIG_INPUT_TOUCHSCREEN=y
-+# CONFIG_TOUCHSCREEN_ADS7846 is not set
-+# CONFIG_TOUCHSCREEN_GUNZE is not set
-+# CONFIG_TOUCHSCREEN_ELO is not set
-+# CONFIG_TOUCHSCREEN_MTOUCH is not set
-+# CONFIG_TOUCHSCREEN_MK712 is not set
-+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-+# CONFIG_TOUCHSCREEN_UCB1400 is not set
-+CONFIG_TOUCHSCREEN_NOMADIK=m
-+# CONFIG_INPUT_MISC is not set
 +
-+#
-+# Hardware I/O ports
-+#
-+# CONFIG_SERIO is not set
-+# CONFIG_GAMEPORT is not set
++                      --------------------
++   srcdevtype, src_addr |                | destdevtype, dest_addr
++   def dmadev config  |                  | default dmadev configuration
++                      |                  |
++ (Src DMA periph)------>|    DMA Channel   |--------> (Dest DMA peripharal)
++                      |                  |
++                      --------------------
++                      (mode of  operation)
++                      (User configuration)
++                      (Xfer Size in bytes)
 +
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_HW_CONSOLE=y
-+# CONFIG_VT_HW_CONSOLE_BINDING is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
++DMAable devices and their default configurations are SOC specific and declared
++in arch/arm/mach-nomadik/<SOC_NAME>_devices.c file (will be explained latter
++in this guide). Each DMAble device is identified by unique name, during
++configuration the src and dest dmadev names need to be specified.
 +
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_8250 is not set
++Transfer Size in bytes, src_addr and dest_addr not a part of configuration as
++they keeps changing and need to be provided before enable_dma request
 +
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+CONFIG_SERIAL_AMBA_PL011=y
-+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_LEGACY_PTYS=y
-+CONFIG_LEGACY_PTY_COUNT=256
++User programmable dmadev configuration: These are optional configuration on
++the top of default for the changable paramters (specially Brust size and
++transfer width). This will be exmpained latter in this guide
 +
-+#
-+# IPMI
-+#
-+# CONFIG_IPMI_HANDLER is not set
++for ex, to configure a dma chnnel for memory to MSP peripharal DMA transfer
++the sructure should be filled as-
 +
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+CONFIG_HW_RANDOM=m
-+# CONFIG_NVRAM is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_RAW_DRIVER is not set
++      struct nmdk_dma_info test_dma_config =
++      {
++              .mode    = MEM_TO_MEM,
++              .srcdevtype = "mem",
++              .destdevtype = "msp0rx",
++              .config = NULL,
++      };
 +
-+#
-+# TPM devices
-+#
-+# CONFIG_TCG_TPM is not set
++Out of all configuration parameter "mode" is very important since it decides
++the mode of DMA channel operation, there are several features supported all
++are configurable through mode.
 +
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+CONFIG_I2C_CHARDEV=y
++   a) Mode of operation: Transfer type
++      there are four basic modes of operation those are
++      MEM_TO_MEM,     MEM_TO_PERIPH,  PERIPH_TO_MEM,  PERIPH_TO_PERIPH
++      you should program any one as per you need.
 +
-+#
-+# I2C Algorithms
-+#
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
++      for ex. dma_info.mode=MEM_TO_PERIPH;
 +
-+#
-+# I2C Hardware Bus support
-+#
-+CONFIG_I2C_NOMADIK=y
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_STUB is not set
-+# CONFIG_I2C_PCA_ISA is not set
++   b) Mode of operation: flow control
++      By default flow controller is DMA controller, if you want to program
++      flow controller as peripharal you can use the provided macros as
 +
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 is not set
-+# CONFIG_SENSORS_PCA9539 is not set
-+# CONFIG_SENSORS_PCF8591 is not set
-+# CONFIG_SENSORS_MAX6875 is not set
-+# CONFIG_I2C_DEBUG_CORE is not set
-+# CONFIG_I2C_DEBUG_ALGO is not set
-+# CONFIG_I2C_DEBUG_BUS is not set
-+# CONFIG_I2C_DEBUG_CHIP is not set
++      for ex. dma_info.mode=FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++      To mention the flow controller is DMA controller.
 +
-+#
-+# SPI support
-+#
-+CONFIG_SPI=y
-+# CONFIG_SPI_DEBUG is not set
-+CONFIG_SPI_MASTER=y
++      for ex. dma_info.mode=FLOW_CNTRL_PERIPH(MEM_TO_PERIPH);
++      To mention the flow controller is peripharal controller.
 +
-+#
-+# SPI Master Controller Drivers
-+#
-+# CONFIG_SPI_BITBANG is not set
-+CONFIG_NOMADIK_SPI=m
++      Flow controller device cannot be peripharal for MEM_TO_MEM transter
 +
-+#
-+# SPI Protocol Masters
-+#
++   c) Mode of operation: Double Buffered Transfer
++      There are some peripharals like SAA(Smart Audio Accelerator) who
++      requires DMA transfers to be done in double buffer mode, in double
++      buffered mode of operation the current dma requested in divided in two,
++      equal sequential transfers before scheduling.
 +
-+#
-+# Dallas's 1-wire bus
-+#
-+# CONFIG_W1 is not set
++      By default standard single buffered transfer mode is programmed,
++      to configure Double Buffered Transfer mode a macro DMA_DOUBLE_BUFFERED
++      should be ORed with other configuration parameters
 +
-+#
-+# Hardware Monitoring support
-+#
-+CONFIG_HWMON=y
-+# CONFIG_HWMON_VID is not set
-+# CONFIG_SENSORS_ABITUGURU is not set
-+# CONFIG_SENSORS_ADM1021 is not set
-+# CONFIG_SENSORS_ADM1025 is not set
-+# CONFIG_SENSORS_ADM1026 is not set
-+# CONFIG_SENSORS_ADM1031 is not set
-+# CONFIG_SENSORS_ADM9240 is not set
-+# CONFIG_SENSORS_ASB100 is not set
-+# CONFIG_SENSORS_ATXP1 is not set
-+# CONFIG_SENSORS_DS1621 is not set
-+# CONFIG_SENSORS_F71805F is not set
-+# CONFIG_SENSORS_FSCHER is not set
-+# CONFIG_SENSORS_FSCPOS is not set
-+# CONFIG_SENSORS_GL518SM is not set
-+# CONFIG_SENSORS_GL520SM is not set
-+# CONFIG_SENSORS_IT87 is not set
-+# CONFIG_SENSORS_LM63 is not set
-+# CONFIG_SENSORS_LM70 is not set
-+# CONFIG_SENSORS_LM75 is not set
-+# CONFIG_SENSORS_LM77 is not set
-+# CONFIG_SENSORS_LM78 is not set
-+# CONFIG_SENSORS_LM80 is not set
-+# CONFIG_SENSORS_LM83 is not set
-+# CONFIG_SENSORS_LM85 is not set
-+# CONFIG_SENSORS_LM87 is not set
-+# CONFIG_SENSORS_LM90 is not set
-+# CONFIG_SENSORS_LM92 is not set
-+# CONFIG_SENSORS_MAX1619 is not set
-+# CONFIG_SENSORS_PC87360 is not set
-+# CONFIG_SENSORS_PC87427 is not set
-+# CONFIG_SENSORS_SMSC47M1 is not set
-+# CONFIG_SENSORS_SMSC47M192 is not set
-+# CONFIG_SENSORS_SMSC47B397 is not set
-+# CONFIG_SENSORS_VT1211 is not set
-+# CONFIG_SENSORS_W83781D is not set
-+# CONFIG_SENSORS_W83791D is not set
-+# CONFIG_SENSORS_W83792D is not set
-+# CONFIG_SENSORS_W83793 is not set
-+# CONFIG_SENSORS_W83L785TS is not set
-+# CONFIG_SENSORS_W83627HF is not set
-+# CONFIG_SENSORS_W83627EHF is not set
-+# CONFIG_HWMON_DEBUG_CHIP is not set
++      for ex. dma_info.mode=DMA_DOUBLE_BUFFERED |
++                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
 +
-+#
-+# Misc devices
-+#
-+# CONFIG_TIFM_CORE is not set
++   d) Mode of operation: Infinite DMA Transfer
++      If you want to establish DMA transafer between two DMAble devices
++      infinitely without CPUs intervention, this means once transfer is
++      scheduled, it will reschedule it self at completion automatically.
 +
-+#
-+# LED devices
-+#
-+# CONFIG_NEW_LEDS is not set
++      By default infinite DMA transfer is disabled,
++      to configure Infinite DMA Transfer mode a macro DMA_INFINITE_XFER
++      should be ORed with other configuration parameters
 +
-+#
-+# LED drivers
-+#
++      for ex. dma_info.mode=DMA_INFINITE_XFER |
++                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
 +
-+#
-+# LED Triggers
-+#
++      In Infinite DMA transfer mode, you will never receive completion
++      interrupt and callback interrupt handler cannot be executed
 +
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
++   e) Mode of operation: Pipe reservation
++      Reserving a pipe will dediate a pipe for a channel
++      By default pipe is not reserved at the time of configuration. when you
++      schedule a enable_dma request, system looks for the available pipe and
++      schedules a transfer on it. This adds more flexibility to system to
++      handle more channels on limited pipes. In case the all the pipes are
++      busy the request will be deffered,
++      if you want to avoid this behavior, i.e. whenever you request enable_dma
++      pipe must be available to execute it, then you can reserve a pipe during
++      configuration.
 +
-+#
-+# Digital Video Broadcasting Devices
-+#
-+# CONFIG_DVB is not set
++      to reserve a pipe, a macro DMA_PIPE_RESERVED
++      should be ORed with other configuration parameters
 +
-+#
-+# Graphics support
-+#
-+CONFIG_FIRMWARE_EDID=y
-+CONFIG_FB=y
-+CONFIG_FB_CFB_FILLRECT=y
-+CONFIG_FB_CFB_COPYAREA=y
-+CONFIG_FB_CFB_IMAGEBLIT=y
-+# CONFIG_FB_MACMODES is not set
-+# CONFIG_FB_BACKLIGHT is not set
-+CONFIG_FB_MODE_HELPERS=y
-+# CONFIG_FB_TILEBLITTING is not set
-+CONFIG_FB_ARMCLCD=y
-+# CONFIG_FB_S1D13XXX is not set
-+# CONFIG_FB_VIRTUAL is not set
++      for ex. dma_info.mode=DMA_PIPE_RESERVED |
++                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
 +
-+#
-+# Console display driver support
-+#
-+# CONFIG_VGA_CONSOLE is not set
-+CONFIG_DUMMY_CONSOLE=y
-+CONFIG_FRAMEBUFFER_CONSOLE=y
-+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-+CONFIG_FONTS=y
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+# CONFIG_FONT_6x11 is not set
-+# CONFIG_FONT_7x14 is not set
-+# CONFIG_FONT_PEARL_8x8 is not set
-+# CONFIG_FONT_ACORN_8x8 is not set
-+# CONFIG_FONT_MINI_4x6 is not set
-+# CONFIG_FONT_SUN8x16 is not set
-+# CONFIG_FONT_SUN12x22 is not set
-+# CONFIG_FONT_10x18 is not set
++   g) Mode of operation: Channel Priority
++      At hardware level there are total 16 DMA pipes (i.e. 8 on each
++      DMAC) each having its priority (i.e. pipe 0 having highest and 7 with
++      lowest). but since the pipes are allocated dynamically you never know
++      which pipe will be assigned to which channel. To take care of this
++      issue driver has in-built channel priority policy manager
 +
-+#
-+# Logo configuration
-+#
-+CONFIG_LOGO=y
-+CONFIG_LOGO_LINUX_MONO=y
-+CONFIG_LOGO_LINUX_VGA16=y
-+CONFIG_LOGO_LINUX_CLUT224=y
-+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++      Priority        DMAC0 PIPES     DMAC1 PIPES     Policy
++              -----------------------------------------------------
++      Highest         | 0  |          | 1  |          HIGH
++      .               | 2  |          | 3  |          (0->15)
++      .       -----------------------------------------------------
++      .               | 4  |          | 5  |          NORMAL
++      .               | 6  |          | 7  |          (4->15)
++      .       -----------------------------------------------------
++      .               | 8  |          | 9  |          LOW
++      .               | 10 |          | 11 |          (8->15)
++      .       -----------------------------------------------------
++      .               | 12 |          | 13 |  UNDEFINED (fm 15->0)
++      Lowest          | 14 |          | 15 |  For MEM-To MEM Xfer (15->12)
++              -----------------------------------------------------
 +
-+#
-+# Sound
-+#
-+CONFIG_NOMADIK_ACODEC=m
-+CONFIG_NOMADIK_STW5094=y
-+# CONFIG_NOMADIK_STW5095 is not set
-+CONFIG_SOUND=m
++      Channel priority setup during configuration tells additional
++      information to the driver that the channel under request has a
++      particular priority. And the pipe allocation policy of a driver
++      allocates a pipe accordingly for a transfer under schedule.
 +
-+#
-+# Advanced Linux Sound Architecture
-+#
-+CONFIG_SND=m
-+CONFIG_SND_TIMER=m
-+CONFIG_SND_PCM=m
-+# CONFIG_SND_SEQUENCER is not set
-+# CONFIG_SND_MIXER_OSS is not set
-+# CONFIG_SND_PCM_OSS is not set
-+# CONFIG_SND_DYNAMIC_MINORS is not set
-+CONFIG_SND_SUPPORT_OLD_API=y
-+CONFIG_SND_VERBOSE_PROCFS=y
-+# CONFIG_SND_VERBOSE_PRINTK is not set
-+# CONFIG_SND_DEBUG is not set
++      By default DMA_EXCH_PRIORITY_UNDEFINED is set for each channel, as
++      per policy the free and available pipe search will be started from
++      lowest to highest.
++      there are three other priorities HIGH, NORMAL and LOW which can be set
++      by ORing respective macro with other configuration parameters
 +
-+#
-+# Generic devices
-+#
-+# CONFIG_SND_DUMMY is not set
-+# CONFIG_SND_MTPAV is not set
-+# CONFIG_SND_SERIAL_U16550 is not set
-+# CONFIG_SND_MPU401 is not set
++      for ex. dma_info.mode=DMA_EXCH_PRIORITY_HIGH |
++                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
 +
-+#
-+# ALSA ARM devices
-+#
-+CONFIG_SND_NOMADIK_ALSA=m
-+# CONFIG_SND_ARMAACI is not set
++      Channel priority setup macros for configurations-
++      DMA_EXCH_PRIORITY_UNDEFINED
++      DMA_EXCH_PRIORITY_LOW
++      DMA_EXCH_PRIORITY_NORMAL
++      DMA_EXCH_PRIORITY_HIGH
 +
-+#
-+# Open Sound System
-+#
-+# CONFIG_SOUND_PRIME is not set
++   h) Mode of operation: Queueing DMA transfer requests
++      In the standard kernel DMA interface channel queueing is not allowed
++      once enable_dma request is executed system discards all subsequent
++      enable_dma request untill DMA finishes first scheduled request.
++      Nomadik DMA driver provides you flexibility to enable and use this
++      feature if required. Enabling this feature will accept all subsequent
++      enable_dma requests and queue them in a pipe, as system finishes
++      current transfer, next pre-scheduled transfer in a queue will be
++      executed, thus all enable_dma requests can be processed.
 +
-+#
-+# HID Devices
-+#
-+CONFIG_HID=y
++      This feature can be enabled by ORing a macro DMA_QUEUE_ENABLED with
++      other configuration parameters
 +
-+#
-+# USB support
-+#
-+CONFIG_USB_ARCH_HAS_HCD=y
-+# CONFIG_USB_ARCH_HAS_OHCI is not set
-+# CONFIG_USB_ARCH_HAS_EHCI is not set
-+# CONFIG_USB is not set
++      for ex. dma_info.mode=DMA_QUEUE_ENABLED |
++                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
 +
-+#
-+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-+#
++4. DMA Interrupt hanndling for callback functions.
++======================================================
++When you schedule a DMA transfer, there should be a mechanism by which you know
++the transfer is finished sucessfully. In Nomadik DMA transfer a terminal
++count interrupt will be generated at the end of sucessfull transfer which can
++be requested and processed like any other standard interrupt.
 +
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
++There are S/w decoded IRQs associated with all DMA channels.
++the macro IRQNO_FOR_DMACH(dmach) is provided to find irq for a DMA channel and
++the macro DMACH_FOR_IRQNO(irq) can be used to find DMA channel for irq number
 +
-+#
-+# MMC/SD Card support
-+#
-+CONFIG_MMC=m
-+# CONFIG_MMC_DEBUG is not set
-+CONFIG_MMC_BLOCK=m
-+# CONFIG_MMC_ARMMMCI is not set
-+# CONFIG_MMC_WBSD is not set
-+# CONFIG_MMC_TIFM_SD is not set
-+CONFIG_MMC_NOMADIK=m
-+CONFIG_NOMADIK_MMC_DMA=y
-+# CONFIG_NOMADIK_MMC_POLL is not set
-+# CONFIG_NOMADIK_MMC_INTR is not set
++The DMA callback functions can be invoked as interrupt handler and requested
++through standard system calls i.e request_irq and free_irq.
 +
-+#
-+# Real Time Clock
-+#
-+CONFIG_RTC_LIB=y
-+# CONFIG_RTC_CLASS is not set
++It is recommented to use your own tasklets to do deffered processing
++since it may block other DMA interuppts being processed in time.
 +
-+#
-+# File systems
-+#
-+CONFIG_EXT2_FS=y
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XIP is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_EXT4DEV_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_JFS_FS is not set
-+# CONFIG_FS_POSIX_ACL is not set
-+# CONFIG_XFS_FS is not set
-+# CONFIG_GFS2_FS is not set
-+# CONFIG_OCFS2_FS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_FUSE_FS is not set
++Below system messages indicates that irqno 188 to 191 are DMA interrupts
++root@NDK10_A0:/home/prafulla/alsa# cat /proc/interrupts
++           CPU0
++  4:      12077:PL02          -  Nomadik Timer Tick
++ 10:          0               -  rtc
++ 11:          0               -  ssp
++ 17:        581:PL08          -  uart-pl011
++ 19:          6:PL10          -  msp
++ 20:         33               -  i2c0
++ 21:        296               -  i2c1
++ 22:         81:PL02          -  NMDK_MMC (data)
++ 26:          1               -  SAA0
++ 27:          0               -  SAA1
++113:          0               -  mmc_detect
++168:      19176:PL08          -  eth0
++188:         46           dummy  dmaclbk-sdmmc->mem
++189:          0           dummy  <NULL>
++190:      10462           dummy  dmaclbk-msp0rx->mem
++191:      10437           dummy  dmaclbk-mem->msp0tx
++Err:          0
 +
-+#
-+# CD-ROM/DVD Filesystems
-+#
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_UDF_FS is not set
++5. Scatter-gather Support
++======================================================
++The Nomadik DMA driver supprts scatter-gather transfer for MEM_TO_PERIPH and
++PERIPH_TO_MEM type of data transfer. to use scatter gather suport following
++sequence must be executed.
++      a) request_dma, request_irq
++      b) get the *sg and sg_len form the upper layers
++      c) execute dma_map_sg with above information
++      d) set peripharal DMA address (__set_dma_srcaddr / __set_dma_srcaddr)
++      e) set memory DMA address using set_dma_sg API with sg information
++      f) set_dma_count for transfer size
++      g) execute enable_dma
++      h) wait for transfer complete event through callback
++      i) unmap sg list using dma_unmap_sg
++      j) free_dma
 +
-+#
-+# DOS/FAT/NT Filesystems
-+#
-+CONFIG_FAT_FS=m
-+# CONFIG_MSDOS_FS is not set
-+CONFIG_VFAT_FS=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="cp437"
-+# CONFIG_NTFS_FS is not set
++6. /proc/dma interfce.
++======================================================
++/proc/dma entry is created to show the information of allocated DMA resources
++executing cat /proc/dma will list the allocation of all used DMA channles
 +
-+#
-+# Pseudo filesystems
-+#
-+CONFIG_PROC_FS=y
-+CONFIG_PROC_SYSCTL=y
-+CONFIG_SYSFS=y
-+CONFIG_TMPFS=y
-+# CONFIG_TMPFS_POSIX_ACL is not set
-+# CONFIG_HUGETLB_PAGE is not set
-+CONFIG_RAMFS=y
-+# CONFIG_CONFIGFS_FS is not set
++for ex-
++root@NDK10_A0:/home/prafulla/alsa# cat /proc/dma
++ 0:         DMACH: sdmmc->mem
++ 1:         DMACH: mem->sdmmc
++ 2:         DMACH: msp0rx->mem
++ 3:         DMACH: mem->msp0tx
 +
-+#
-+# Miscellaneous filesystems
-+#
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_HFSPLUS_FS is not set
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+CONFIG_JFFS2_FS_WRITEBUFFER=y
-+# CONFIG_JFFS2_SUMMARY is not set
-+# CONFIG_JFFS2_FS_XATTR is not set
-+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-+CONFIG_JFFS2_ZLIB=y
-+CONFIG_JFFS2_RTIME=y
-+# CONFIG_JFFS2_RUBIN is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
++7. HOWTO add new DMA peripharal device support
++======================================================
++As per multiboard strategy
++(ref : ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt)
++for each supported SOC there is an arch/arm/mach-nomadik/<SOC>_devices.c
++In this file there is data structure "dmadev_default_config_tbl"
++Add a new entry for the table for new DMA peripharal device
++(refer Architecture.DMA Support Chapter fo SOC specification)
 +
-+#
-+# Network File Systems
-+#
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+# CONFIG_NFS_V3_ACL is not set
-+CONFIG_NFS_V4=y
-+# CONFIG_NFS_DIRECTIO is not set
-+# CONFIG_NFSD is not set
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=y
-+CONFIG_SUNRPC_GSS=y
-+CONFIG_RPCSEC_GSS_KRB5=y
-+# CONFIG_RPCSEC_GSS_SPKM3 is not set
-+# CONFIG_SMB_FS is not set
-+# CONFIG_CIFS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_CODA_FS is not set
-+# CONFIG_AFS_FS is not set
-+# CONFIG_9P_FS is not set
++for ex-
++      {.id = "sdmmc",
++         .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD |
++                DMA_BSIZE_8 | DMA_REQUEST_LINE(21) |
++              DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE |
++                DMA_DEV_DMAC1_CANBE_USED  ),},
 +
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
++      explaination:
++      id:     This is the unique identification string will be used in
++              configuration as srcdevtype or destdevtype.
++      config: This should be ORed value of following selection
++          a)  DMA_AHB_M0      : to select AHB master 0 for this device
++              or
++              DMA_AHB_M1      : to select AHB master 1 for this device
 +
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS=y
-+CONFIG_NLS_DEFAULT="cp437"
-+CONFIG_NLS_CODEPAGE_437=m
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+# CONFIG_NLS_CODEPAGE_850 is not set
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+# CONFIG_NLS_ASCII is not set
-+# CONFIG_NLS_ISO8859_1 is not set
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
++          b)  DMA_ADR_INC     : to indicate DMA address is incremented after
++                                each transfer (memory, buffer case)
++              or
++              DMA_ADR_NOINC   : to indicate DMA address is not incremented
++                                after each transfer (fifo case)
 +
-+#
-+# Distributed Lock Manager
-+#
-+# CONFIG_DLM is not set
++          c)  DMA_WIDTH_WORD  : to select word(32bits) as transfer width
++              or
++              DMA_WIDTH_HALFWORD: to select halfword(16bits) as transfer width
++              or
++              DMA_WIDTH_BYTE  : to select byte(8bits) as transfer width
 +
-+#
-+# Profiling support
-+#
-+# CONFIG_PROFILING is not set
++          d)  DMA_BSIZE_1     : to indicate 1 byte makes one DMA brust
++              or
++              DMA_BSIZE_4     : to indicate 4 bytes makes one DMA brust
++              or
++              DMA_BSIZE_8     : to indicate 8 bytes makes one DMA brust
++              or
++              DMA_BSIZE_16    : to indicate 16 bytes makes one DMA brust
++              or
++              DMA_BSIZE_32    : to indicate 32 bytes makes one DMA brust
++              or
++              DMA_BSIZE_64    : to indicate 64 bytes makes one DMA brust
++              or
++              DMA_BSIZE_128   : to indicate 128 bytes makes one DMA brust
++              or
++              DMA_BSIZE_256   : to indicate 256 bytes makes one DMA brust
 +
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_MUST_CHECK=y
-+CONFIG_MAGIC_SYSRQ=y
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+CONFIG_DEBUG_KERNEL=y
-+CONFIG_LOG_BUF_SHIFT=14
-+CONFIG_DETECT_SOFTLOCKUP=y
-+# CONFIG_SCHEDSTATS is not set
-+# CONFIG_DEBUG_SLAB is not set
-+CONFIG_DEBUG_PREEMPT=y
-+# CONFIG_DEBUG_RT_MUTEXES is not set
-+# CONFIG_RT_MUTEX_TESTER is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+CONFIG_DEBUG_MUTEXES=y
-+# CONFIG_DEBUG_RWSEMS is not set
-+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-+# CONFIG_DEBUG_KOBJECT is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_DEBUG_VM is not set
-+# CONFIG_DEBUG_LIST is not set
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_FORCED_INLINING is not set
-+# CONFIG_RCU_TORTURE_TEST is not set
-+# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
-+# CONFIG_KGDB is not set
-+# CONFIG_DEBUG_USER is not set
-+# CONFIG_DEBUG_ERRORS is not set
-+# CONFIG_DEBUG_LL is not set
++          e)  DMA_REQUEST_LINE(x) : program peripharal request line number
++                                    (x less than 32)
 +
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+# CONFIG_SECURITY is not set
++          f)  DMA_DEV_BSIZE_CONFIGURABLE: to indicate the burst size can be
++                                probrammed by user
++              or
++              DMA_DEV_BSIZE_NOT_CONFIGURABLE: to indicate the burst size can
++                                not be probrammed by user
++          g)  DMA_DEV_DWIDTH_CONFIGURABLE: to indicate the transfer width can
++                                be probrammed by user
++              or
++              DMA_DEV_DWIDTH_NOT_CONFIGURABLE: to indicate the transfer width
++                                can not be probrammed by user
 +
-+#
-+# Cryptographic options
-+#
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+CONFIG_CRYPTO_MANAGER=y
-+# CONFIG_CRYPTO_HMAC is not set
-+# CONFIG_CRYPTO_XCBC is not set
-+# CONFIG_CRYPTO_NULL is not set
-+# CONFIG_CRYPTO_MD4 is not set
-+CONFIG_CRYPTO_MD5=y
-+# CONFIG_CRYPTO_SHA1 is not set
-+# CONFIG_CRYPTO_SHA256 is not set
-+# CONFIG_CRYPTO_SHA512 is not set
-+# CONFIG_CRYPTO_WP512 is not set
-+# CONFIG_CRYPTO_TGR192 is not set
-+# CONFIG_CRYPTO_GF128MUL is not set
-+CONFIG_CRYPTO_ECB=m
-+CONFIG_CRYPTO_CBC=y
-+# CONFIG_CRYPTO_LRW is not set
-+CONFIG_CRYPTO_DES=y
-+# CONFIG_CRYPTO_BLOWFISH is not set
-+# CONFIG_CRYPTO_TWOFISH is not set
-+# CONFIG_CRYPTO_SERPENT is not set
-+# CONFIG_CRYPTO_AES is not set
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+# CONFIG_CRYPTO_ARC4 is not set
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+# CONFIG_CRYPTO_MICHAEL_MIC is not set
-+# CONFIG_CRYPTO_CRC32C is not set
-+# CONFIG_CRYPTO_TEST is not set
++          h)  DMA_DEV_DMAC1_CANBE_USED: to indicate DMA controller1 can be
++                                used for the transfer
++              or
++              DMA_DEV_DMAC0_CANBE_USED: to indicate DMA controller0 can be
++                                used for the transfer
++              or
++              DMA_DEV_BOTH_DMACS_CANBE_USED: to indicate both DMA controllers
++                                0 and 1 can be used for the transfer
 +
-+#
-+# Hardware crypto devices
-+#
++8. System Limitations and Solutions:
++=====================================
++1. MAX_DMA_CHANNELS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
++     that defiens max no. of dma channels that can be used simultenously. if in
++     complex system scenario these channels are insuffienent, you may increase
++     this number as per your needs.
++2. MAX_DMA_LLIS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
++     that defiens max no. of LLIs used internally by dma driver. lli pool is
++     internally maitained by driver and aquired whenver there is a enable_dma
++     request and freed at each dma transfer completion. In a dynamic system
++     usage a run time message "unable to find free lli.. rechecking..." can be
++     observed, if such case you may increase the defined value for this macro,
++     Assiging very large value eats free DMAble memory.
 +
-+#
-+# Library routines
-+#
-+CONFIG_BITREVERSE=y
-+# CONFIG_CRC_CCITT is not set
-+# CONFIG_CRC16 is not set
-+CONFIG_CRC32=y
-+CONFIG_LIBCRC32C=m
-+CONFIG_ZLIB_INFLATE=y
-+CONFIG_ZLIB_DEFLATE=y
-+CONFIG_PLIST=y
-+CONFIG_IOMAP_COPY=y
-diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk15b06_defconfig
---- linux-2.6.20/arch/arm/configs/ndk15b06_defconfig   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/configs/ndk15b06_defconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1221 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.20
-+# Thu Aug 16 17:22:36 2007
-+#
-+CONFIG_ARM=y
-+# CONFIG_GENERIC_TIME is not set
-+CONFIG_MMU=y
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++==============================================================================
 +
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_LOCK_KERNEL=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
 +
-+#
-+# General setup
-+#
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_IPC_NS is not set
-+# CONFIG_POSIX_MQUEUE is not set
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+# CONFIG_TASKSTATS is not set
-+# CONFIG_UTS_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_INITRAMFS_SOURCE=""
-+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-+CONFIG_SYSCTL=y
-+CONFIG_EMBEDDED=y
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_ALL is not set
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_EPOLL=y
-+CONFIG_SHMEM=y
-+CONFIG_SLAB=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+# CONFIG_SLOB is not set
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt
+@@ -0,0 +1,53 @@
++Filename:     ./Documentation/arm/STM-Nomadik/faqs.txt
++Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner:                STMicroelectronics
++Purpose:
++              This documents describes frequesnty occuring problems and
++              their brief solutions while using Nomadik-BSP
++=============================================================================
 +
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+# CONFIG_MODULE_FORCE_UNLOAD is not set
-+# CONFIG_MODVERSIONS is not set
-+# CONFIG_MODULE_SRCVERSION_ALL is not set
-+# CONFIG_KMOD is not set
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
 +
-+#
++F.A.Qs
++======
++Q: I am not getting console on CLCD even though CLCD is enabled
++A: check your command line arguments, there should not be any console related
++   configuration, in this case by default console will be configured to CLCD.
++   In this case system will seek console input from standard input device.
++
++Q: NFS boot is giving messages "server not responding" very frequently
++A: This may be due to network congestion, try NFS boot using "tcp" option
++   (Ex. root=/dev/nfs nfsroot=<server_ipadr>:<mount_point_path>,tcp
++    ip=<host_ipadr>:<server_ipadr>:<gateway_ipard>:255.255.255.0:<hostname>::
++    console=ttyAMA1 mem=64M init=linuxrc)
++
++Q.  How to enable/Disable cursor on CLCD panel?
++A. Create a dummy node "mknod /dev/dummy c 4 0 ".
++   execute a command "echo -e "\033[?1c" > /dev/dummy" to disable the cursor
++   and "echo -e "\033[?0c" > /dev/dummy" to enable the cursor
++   You can also use the "setterm" program to control this and other aspects of
++   the console. "setterm -cursor off > /dev/tty0" will do what you want.
++   "man setterm" will give a vast list of stuff.
++   There is more here:
++   http://linux.bri.st.com/docs/manual/distribution/distribution_guide10.php
++
++Q. How to disable CLCD screen blanking
++A. Create a dummy node "mknod /dev/dummy c 4 0 ".
++   Execute a command "echo -e "\033[9;0]" > /dev/dummy", this will set
++   screen blanking interval to 0 and will not blank the screen at all.
++
++Q. Generally when the kernel is up and running, CLCD is active but after some
++   time screen gets blanked, How to unblank the already blanked CLCD screen ?
++A. Create a dummy node "mknod /dev/dummy c 4 0 ".
++   Execute a command "echo -e "\033[13]" > /dev/dummy", this will activate
++   CLCD screen.
++
++Q. How to enable L2 Cache for Nomadik SOCs
++A. Switch to kernel source path, execute "make menuconfig"
++   Enable option "Enable L2 Cache controller" at location "x -> System Type"
++   L2CC is not available on STn8810 SOC versions
++
++==============================================================================
++
++
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt
+@@ -0,0 +1,140 @@
++Filename: ./Documentation/arm/STM-Nomadik/gpio_user_guide.txt
++Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner:                STMicroelectronics
++Purpose:
++              This Users Guide explains GPIO implimentation and its usage
++              from other drivers for Nomadik platforms
++=============================================================================
++
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
++
++GPIO Configuration:
++===================
++By default GPIO driver is configured to link staticlly with kernel becasue
++it is tightly coupled with irq.c. GPIO is necessary for Nomadik architecture
++
++Brief Architecture:
++GPIO dirver is registered as amba device and will be probed only if
++matches peripharal ID, the SOC specific data and function iterface is provided
++through platfrom_data pointer to allign driver code in sync with multiboard
++strategy.
++
++GPIO driver mainly provides two kinds of functionality
++1. GPIO Interrupt hanndling and control.
++2. Exported GPIO APIs
++      2.1 Usage of GPIO pins/block for read write APIs
++      2.2 Configuration for Alternate functions APIs
++
++1. GPIO Interrupt hanndling and control:-
++==============================================
++VIC generates a common interrupt for all 32 pins in a block, there are such
++three to four blocks in a SOC, Each GPIO interrupt can be considered as
++standard IRQ and can be processed through generic system call (please refer
++irq_usrguide.txt). Further GPIO interrupts are softdecoded hence canot be
++programmed as priority interrupts individually,
++
++2. Exported GPIO APIs
++=====================
++All exported GPIOs are protected against call before initialization. This
++means if the GPIO driver cannot be probled due to any reasons and you try to
++use GPIO exported APIs, and error will be returned.
++APIS nomadik_gpio_readpin and nomadik_gpio_readblock are not protected against
++interrupt configuration becasue reading a GPIO does not harm its usage from
++other context. Where as all other APIS are protected against interrupt
++cnfiguration. This means if the interrupt is already requested on a GPIO pin
++the same pin cannot be configured untill you free that interrupt.
++
++2.1 Usage of GPIO pins/block for read write APIs
++================================================
++      a) nomadik_gpio_setpinconfig:
++              Individual pin can be configured for desired operation.
++      for ex.
++      mmc_pin.dev_name = "test";
++      mmc_pin.mode = GPIO_MODE_SOFTWARE;
++      mmc_pin.direction = GPIO_DIR_OUTPUT;
++      mmc_pin.debounce = GPIO_DEBOUNCE_ENABLE;
++      mmc_pin.debounce_time = GPIO_DEBOUNCE_TIME_60_MICROSEC;
++      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++
++      The above code will configure GPIO_PIN_75 in GPIO mode used as output
++      pin, enabled debouncing logic and set debounce time to 60 miroseconds.
++      debounce logic will be enabled if supported by the SOC version.
++      dev_name is a client device name to which the GPIO will be allocated.
++
++      b) nomadik_gpio_resetpinconfig:
++              sets the particular pin to its reset state.
++
++      c) nomadik_gpio_writepin;
++              write HIGN or LOW value on specified pin
++
++      d) nomadik_gpio_readpin;
++              reads HIGN or LOW value from specified pin
++
++      e) nomadik_gpio_readblock;
++              write multiple bits on specifed group of GPIOs
++      ex.
++      err = nomadik_gpio_writeblock(GPIO_BLOCK_32_BITS_64_TO_95,
++              , 0x0000aa00, 0x0000fc00);
++
++      The above code writes HIGH on GPIO_PIN_74, LOW on GPIO_PIN_75,
++      HIGH on GPIO_PIN_76, LOW on GPIO_PIN_77, and HIGN on GPIO_PIN_78
++
++      f) nomadik_gpio_writeblock;
++              reads multiple bits on specifed group of GPIOs
++
++2.2 Configuration for Alternate functions APIs
++================================================
++      a) nomadik_gpio_altfuncenable:
++              Sets the group of GPIOs dedicated for spefic alternate mode of
++      operation.
++
++      for ex.
++      retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
++
++      The above code configures GPIOs 62 abd 63 (in case of stn8810) for
++      altfun_A, the detailed information which pins to be configured in which
++      mode for specified gpio_alt_function value(GPIO_ALT_I2C_0) is decided by
++      the gpio_altfun_tbl[] declared in <SOC>_devices.c. It has table entries
++      whcih controls altfun configuration.
++
++      for example entry in table
++      {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type =
++       GPIO_ALTF_A,},
++      states that- for gpio_alt_function value GPIO_ALT_I2C_0, from gpio pins 62
++      to 63 needs to be configured for alternate function A. cont=0 specifies that
++      there are no further pins to be configured for GPIO_ALT_I2C_0.
++
++      example for cont=1
++      {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type =
++       GPIO_ALTF_A,},
++      {.altfun = GPIO_ALT_SD_CARD,.start = 82,.end = 87,.cont = 1,.type =
++       GPIO_ALTF_A,},
++      {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type =
++       GPIO_ALTF_A,},
++
++      In the above example cont=1 in first and second declaration states that there
++      are additional entries in sequence to configure pins (82 to 87) and (14 to 16)
++      in altfun A mode for the same gpio_alt_function value GPIO_ALT_MM_CARD
++
++      b) nomadik_gpio_altfuncdisable:
++              This API reconfigures the group of GPIOs dedicated for specific
++      alternate mode of operation in to GPIO mode.
++
++Secured GPIO Access:
++===================
++To prevent GPIO resources getting used/altered by unauthorised way, a method
++is provided to give secured control. When gpio is requested by setpinconfig,
++you need to specify dev_name, GPIO driver records the information that the
++particular pin is alloocated the client named "dev_name", while doing
++resetpinconfig the same dev_id must be passed.
++Simillarly the same should be followed while requesting enabling/disabling altfunction.
++When the GPIO is requested for interrupt, the specified devname will be
++configured as client name.
++
++/proc/gpio interface:
++====================
++/proc/gpio entry is created to show the information of allocated GPIO resources
++
++=======================================================================================
++
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt
+@@ -0,0 +1,171 @@
++Filename: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
++Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
++Owner:                STMicroelectronics
++Created:      9th June 2007
++
++Purpose:
++This Users Guide explains interrupts implimentation and its usage from other
++client drivers for Nomadik platforms
++
++This document is valid subject to assumption -
++1. valid kernel source code with Nomadik support is available
++
++Generic:
++========
++All the available interrupts can be used in through standard system calls
++To use nomadik interrupts, include <linux/interrupt.h> ONLY in your code
++Interrupt numbers generic to all Nomadik cuts are defined in irqs.h
++Interrupt numbers specific to Nomadik cut is defined in <soc>_devices.h
++(refer HOWTO-add_newboard.txt for more information)
++
++IRQ Description:
++================
++for stn8810 chip:
++      IRQ0 to IRQ31   : IRQ lines provided by the VIC for different
++                        on-chip peripharals.
++      IRQ32 to IRQ127 : IRQ lines for GPIO interrupts
++
++for stn8815 chip:
++      IRQ0 to IRQ63   : IRQ lines provided by the VIC for different
++                        on-chip peripharals.
++      IRQ64 to IRQ191 : IRQ lines for GPIO interrupts
++
++Specific:
++========
++1. Vectored Interrupt Controller (VIC) Interrupt Priority configuration:-
++========================================================================
++Generally whenever there is IRQ request to the VIC it will be processed
++immediately, if two or more IRQs active at a time then first in a sequence
++(i.e lower in number) will be processed first (this depends how you decode
++irqnr in entry-macro.S).
++
++Vectored interrupt processing hardware on Nomadik SOC is used to detect,
++process and service the interrupts in prioritized manner.
++This provides faster interrupt processing for comples decision.
++This adds more flexibility to the system and to the driver developers to
++take complex decision making about which interrupt to be proceesed first
++when more than one IRQ goes active at a time.
++
++also while processing priority interrupt all lower priority interrupts will
++be disabled by hardware whereas all higher priority interrupts will be active.
++This adds a benefit to use SA_IRQPRIORITY_x over SA_INTERRUPT becasue
++SA_INTERRUPT disables all interrupt while processign it.
++
++Any 15 (maximum) IRQs lines of VIC can be programmed for priority,
++GPIO_IRQs cannot be programmed for priority since the are softdecoded.
++
++How to program a interrupt for desired priority?
++================================================
++this can be done in two ways
++a. using request_irq
++      for ex.
++      err = request_irq(IRQ_UART1, test_inthandle, SA_IRQPRIORITY_4,
++                       "test", test_data);
++
++      will request IRQ with interrupt priority level 4
++
++b) using set_irq_type
++      This call can be used any time after requesting a interrupt to
++      to enable/disable/change priority level for specific IRQ line
++
++      For ex.
++      set_irq_type(IRQ_UART1, SA_IRQPRIORITY_10);
++
++      will enable priority level for pre-requested IRQ
++      if IRQ was requested with different priority level earlier,
++      this call will change it to specified level
++
++How to disable interrupt priority for a IRQ?
++===========================================
++a) using set_irq_type api
++      This call can be used any time after requesting a interrupt to
++      to enable/disable/change priority level for specific IRQ line
++
++      For ex.
++      set_irq_type(IRQ_UART1, SA_IRQPRIORITY_DISABLE);
++
++      will disable priority level for pre-requested IRQ and will configure
++      if as normal IRQ
++
++How to know which IRQs are programmed for priority?
++===================================================
++executing cat /proc/interrupts interface will display all interrupt information
++if any IRQ is programmed with some priority then it will reflect as-
++
++# cat /proc/interrupts
++           CPU0
++  4:     143193       Nomadik Timer Tick
++ 10:          0       rtc
++ 11:          0       ssp
++ 13:          1       dma1
++ 15:          0       dma0
++ 17:        745       uart-pl011
++ 20:          0       i2c0
++ 21:          4       i2c1
++ 22:        132       NMDK_MMC (data)
++ 30:          0:PL07  msp1
++ 31:          0       msp2
++ 72:        122       nmdk-kp
++ 77:        433       eth0
++ 79:       5175       nmdk-tp
++ 81:         32       mmc_detect
++Err:          0
++#
++
++Above message indicates that IRQ30 for msp1 is programmed as priority interrupt
++with level 7.
++
++2. GPIO Interrupt hanndling and control:-
++==============================================
++GPIO Interrupt control is handled through standard system calls. The macros
++(IRQNO_GPIO(x) and GPIO_PIN_FOR_IRQ(x)) are provided to find out interrupt
++number associated with GPIO and vice-versa.
++Following system calls are suported for GPIO interrupt control:-
++a) request_irq/ free_irq:
++      works in a standard way to request and free GPIO interrupt.
++      When request_irq is invoked for GPIO, it first configures GPIO pin
++      for input operation with debounce disable (if supported). Then it sets
++      interrupt type for falling edge detection by default if not specified
++      in interrupt_flags. You can set type of interrupt during request by
++      passing required SA_TTRIGGER_ flags. GPIO interrupt type will be set
++      during request_irq call if the requested interrupt is NOT shared.
++
++      for ex.
++      err = request_irq(IRQNO_GPIO(x), test_inthandle, SA_TRIGGER_RISING,
++                       "test", test_data);
++
++      will request rising edge interrupt for GPIO x
++
++b) enable_irq/disable_irq:
++      These are standard system calls can be used to enable or disable GPIO
++      irqs whenever required.
++
++      for ex.
++      enable_irq(IRQNO_GPIO(x));
++
++      will enable interrupt for GPIO x
++
++c) set_irq_type:
++      By defult interrupt is requested as falling edge through request_irq call.
++      If you want to use other type of interrupt detection, this call can be used.
++      This call will be necessary to configure shared GPIO interrupt
++
++      For ex.
++      set_irq_type(IRQNO_GPIO(x), SA_TRIGGER_LOW);
++              sets irq type as low level detection
++
++      set_irq_type(IRQNO_GPIO(x), (SA_TRIGGER_RISING|SA_TRIGGER_FALLING);
++              sets irq type for both edges detection
++
++      Please note that set_irq_type overwites previous irq_type, hence the GPIO
++      interrupt behaviour depends upon where you call this API.
++
++      for ex. if you set_irq_type first and then requested interrupt, the
++      request_irq will overwrite the previously set irq type and vice versa.
++
++d) enable_irq_wake/disable_irq_wake:
++      the frame work is provided to handle these call for GPIO interrupt to
++      enable/disable wakup event generation to the power management unit.
++
++===============================================================================
++
+--- /dev/null
++++ linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt
+@@ -0,0 +1,122 @@
++
++ * 1 Nomadik Power Management Strategy
++ * ==========================================
++ * Power in nomadik can be saved by following features
++ * 1. Enable idle tick suppression or dynamic tick
++ * 2. Frequency scaling
++ * 3. Voltage scaling
++ * 4. Take system into soft sleep
++ * 5. Take system into deep sleep
++ * 6. Taking individual device (eg. CLCD) into suspend state
++ *
++ *
++ * 1.1 How to Enable idle tick suppression or dynamic tick
++ * =========================================================
++ *
++ * 1. Select CONFIG_NO_IDLE_HZ in kernel features in kernel configuration
++ * 2. To enable dynamic tick
++ *    echo -n 1 > /sys/devices/system/timer/timer0/dyn_tick
++ * 3. Dynamic tick can be disabled by
++ *    echo -n 0 > /sys/devices/system/timer/timer0/dyn_tick
++ * 4. In idle thread, arm put itself in WFI, hence power is saved. By using
++ *    dynamic tick we can put ARM in WFI for longer duration
++ *
++ * 1.2 Scaling frequencies
++ *====================================
++ * 1. Select CONFIG_CPU_FREQ & CONFIG_CPU_FREQ_NOMADIK in kernel configuration
++ *    during compilation
++ * 2. Check current frequency (In Khz) by
++ *    cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
++ * 3. Change system freq by
++ *    echo -n <freq in khz > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
++ *    If entered freq is not supported in system then next higher valid
++ *    frequency is set
++ * 4. For frequencies which require voltage change, new voltage will be
++ *    reflected. It can be checked by voltage sysfs file
++ * 5. If mapping for frequency and voltage is changed then change is required
++ *     in arch/arm/mach-nomadik/power.c
++ * 6. If different SDRAM parameters are to be changed then change is required
++ *    in  arch/arm/mach-nomadik/power.c
++ * 7. If frequencies are to be altered then change is required in  arch/arm/mach-nomadik/power.c
++ *
++ *
++ * 1.3 Scaling Voltage
++ *====================================
++ * 1. To enable voltage scaling either CONFIG_CPU_FREQ or CONFIG_PM_NOMADIK
++ *    must be selected in configuration
++ * 2. Current voltage can be checked by
++ *    cat /sys/nomadik/current_voltage
++ *    VOLTAGE will be shown in milli volt
++ * 3. To change in current voltage without changing frequency use
++ *    echo < voltage in milli volt > > current_voltage
++ *   However directly changing voltage without frequency is not recommended
++ *   but can be used for performance/testing purpose.
++ * 4. If voltages are to be altered then change is required in  arch/arm/mach-nomadik/power.c
++ *
++ *
++ * 1.4 Taking system into soft sleep
++ *====================================
++ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
++ * 2. Change required sleep type to softsleep by
++ *    echo -n softsleep > /sys/nomadik/sleep_type
++ * 3. To take system into sleep use
++ *    echo -n mem > /sys/power/state
++ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
++ * 5. To specify rtc wakeup duration ( sleeping time )
++      echo -n <sleep duration in seconds > >sleep_duration
++      Default sleep duratioon is 15 seconds
++ * 6. To take system directly into soft sleep without linux power management
++ *    framework use
++ *    echo 1 > /sys/nomadik/softsleep_enable
++ *    This is to be used when we are sure that no driver is active i.e.
++ *    driver need not be be suspended. This interface can save transition
++ *    time but is not recommended. It can be used for testing purpose.
++ *
++ *
++ * 1.5 Taking system into deep sleep
++ *====================================
++ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
++ * 2. Change required sleep type to deepsleep by
++ *    echo -n deepsleep > /sys/nomadik/sleep_type
++ * 3. To take system into sleep use
++ *    echo -n mem > /sys/power/state
++ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
++ * 5. To specify rtc wakeup duration ( sleeping time )
++ *    echo -n <sleep duration in seconds > >sleep_duration
++ *    Default sleep duration is 15 seconds
++ *
++ * 1.6 Taking Individual device into suspend/resume state
++ *=======================================================
++ * 1. Individual device can be taken into suspended state by writing into sysfs
++ *    file. Similiarly device can be resumed back
++ * 2. For example to take CLCD into suspend state use
++      echo -n 2 > /sys/devices/mb:c0/power/state
++ * 3. For example to take CLCD into resumed state use
++      echo -n 0 > /sys/devices/mb:c0/power/state
++ * 4. Similar things can be done for other devices. Few devices such as RTC,
++ *    GPIO should not be takne into suspend state by this interface.
++ *
++ *
++ * 1.7 Enabling/Disabling Individual devices(Keypad, Touchpanel, MMC) as wakeup devices
++ *===================================================================================
++ * 1. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
++ *    echo enabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
++ * 2. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
++ *    echo disabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
++ *    If a device's wakeup state is disabled, it cannot be used for waking the
++ *    system from sleep.
++ * 3. Above steps are applicable for any device that can wakeup the system
++ *
++ *
++ * 1.8 To add a device that can be used to wakeup
++ *================================================
++ * 1. To make a platform device to be able to wakeup a system, change is
++ * required in board specific file like arch/arm/mach-nomadik/ndk15_devices.c
++ * 2. To make a amba device to be able to wakeup a system, change is required
++ * in platform specific file like arch/arm/mach-nomadik/stn8815_devices.c
++ *
++ *
++ *
++ */
++
++
+--- linux-2.6.20.orig/MAINTAINERS
++++ linux-2.6.20/MAINTAINERS
+@@ -1939,10 +1939,19 @@ M:     ebiederm@xmission.com
+ W:    http://www.xmission.com/~ebiederm/files/kexec/
+ L:    linux-kernel@vger.kernel.org
+ L:    fastboot@osdl.org
+ S:    Maintained
++KGDB
++P:    Tom Rini
++P:    Amit S. Kale
++M:    trini@kernel.crashing.org
++M:    amitkale@linsyssoft.com
++W:    http://sourceforge.net/projects/kgdb
++L:    kgdb-bugreport@lists.sourceforge.net
++S:    Maintained
++
+ KPROBES
+ P:    Prasanna S Panchamukhi
+ M:    prasanna@in.ibm.com
+ P:    Ananth N Mavinakayanahalli
+ M:    ananth@in.ibm.com
+--- linux-2.6.20.orig/Makefile
++++ linux-2.6.20/Makefile
+@@ -10,11 +10,11 @@ NAME = Homicidal Dwarf Hamster
+ # Comments in this file are targeted only to the developer, do not
+ # expect to learn how to build the kernel reading this file.
+ # Do not:
+ # o  use make's built-in rules and variables
+-#    (this increases performance and avoid hard-to-debug behavour);
++#    (this increases performance and avoids hard-to-debug behaviour);
+ # o  print "Entering directory ...";
+ MAKEFLAGS += -rR --no-print-directory
+ # We are using a recursive build, so we need to do a little thinking
+ # to get the ordering right.
+@@ -319,11 +319,11 @@ AFLAGS          := -D__ASSEMBLY__
+ # Read KERNELRELEASE from include/config/kernel.release (if it exists)
+ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
+ KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+ export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
+-export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
++export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CFLAGS CROSS_COMPILE AS LD CC
+ export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
+ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
+ export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+ export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+@@ -495,11 +495,11 @@ CFLAGS           += -fno-omit-frame-pointer $(cal
+ else
+ CFLAGS                += -fomit-frame-pointer
+ endif
+ ifdef CONFIG_DEBUG_INFO
+-CFLAGS                += -g
++CFLAGS                += -gdwarf-2
+ endif
+ # Force gcc to behave correct even for buggy distributions
+ CFLAGS          += $(call cc-option, -fno-stack-protector)
+@@ -528,11 +528,10 @@ export   INSTALL_PATH ?= /boot
+ #
+ # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
+ # relocations required by build roots.  This is not defined in the
+ # makefile but the argument can be passed to make if needed.
+ #
+-
+ MODLIB        = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
+ export MODLIB
+ #
+ #  INSTALL_MOD_STRIP, if defined, will cause modules to be
+@@ -574,11 +573,11 @@ libs-y           := $(libs-y1) $(libs-y2)
+ # Build vmlinux
+ # ---------------------------------------------------------------------------
+ # vmlinux is built from the objects selected by $(vmlinux-init) and
+ # $(vmlinux-main). Most are built-in.o files from top-level directories
+-# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
++# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
+ # Ordering when linking is important, and $(vmlinux-init) must be first.
+ #
+ # vmlinux
+ #   ^
+ #   |
+@@ -732,18 +731,20 @@ debug_kallsyms: .tmp_map$(last_kallsyms)
+ .tmp_map2: .tmp_map1
+ endif # ifdef CONFIG_KALLSYMS
++include $(srctree)/scripts/ksymhash/Makefile
+ # vmlinux image - including updated kernel symbols
+ vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
+ ifdef CONFIG_HEADERS_CHECK
+       $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
+ endif
+       $(call if_changed_rule,vmlinux__)
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
+       $(Q)rm -f .old_version
++      $(rule_ksymhash)
+ # The actual objects are generated when descending, 
+ # make sure no implicit rule kicks in
+ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+@@ -1480,11 +1481,16 @@ endif
+ clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+ endif # skip-makefile
+ PHONY += FORCE
+-FORCE:
++include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk
++      mkdir -p include/linux/
++      awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h
++
++FORCE: include/linux/dwarf2-defs.h
++
+ # Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes.
+ Makefile: ;
+ # Declare the contents of the .PHONY variable as phony.  We keep that
+--- linux-2.6.20.orig/arch/arm/Kconfig
++++ linux-2.6.20/arch/arm/Kconfig
+@@ -117,11 +117,11 @@ source "init/Kconfig"
+ menu "System Type"
+ choice
+       prompt "ARM system type"
+-      default ARCH_VERSATILE
++      default ARCH_NOMADIK
+ config ARCH_AAEC2000
+       bool "Agilent AAEC-2000 based"
+       select ARM_AMBA
+       help
+@@ -201,10 +201,18 @@ config ARCH_NETX
+       bool "Hilscher NetX based"
+       select ARM_VIC
+       help
+         This enables support for systems based on the Hilscher NetX Soc
++config ARCH_NOMADIK
++      bool "Nomadik"
++      select ARM_AMBA
++      select ISA_DMA_API
++      select ICST525
++      help
++        Support for ARM's NOMADIK platform.
++
+ config ARCH_H720X
+       bool "Hynix HMS720x-based"
+       select ISA_DMA_API
+       help
+         This enables support for systems based on the Hynix HMS720x
+@@ -379,10 +387,11 @@ source "arch/arm/mach-realview/Kconfig"
+ source "arch/arm/mach-at91rm9200/Kconfig"
+ source "arch/arm/mach-netx/Kconfig"
++source "arch/arm/mach-nomadik/Kconfig"
+ # Definitions to make life easier
+ config ARCH_ACORN
+       bool
+ config PLAT_IOP
+@@ -738,11 +747,11 @@ config XIP_PHYS_ADDR
+         be linked for and stored to.  This address is dependent on your
+         own flash usage.
+ endmenu
+-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
++if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_NOMADIK )
+ menu "CPU Frequency scaling"
+ source "drivers/cpufreq/Kconfig"
+@@ -774,10 +783,21 @@ config CPU_FREQ_IMX
+       help
+         This enables the CPUfreq driver for i.MX CPUs.
+         If in doubt, say N.
++config CPU_FREQ_NOMADIK
++      tristate "CPUfreq driver for ARM Nomadik CPUs"
++      depends on ARCH_NOMADIK && CPU_FREQ && NOMADIK_NDK15
++      default y
++      select NOMADIK_DMA
++      help
++        This enables the CPUfreq driver for ARM Nomadik CPUs.
++
++        For details, take a look at <file:Documentation/cpu-freq>.
++
++        If in doubt, say Y.
+ endmenu
+ endif
+ menu "Floating point emulation"
+@@ -908,10 +928,11 @@ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32
+       || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+       || ARCH_IXP23XX
+ source "drivers/ide/Kconfig"
+ endif
++
+ source "drivers/scsi/Kconfig"
+ source "drivers/ata/Kconfig"
+ source "drivers/md/Kconfig"
+--- linux-2.6.20.orig/arch/arm/Makefile
++++ linux-2.6.20/arch/arm/Makefile
+@@ -18,11 +18,11 @@ GZFLAGS            :=-9
+ # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+ CFLAGS                +=$(call cc-option,-marm,)
+ # Do not use arch/arm/defconfig - it's always outdated.
+ # Select a platform tht is kept up-to-date
+-KBUILD_DEFCONFIG := versatile_defconfig
++KBUILD_DEFCONFIG := ndk15_defconfig
+ # defines filename extension depending memory manement type.
+ ifeq ($(CONFIG_MMU),)
+ MMUEXT                := -nommu
+ endif
+@@ -87,10 +87,11 @@ CHECKFLAGS += -D__arm__
+ #Default value
+ head-y                := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
+ textofs-y     := 0x00008000
++
+  machine-$(CONFIG_ARCH_RPC)      := rpc
+  machine-$(CONFIG_ARCH_EBSA110)          := ebsa110
+  machine-$(CONFIG_ARCH_CLPS7500)   := clps7500
+   incdir-$(CONFIG_ARCH_CLPS7500)   := cl7500
+  machine-$(CONFIG_FOOTBRIDGE)    := footbridge
+@@ -104,10 +105,11 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
+  textofs-$(CONFIG_SA1111)        := 0x00208000
+ endif
+  machine-$(CONFIG_ARCH_PXA)      := pxa
+  machine-$(CONFIG_ARCH_L7200)    := l7200
+  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
++ machine-$(CONFIG_ARCH_NOMADIK)          := nomadik
+  textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
+  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
+  machine-$(CONFIG_ARCH_IOP32X)           := iop32x
+  machine-$(CONFIG_ARCH_IOP33X)           := iop33x
+  machine-$(CONFIG_ARCH_IOP13XX)          := iop13xx
+@@ -198,16 +200,25 @@ ifneq ($(KBUILD_SRC),)
+ else
+       $(Q)ln -fsn $(INCDIR) include/asm-arm/arch
+ endif
+       @touch $@
+-archprepare: maketools
++archprepare: maketools machprepare
+-PHONY += maketools FORCE
++PHONY += maketools machprepare machclean machmrproper FORCE
+ maketools: include/linux/version.h include/asm-arm/.arch FORCE
+       $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
++
++# Machine specific preparation if it exists
++MACHPREPARE_PATH = $(strip `grep "machprepare:" $(MACHINE)Makefile* | grep -o $(MACHINE)`)
++
++machprepare:
++ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
++      $(Q)set -e; for i in $(MACHPREPARE_PATH); do $(MAKE) -C $$i $@; done
++endif
++
+ # Convert bzImage to zImage
+ bzImage: zImage
+ zImage Image xipImage bootpImage uImage: vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+@@ -216,12 +227,27 @@ zinstall install: vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+ CLEAN_FILES += include/asm-arm/mach-types.h \
+              include/asm-arm/arch include/asm-arm/.arch
++# Machine specific mrproper operation if it exists
++MACHMRPROPER_PATH =`find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machmrproper: | sed 's/Makefile:machmrproper://g' | sed 's/Makefile://g'`
++
++machmrproper:
++      $(Q)set -e; for i in $(MACHMRPROPER_PATH); do $(MAKE) -C $$i $@; done
++
++# We use MRPROPER_FILES
++archmrproper: machmrproper
++
++# Machine specific clean operation
++MACHCLEAN_PATH = `find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machclean: | sed 's/Makefile:machclean://g' | sed 's/Makefile://g'`
++
++machclean:
++      $(Q)set -e; for i in $(MACHCLEAN_PATH); do $(MAKE) -C $$i $@; done
++
+ # We use MRPROPER_FILES and CLEAN_FILES now
+-archclean:
++archclean: machclean
+       $(Q)$(MAKE) $(clean)=$(boot)
+ # My testing targets (bypasses dependencies)
+ bp:;  $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
+ i zi:;        $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+--- linux-2.6.20.orig/arch/arm/common/rtctime.c
++++ linux-2.6.20/arch/arm/common/rtctime.c
+@@ -199,17 +199,17 @@ static int rtc_ioctl(struct inode *inode
+                       ret = -EFAULT;
+                       break;
+               }
+               alrm.enabled = 0;
+               alrm.pending = 0;
+-              alrm.time.tm_mday = -1;
++/*            alrm.time.tm_mday = -1;
+               alrm.time.tm_mon = -1;
+               alrm.time.tm_year = -1;
+               alrm.time.tm_wday = -1;
+               alrm.time.tm_yday = -1;
+               alrm.time.tm_isdst = -1;
+-              ret = rtc_arm_set_alarm(ops, &alrm);
++*/            ret = rtc_arm_set_alarm(ops, &alrm);
+               break;
+       case RTC_RD_TIME:
+               ret = rtc_arm_read_time(ops, &tm);
+               if (ret)
+--- /dev/null
++++ linux-2.6.20/arch/arm/configs/ndk10_defconfig
+@@ -0,0 +1,1205 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.20
++# Thu Aug 16 17:17:58 2007
++#
++CONFIG_ARM=y
++# CONFIG_GENERIC_TIME is not set
++CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_IPC_NS is not set
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_UTS_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_SLAB=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_SLOB is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++
++#
 +# Block layer
 +#
 +CONFIG_BLOCK=y
@@ -1362,28 +2504,19 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# CONFIG_ARCH_SHARK is not set
 +# CONFIG_ARCH_LH7A40X is not set
 +# CONFIG_ARCH_OMAP is not set
-+# CONFIG_NOMADIK_NDK10_CUT_A1 is not set
++CONFIG_NOMADIK_NDK10_CUT_A1=y
 +# CONFIG_NOMADIK_NDK10_CUT_B06 is not set
 +# CONFIG_NOMADIK_NDK10_CUT_B0 is not set
 +# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set
 +# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set
-+CONFIG_NOMADIK_NDK15_REV2_B_06=y
++# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set
 +# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set
-+CONFIG_NOMADIK_TARGET="NDK15_Rev2_B_06"
-+CONFIG_NOMADIK_SOC="stn8815"
-+CONFIG_NOMADIK_PLATFORM="ndk15"
-+CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=20 "
-+CONFIG_NOMADIK_CPLD_V2010=y
-+CONFIG_NOMADIK_NDK15=y
-+
-+#
-+# Nomadik chip used STn8815S22 cut B0 (marked STN8815BBS22H11 Secure)
-+#
-+
-+#
-+# Target board CPLD version 2.0.1.0
-+#
-+CONFIG_NOMADIK_STN8815BBS22H11=y
++CONFIG_NOMADIK_TARGET="NDK10_Cut_A1"
++CONFIG_NOMADIK_SOC="stn8810"
++CONFIG_NOMADIK_PLATFORM="ndk10"
++CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++CONFIG_NOMADIK_NDK10=y
++CONFIG_NOMADIK_NDK10_CUTA=y
 +CONFIG_NOMADIK_GPIO=y
 +CONFIG_GPIO_PROC=y
 +CONFIG_NOMADIK_DMA=y
@@ -1392,13 +2525,12 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +CONFIG_NOMADIK_MTU=m
 +CONFIG_NOMADIK_MTU_SYSTEM_TICK=y
 +CONFIG_NOMADIK_RTC=y
-+CONFIG_NOMADIK_PM=y
 +# CONFIG_NOMADIK_SVA_INIT_MEM is not set
 +CONFIG_NOMADIK_SVA_MEM_SIZE=4
 +# CONFIG_NOMADIK_SAA_INIT_MEM is not set
-+CONFIG_FB_NOMADIK_VGA=y
++# CONFIG_FB_NOMADIK_VGA is not set
 +# CONFIG_FB_NOMADIK_CRT is not set
-+# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set
++CONFIG_FB_NOMADIK_QVGA_PORTRAIT=y
 +# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set
 +# CONFIG_FB_NOMADIK_PANEL_8BPP is not set
 +CONFIG_FB_NOMADIK_PANEL_16BPP=y
@@ -1407,16 +2539,16 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# CONFIG_SGA_INST_BUFFER_20 is not set
 +CONFIG_SGA_INST_BUFFER_NUM=2
 +CONFIG_FB_NOMADIK_PANEL_BPP=16
-+CONFIG_FB_NOMADIK_PANEL_NAME="VGA"
-+CONFIG_FB_NOMADIK_PANEL_XRES=640
-+CONFIG_FB_NOMADIK_PANEL_YRES=480
-+CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x21
-+CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x40
-+CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x07
-+CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x24
-+CONFIG_FB_NOMADIK_PANEL_HSLEN=0x40
-+CONFIG_FB_NOMADIK_PANEL_VSLEN=0x19
-+CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x027f1800
++CONFIG_FB_NOMADIK_PANEL_NAME="QVGA_Portrait"
++CONFIG_FB_NOMADIK_PANEL_XRES=240
++CONFIG_FB_NOMADIK_PANEL_YRES=320
++CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x13
++CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x2f
++CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x04
++CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x0f
++CONFIG_FB_NOMADIK_PANEL_HSLEN=0x13
++CONFIG_FB_NOMADIK_PANEL_VSLEN=0x04
++CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x00ef1804
 +
 +#
 +# Processor Type
@@ -1488,19 +2620,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +#
 +# CPU Frequency scaling
 +#
-+CONFIG_CPU_FREQ=y
-+CONFIG_CPU_FREQ_TABLE=y
-+# CONFIG_CPU_FREQ_DEBUG is not set
-+CONFIG_CPU_FREQ_STAT=y
-+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
-+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
-+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-+CONFIG_CPU_FREQ_GOV_USERSPACE=y
-+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-+CONFIG_CPU_FREQ_NOMADIK=y
++# CONFIG_CPU_FREQ is not set
 +
 +#
 +# Floating point emulation
@@ -1524,10 +2644,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +#
 +# Power management options
 +#
-+CONFIG_PM=y
-+# CONFIG_PM_LEGACY is not set
-+# CONFIG_PM_DEBUG is not set
-+# CONFIG_PM_SYSFS_DEPRECATED is not set
++# CONFIG_PM is not set
 +# CONFIG_APM is not set
 +
 +#
@@ -1550,10 +2667,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# CONFIG_IP_MULTICAST is not set
 +# CONFIG_IP_ADVANCED_ROUTER is not set
 +CONFIG_IP_FIB_HASH=y
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+CONFIG_IP_PNP_BOOTP=y
-+# CONFIG_IP_PNP_RARP is not set
++# CONFIG_IP_PNP is not set
 +# CONFIG_NET_IPIP is not set
 +# CONFIG_NET_IPGRE is not set
 +# CONFIG_ARPD is not set
@@ -1572,9 +2686,22 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +CONFIG_TCP_CONG_CUBIC=y
 +CONFIG_DEFAULT_TCP_CONG="cubic"
 +# CONFIG_TCP_MD5SIG is not set
-+# CONFIG_IPV6 is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
 +# CONFIG_INET6_XFRM_TUNNEL is not set
 +# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
 +# CONFIG_NETWORK_SECMARK is not set
 +# CONFIG_NETFILTER is not set
 +
@@ -1644,7 +2771,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +CONFIG_MTD_CONCAT=y
 +CONFIG_MTD_PARTITIONS=y
 +# CONFIG_MTD_REDBOOT_PARTS is not set
-+CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_CMDLINE_PARTS is not set
 +# CONFIG_MTD_AFS_PARTS is not set
 +
 +#
@@ -1799,8 +2926,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# Ethernet (10 or 100Mbit)
 +#
 +CONFIG_NET_ETHERNET=y
-+CONFIG_MII=y
-+CONFIG_SMC91X=y
++CONFIG_MII=m
++CONFIG_SMC91X=m
 +# CONFIG_DM9000 is not set
 +
 +#
@@ -1847,8 +2974,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +#
 +CONFIG_INPUT_MOUSEDEV=m
 +CONFIG_INPUT_MOUSEDEV_PSAUX=y
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
 +# CONFIG_INPUT_JOYDEV is not set
 +# CONFIG_INPUT_TSDEV is not set
 +CONFIG_INPUT_EVDEV=m
@@ -1890,7 +3017,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# Character devices
 +#
 +CONFIG_VT=y
-+# CONFIG_VT_CONSOLE is not set
++CONFIG_VT_CONSOLE=y
 +CONFIG_HW_CONSOLE=y
 +# CONFIG_VT_HW_CONSOLE_BINDING is not set
 +# CONFIG_SERIAL_NONSTANDARD is not set
@@ -1909,7 +3036,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +CONFIG_SERIAL_CORE=y
 +CONFIG_SERIAL_CORE_CONSOLE=y
 +CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
 +
 +#
 +# IPMI
@@ -1963,7 +3091,6 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# CONFIG_SENSORS_PCA9539 is not set
 +# CONFIG_SENSORS_PCF8591 is not set
 +# CONFIG_SENSORS_MAX6875 is not set
-+CONFIG_CPLD_I2C=y
 +# CONFIG_I2C_DEBUG_CORE is not set
 +# CONFIG_I2C_DEBUG_ALGO is not set
 +# CONFIG_I2C_DEBUG_BUS is not set
@@ -2105,8 +3232,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# Logo configuration
 +#
 +CONFIG_LOGO=y
-+# CONFIG_LOGO_LINUX_MONO is not set
-+# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
 +CONFIG_LOGO_LINUX_CLUT224=y
 +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 +
@@ -2114,8 +3241,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# Sound
 +#
 +CONFIG_NOMADIK_ACODEC=m
-+# CONFIG_NOMADIK_STW5094 is not set
-+CONFIG_NOMADIK_STW5095=y
++CONFIG_NOMADIK_STW5094=y
++# CONFIG_NOMADIK_STW5095 is not set
 +CONFIG_SOUND=m
 +
 +#
@@ -2281,7 +3408,6 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +CONFIG_NFS_V4=y
 +# CONFIG_NFS_DIRECTIO is not set
 +# CONFIG_NFSD is not set
-+CONFIG_ROOT_NFS=y
 +CONFIG_LOCKD=y
 +CONFIG_LOCKD_V4=y
 +CONFIG_NFS_COMMON=y
@@ -2379,12 +3505,12 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 +# CONFIG_DEBUG_KOBJECT is not set
-+# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_BUGVERBOSE=y
 +CONFIG_DEBUG_INFO=y
 +# CONFIG_DEBUG_VM is not set
 +# CONFIG_DEBUG_LIST is not set
 +CONFIG_FRAME_POINTER=y
-+CONFIG_FORCED_INLINING=y
++# CONFIG_FORCED_INLINING is not set
 +# CONFIG_RCU_TORTURE_TEST is not set
 +# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
 +# CONFIG_KGDB is not set
@@ -2451,9 +3577,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15b06_defconfig ../new/linux-2.6.2
 +CONFIG_ZLIB_DEFLATE=y
 +CONFIG_PLIST=y
 +CONFIG_IOMAP_COPY=y
-diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15_defconfig ../new/linux-2.6.20/arch/arm/configs/ndk15_defconfig
---- linux-2.6.20/arch/arm/configs/ndk15_defconfig      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/configs/ndk15_defconfig       2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/configs/ndk15_defconfig
 @@ -0,0 +1,1221 @@
 +#
 +# Automatically generated make config: don't edit
@@ -3676,14 +4801,13 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/ndk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_ZLIB_DEFLATE=y
 +CONFIG_PLIST=y
 +CONFIG_IOMAP_COPY=y
-diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/arch/arm/configs/nhk15_defconfig
---- linux-2.6.20/arch/arm/configs/nhk15_defconfig      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/configs/nhk15_defconfig       2008-11-19 16:47:02.000000000 +0530
-@@ -0,0 +1,1458 @@
+--- /dev/null
++++ linux-2.6.20/arch/arm/configs/ndk15b06_defconfig
+@@ -0,0 +1,1221 @@
 +#
 +# Automatically generated make config: don't edit
 +# Linux kernel version: 2.6.20
-+# Fri Aug 22 11:48:56 2008
++# Thu Aug 16 17:22:36 2007
 +#
 +CONFIG_ARM=y
 +# CONFIG_GENERIC_TIME is not set
@@ -3731,6 +4855,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_UID16=y
 +CONFIG_SYSCTL_SYSCALL=y
 +CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
 +# CONFIG_KALLSYMS_EXTRA_PASS is not set
 +CONFIG_HOTPLUG=y
 +CONFIG_PRINTK=y
@@ -3816,61 +4941,62 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_NOMADIK_NDK10_CUT_B0 is not set
 +# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set
 +# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set
-+# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set
++CONFIG_NOMADIK_NDK15_REV2_B_06=y
 +# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set
-+CONFIG_NOMADIK_NHK15=y
-+CONFIG_NOMADIK_TARGET="NHK15"
++CONFIG_NOMADIK_TARGET="NDK15_Rev2_B_06"
 +CONFIG_NOMADIK_SOC="stn8815"
-+CONFIG_NOMADIK_PLATFORM="nhk15"
-+CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=40 "
-+CONFIG_NOMADIK_STN8815CAS22H11=y
++CONFIG_NOMADIK_PLATFORM="ndk15"
++CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=20 "
++CONFIG_NOMADIK_CPLD_V2010=y
++CONFIG_NOMADIK_NDK15=y
 +
 +#
-+# Nomadik chip used STn8815
++# Nomadik chip used STn8815S22 cut B0 (marked STN8815BBS22H11 Secure)
 +#
++
++#
++# Target board CPLD version 2.0.1.0
++#
++CONFIG_NOMADIK_STN8815BBS22H11=y
 +CONFIG_NOMADIK_GPIO=y
-+CONFIG_NOMADIK_ENABLE_L2CACHE=y
 +CONFIG_GPIO_PROC=y
 +CONFIG_NOMADIK_DMA=y
-+CONFIG_NOMADIK_SSP=y
-+CONFIG_NOMADIK_MSP=y
++CONFIG_NOMADIK_SSP=m
++CONFIG_NOMADIK_MSP=m
 +CONFIG_NOMADIK_MTU=m
 +CONFIG_NOMADIK_MTU_SYSTEM_TICK=y
 +CONFIG_NOMADIK_RTC=y
 +CONFIG_NOMADIK_PM=y
-+CONFIG_NOMADIK_SVA_INIT_MEM=y
-+CONFIG_FORCE_MAX_ZONEORDER=13
-+CONFIG_NOMADIK_SVA_MEM_SIZE=18
-+CONFIG_NOMADIK_SVA_VPIP=y
++# CONFIG_NOMADIK_SVA_INIT_MEM is not set
++CONFIG_NOMADIK_SVA_MEM_SIZE=4
 +# CONFIG_NOMADIK_SAA_INIT_MEM is not set
-+# CONFIG_FB_NOMADIK_VGA is not set
++CONFIG_FB_NOMADIK_VGA=y
 +# CONFIG_FB_NOMADIK_CRT is not set
 +# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set
 +# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set
-+CONFIG_FB_NOMADIK_WVGA=y
 +# CONFIG_FB_NOMADIK_PANEL_8BPP is not set
-+# CONFIG_FB_NOMADIK_PANEL_16BPP is not set
++CONFIG_FB_NOMADIK_PANEL_16BPP=y
 +# CONFIG_FB_NOMADIK_PANEL_24BPP is not set
-+CONFIG_FB_NOMADIK_PANEL_24BPP_PACKED=y
-+CONFIG_FB_NOMADIK_ACCLN=y
-+CONFIG_FB_NOMADIK_PANEL_BPP=24
-+CONFIG_FB_NOMADIK_PANEL_NAME="WVGA"
-+CONFIG_FB_NOMADIK_PANEL_XRES=800
++CONFIG_SGA_INST_BUFFER_2=y
++# CONFIG_SGA_INST_BUFFER_20 is not set
++CONFIG_SGA_INST_BUFFER_NUM=2
++CONFIG_FB_NOMADIK_PANEL_BPP=16
++CONFIG_FB_NOMADIK_PANEL_NAME="VGA"
++CONFIG_FB_NOMADIK_PANEL_XRES=640
 +CONFIG_FB_NOMADIK_PANEL_YRES=480
-+CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0xD6
-+CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x27
-+CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x22
-+CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0xA
-+CONFIG_FB_NOMADIK_PANEL_HSLEN=0x1
-+CONFIG_FB_NOMADIK_PANEL_VSLEN=0x1
-+CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x031f1822
++CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0x21
++CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x40
++CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x07
++CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0x24
++CONFIG_FB_NOMADIK_PANEL_HSLEN=0x40
++CONFIG_FB_NOMADIK_PANEL_VSLEN=0x19
++CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x027f1800
 +
 +#
 +# Processor Type
 +#
 +CONFIG_CPU_32=y
 +# CONFIG_CPU_ARM920T is not set
-+CONFIG_L2CACHE_ENABLE=y
 +CONFIG_CPU_ARM926T=y
 +# CONFIG_CPU_ARM1020 is not set
 +# CONFIG_CPU_ARM1022 is not set
@@ -3930,7 +5056,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +CONFIG_ZBOOT_ROM_TEXT=0x0
 +CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc mem=64M"
++CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc"
 +# CONFIG_XIP_KERNEL is not set
 +
 +#
@@ -3993,33 +5119,24 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_XFRM=y
 +# CONFIG_XFRM_USER is not set
 +# CONFIG_XFRM_SUB_POLICY is not set
-+CONFIG_NET_KEY=y
++# CONFIG_NET_KEY is not set
 +CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+CONFIG_IP_ADVANCED_ROUTER=y
-+CONFIG_ASK_IP_FIB_HASH=y
-+# CONFIG_IP_FIB_TRIE is not set
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
 +CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_MULTIPLE_TABLES is not set
-+# CONFIG_IP_ROUTE_MULTIPATH is not set
-+# CONFIG_IP_ROUTE_VERBOSE is not set
 +CONFIG_IP_PNP=y
 +CONFIG_IP_PNP_DHCP=y
-+# CONFIG_IP_PNP_BOOTP is not set
++CONFIG_IP_PNP_BOOTP=y
 +# CONFIG_IP_PNP_RARP is not set
-+CONFIG_NET_IPIP=y
-+CONFIG_NET_IPGRE=y
-+# CONFIG_NET_IPGRE_BROADCAST is not set
-+CONFIG_IP_MROUTE=y
-+# CONFIG_IP_PIMSM_V1 is not set
-+# CONFIG_IP_PIMSM_V2 is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
 +# CONFIG_ARPD is not set
 +# CONFIG_SYN_COOKIES is not set
 +# CONFIG_INET_AH is not set
 +# CONFIG_INET_ESP is not set
 +# CONFIG_INET_IPCOMP is not set
 +# CONFIG_INET_XFRM_TUNNEL is not set
-+CONFIG_INET_TUNNEL=y
++# CONFIG_INET_TUNNEL is not set
 +CONFIG_INET_XFRM_MODE_TRANSPORT=y
 +CONFIG_INET_XFRM_MODE_TUNNEL=y
 +CONFIG_INET_XFRM_MODE_BEET=y
@@ -4072,29 +5189,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_NET_PKTGEN is not set
 +# CONFIG_HAMRADIO is not set
 +# CONFIG_IRDA is not set
-+CONFIG_BT=m
-+CONFIG_BT_L2CAP=m
-+CONFIG_BT_SCO=m
-+CONFIG_BT_RFCOMM=m
-+CONFIG_BT_RFCOMM_TTY=y
-+CONFIG_BT_BNEP=m
-+CONFIG_BT_BNEP_MC_FILTER=y
-+CONFIG_BT_BNEP_PROTO_FILTER=y
-+CONFIG_BT_HIDP=m
-+
-+#
-+# Bluetooth device drivers
-+#
-+# CONFIG_BT_HCIUSB is not set
-+CONFIG_BT_HCIUART=m
-+CONFIG_BT_HCIUART_H4=y
-+CONFIG_BT_HCIUART_BCSP=y
-+# CONFIG_BT_HCIBCM203X is not set
-+# CONFIG_BT_HCIBPA10X is not set
-+# CONFIG_BT_HCIBFUSB is not set
-+CONFIG_BT_HCIVHCI=m
++# CONFIG_BT is not set
 +# CONFIG_IEEE80211 is not set
-+CONFIG_WIRELESS_EXT=y
 +
 +#
 +# Device Drivers
@@ -4106,6 +5202,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_STANDALONE=y
 +CONFIG_PREVENT_FIRMWARE_BUILD=y
 +CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
 +# CONFIG_SYS_HYPERVISOR is not set
 +
 +#
@@ -4128,8 +5225,9 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# User Modules And Translation Layers
 +#
 +CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLKDEVS=y
-+CONFIG_MTD_BLOCK=y
++# CONFIG_MTD_BLKDEVS is not set
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
 +# CONFIG_FTL is not set
 +# CONFIG_NFTL is not set
 +# CONFIG_INFTL is not set
@@ -4198,12 +5296,11 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_MTD_NAND_IDS=y
 +# CONFIG_MTD_NAND_DISKONCHIP is not set
 +# CONFIG_MTD_NAND_NANDSIM is not set
-+CONFIG_MTD_ONENAND=y
-+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
-+CONFIG_MTD_ONENAND_GENERIC=y
-+# CONFIG_MTD_ONENAND_OTP is not set
-+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
-+# CONFIG_MTD_ONENAND_SIM is not set
++
++#
++# OneNAND Flash Device Drivers
++#
++# CONFIG_MTD_ONENAND is not set
 +
 +#
 +# Parallel port support
@@ -4218,10 +5315,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# Block devices
 +#
 +# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_LOOP is not set
 +# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_UB is not set
 +CONFIG_BLK_DEV_RAM=y
 +CONFIG_BLK_DEV_RAM_COUNT=16
 +CONFIG_BLK_DEV_RAM_SIZE=46080
@@ -4234,43 +5329,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# SCSI device support
 +#
 +# CONFIG_RAID_ATTRS is not set
-+CONFIG_SCSI=y
-+# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI is not set
 +# CONFIG_SCSI_NETLINK is not set
-+CONFIG_SCSI_PROC_FS=y
-+
-+#
-+# SCSI support type (disk, tape, CD-ROM)
-+#
-+CONFIG_BLK_DEV_SD=y
-+# CONFIG_CHR_DEV_ST is not set
-+# CONFIG_CHR_DEV_OSST is not set
-+# CONFIG_BLK_DEV_SR is not set
-+CONFIG_CHR_DEV_SG=y
-+# CONFIG_CHR_DEV_SCH is not set
-+
-+#
-+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-+#
-+CONFIG_SCSI_MULTI_LUN=y
-+CONFIG_SCSI_CONSTANTS=y
-+CONFIG_SCSI_LOGGING=y
-+CONFIG_SCSI_SCAN_ASYNC=y
-+
-+#
-+# SCSI Transports
-+#
-+# CONFIG_SCSI_SPI_ATTRS is not set
-+# CONFIG_SCSI_FC_ATTRS is not set
-+# CONFIG_SCSI_ISCSI_ATTRS is not set
-+# CONFIG_SCSI_SAS_ATTRS is not set
-+# CONFIG_SCSI_SAS_LIBSAS is not set
-+
-+#
-+# SCSI low-level drivers
-+#
-+# CONFIG_ISCSI_TCP is not set
-+# CONFIG_SCSI_DEBUG is not set
 +
 +#
 +# Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -4332,15 +5392,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Wireless LAN (non-hamradio)
 +#
-+CONFIG_NET_RADIO=y
-+# CONFIG_NET_WIRELESS_RTNETLINK is not set
-+
-+#
-+# Obsolete Wireless cards support (pre-802.11)
-+#
-+# CONFIG_STRIP is not set
-+# CONFIG_USB_ZD1201 is not set
-+# CONFIG_HOSTAP is not set
++# CONFIG_NET_RADIO is not set
 +
 +#
 +# Wan interfaces
@@ -4367,10 +5419,13 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Userland interfaces
 +#
-+# CONFIG_INPUT_MOUSEDEV is not set
++CONFIG_INPUT_MOUSEDEV=m
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
 +# CONFIG_INPUT_JOYDEV is not set
 +# CONFIG_INPUT_TSDEV is not set
-+CONFIG_INPUT_EVDEV=y
++CONFIG_INPUT_EVDEV=m
 +# CONFIG_INPUT_EVBUG is not set
 +
 +#
@@ -4383,7 +5438,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_KEYBOARD_XTKBD is not set
 +# CONFIG_KEYBOARD_NEWTON is not set
 +# CONFIG_KEYBOARD_STOWAWAY is not set
-+CONFIG_KEYPAD_NOMADIK=y
++CONFIG_KEYPAD_NOMADIK=m
 +# CONFIG_INPUT_MOUSE is not set
 +# CONFIG_INPUT_JOYSTICK is not set
 +CONFIG_INPUT_TOUCHSCREEN=y
@@ -4396,8 +5451,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 +# CONFIG_TOUCHSCREEN_UCB1400 is not set
-+# CONFIG_TOUCHSCREEN_NOMADIK is not set
-+CONFIG_TOUCHSCREEN_NOMADIK_TS2003=y
++CONFIG_TOUCHSCREEN_NOMADIK=m
 +# CONFIG_INPUT_MISC is not set
 +
 +#
@@ -4483,6 +5537,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_SENSORS_PCA9539 is not set
 +# CONFIG_SENSORS_PCF8591 is not set
 +# CONFIG_SENSORS_MAX6875 is not set
++CONFIG_CPLD_I2C=y
 +# CONFIG_I2C_DEBUG_CORE is not set
 +# CONFIG_I2C_DEBUG_ALGO is not set
 +# CONFIG_I2C_DEBUG_BUS is not set
@@ -4492,13 +5547,14 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# SPI support
 +#
 +CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
 +CONFIG_SPI_MASTER=y
 +
 +#
 +# SPI Master Controller Drivers
 +#
 +# CONFIG_SPI_BITBANG is not set
-+CONFIG_NOMADIK_SPI=y
++CONFIG_NOMADIK_SPI=m
 +
 +#
 +# SPI Protocol Masters
@@ -4529,7 +5585,6 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_SENSORS_GL518SM is not set
 +# CONFIG_SENSORS_GL520SM is not set
 +# CONFIG_SENSORS_IT87 is not set
-+CONFIG_SENSORS_LIS3LV02DL=m
 +# CONFIG_SENSORS_LM63 is not set
 +# CONFIG_SENSORS_LM70 is not set
 +# CONFIG_SENSORS_LM75 is not set
@@ -4560,11 +5615,8 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Misc devices
 +#
-+CONFIG_STMPE_NOMADIK=y
-+CONFIG_SIF_NOMADIK=y
-+CONFIG_ETM_NOMADIK=m
 +# CONFIG_TIFM_CORE is not set
-+CONFIG_BATT_NOMADIK=y
++
 +#
 +# LED devices
 +#
@@ -4581,35 +5633,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Multimedia devices
 +#
-+CONFIG_VIDEO_DEV=y
-+# CONFIG_VIDEO_V4L1 is not set
-+CONFIG_VIDEO_V4L1_COMPAT=y
-+CONFIG_VIDEO_V4L2=y
-+
-+#
-+# Video Capture Adapters
-+#
-+
-+#
-+# Video Capture Adapters
-+#
-+# CONFIG_VIDEO_ADV_DEBUG is not set
-+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-+# CONFIG_VIDEO_VIVI is not set
-+# CONFIG_VIDEO_SAA5246A is not set
-+# CONFIG_VIDEO_SAA5249 is not set
-+
-+#
-+# V4L USB devices
-+#
-+# CONFIG_VIDEO_PVRUSB2 is not set
-+# CONFIG_VIDEO_USBVISION is not set
-+CONFIG_VIDEO_NOMADIK=y
-+
-+#
-+# Radio Adapters
-+#
-+# CONFIG_USB_DSBR is not set
++# CONFIG_VIDEO_DEV is not set
 +
 +#
 +# Digital Video Broadcasting Devices
@@ -4617,14 +5641,6 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_DVB is not set
 +
 +#
-+# NOMADIK Audio Video Drivers(SAA and SVA) 
-+#
-+CONFIG_NOMADIK_SAA=m
-+CONFIG_NOMADIK_SVA=m
-+CONFIG_NOMADIK_OGL=m
-+# CONFIG_USB_DABUSB is not set
-+
-+#
 +# Graphics support
 +#
 +CONFIG_FIRMWARE_EDID=y
@@ -4671,17 +5687,17 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Sound
 +#
-+CONFIG_NOMADIK_ACODEC=y
++CONFIG_NOMADIK_ACODEC=m
 +# CONFIG_NOMADIK_STW5094 is not set
 +CONFIG_NOMADIK_STW5095=y
-+CONFIG_SOUND=y
++CONFIG_SOUND=m
 +
 +#
 +# Advanced Linux Sound Architecture
 +#
-+CONFIG_SND=y
-+CONFIG_SND_TIMER=y
-+CONFIG_SND_PCM=y
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
 +# CONFIG_SND_SEQUENCER is not set
 +# CONFIG_SND_MIXER_OSS is not set
 +# CONFIG_SND_PCM_OSS is not set
@@ -4694,7 +5710,6 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Generic devices
 +#
-+CONFIG_SND_AC97_CODEC=y
 +# CONFIG_SND_DUMMY is not set
 +# CONFIG_SND_MTPAV is not set
 +# CONFIG_SND_SERIAL_U16550 is not set
@@ -4704,18 +5719,12 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# ALSA ARM devices
 +#
 +CONFIG_SND_NOMADIK_ALSA=m
-+CONFIG_SND_ARMAACI=y
-+
-+#
-+# USB devices
-+#
-+# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_ARMAACI is not set
 +
 +#
 +# Open Sound System
 +#
 +# CONFIG_SOUND_PRIME is not set
-+CONFIG_AC97_BUS=y
 +
 +#
 +# HID Devices
@@ -4728,161 +5737,30 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_USB_ARCH_HAS_HCD=y
 +# CONFIG_USB_ARCH_HAS_OHCI is not set
 +# CONFIG_USB_ARCH_HAS_EHCI is not set
-+CONFIG_USB=y
-+#CONFIG_USB_DEBUG is not set
-+
-+#
-+# Miscellaneous USB options
-+#
-+CONFIG_USB_DEVICEFS=y
-+CONFIG_USB_BANDWIDTH=y
-+CONFIG_USB_DYNAMIC_MINORS=y
-+# CONFIG_USB_SUSPEND is not set
-+# CONFIG_USB_OTG is not set
-+
-+#
-+# USB Host Controller Drivers
-+#
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_SL811_HCD is not set
-+
-+#
-+# USB Device Class drivers
-+#
-+# CONFIG_USB_ACM is not set
-+# CONFIG_USB_PRINTER is not set
++# CONFIG_USB is not set
 +
 +#
 +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 +#
 +
 +#
-+# may also be needed; see USB_STORAGE Help for more information
-+#
-+CONFIG_USB_STORAGE=y
-+#CONFIG_USB_STORAGE_DEBUG is not set
-+# CONFIG_USB_STORAGE_DATAFAB is not set
-+# CONFIG_USB_STORAGE_FREECOM is not set
-+# CONFIG_USB_STORAGE_DPCM is not set
-+# CONFIG_USB_STORAGE_USBAT is not set
-+# CONFIG_USB_STORAGE_SDDR09 is not set
-+# CONFIG_USB_STORAGE_SDDR55 is not set
-+# CONFIG_USB_STORAGE_JUMPSHOT is not set
-+# CONFIG_USB_STORAGE_ALAUDA is not set
-+# CONFIG_USB_STORAGE_KARMA is not set
-+# CONFIG_USB_LIBUSUAL is not set
-+
-+#
-+# USB Input Devices
-+#
-+CONFIG_USB_HID=y
-+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-+# CONFIG_HID_FF is not set
-+# CONFIG_USB_HIDDEV is not set
-+# CONFIG_USB_AIPTEK is not set
-+# CONFIG_USB_WACOM is not set
-+# CONFIG_USB_ACECAD is not set
-+# CONFIG_USB_KBTAB is not set
-+# CONFIG_USB_POWERMATE is not set
-+# CONFIG_USB_TOUCHSCREEN is not set
-+# CONFIG_USB_YEALINK is not set
-+# CONFIG_USB_XPAD is not set
-+# CONFIG_USB_ATI_REMOTE is not set
-+# CONFIG_USB_ATI_REMOTE2 is not set
-+# CONFIG_USB_KEYSPAN_REMOTE is not set
-+# CONFIG_USB_APPLETOUCH is not set
-+
-+#
-+# USB Imaging devices
-+#
-+# CONFIG_USB_MDC800 is not set
-+# CONFIG_USB_MICROTEK is not set
-+
-+#
-+# USB Network Adapters
-+#
-+# CONFIG_USB_CATC is not set
-+# CONFIG_USB_KAWETH is not set
-+# CONFIG_USB_PEGASUS is not set
-+# CONFIG_USB_RTL8150 is not set
-+# CONFIG_USB_USBNET_MII is not set
-+# CONFIG_USB_USBNET is not set
-+CONFIG_USB_MON=y
-+
-+#
-+# USB port drivers
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# CONFIG_USB_SERIAL is not set
-+
-+#
-+# USB Miscellaneous drivers
-+#
-+# CONFIG_USB_EMI62 is not set
-+# CONFIG_USB_EMI26 is not set
-+# CONFIG_USB_ADUTUX is not set
-+# CONFIG_USB_AUERSWALD is not set
-+# CONFIG_USB_RIO500 is not set
-+# CONFIG_USB_LEGOTOWER is not set
-+# CONFIG_USB_LCD is not set
-+# CONFIG_USB_LED is not set
-+# CONFIG_USB_CYPRESS_CY7C63 is not set
-+# CONFIG_USB_CYTHERM is not set
-+# CONFIG_USB_PHIDGET is not set
-+# CONFIG_USB_IDMOUSE is not set
-+# CONFIG_USB_FTDI_ELAN is not set
-+# CONFIG_USB_APPLEDISPLAY is not set
-+# CONFIG_USB_LD is not set
-+# CONFIG_USB_TRANCEVIBRATOR is not set
-+CONFIG_USB_TEST=y
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
 +# USB Gadget Support
 +#
-+CONFIG_USB_GADGET=m
-+# CONFIG_USB_GADGET_DEBUG_FILES is not set
-+CONFIG_USB_GADGET_SELECTED=y
-+# CONFIG_USB_GADGET_NET2280 is not set
-+# CONFIG_USB_GADGET_PXA2XX is not set
-+# CONFIG_USB_GADGET_GOKU is not set
-+# CONFIG_USB_GADGET_LH7A40X is not set
-+# CONFIG_USB_GADGET_OMAP is not set
-+# CONFIG_USB_GADGET_AT91 is not set
-+CONFIG_USB_GADGET_DUMMY_HCD=y
-+CONFIG_USB_DUMMY_HCD=m
-+CONFIG_USB_GADGET_DUALSPEED=y
-+CONFIG_USB_ZERO=m
-+# CONFIG_USB_ETH is not set
-+# CONFIG_USB_GADGETFS is not set
-+CONFIG_USB_FILE_STORAGE=m
-+# CONFIG_USB_FILE_STORAGE_TEST is not set
-+# CONFIG_USB_G_SERIAL is not set
-+# CONFIG_USB_MIDI_GADGET is not set
-+CONFIG_USB_INVENTRA_HCD=m
-+CONFIG_USB_INVENTRA_HCD_HOST=y
-+# CONFIG_USB_INVENTRA_HCD_GADGET_API is not set
-+# CONFIG_USB_INVENTRA_HCD_OTG is not set
-+# CONFIG_USB_INVENTRA_HCD_OTG_GSTORAGE is not set
-+# CONFIG_USB_INVENTRA_STATIC_CONFIG is not set
-+# CONFIG_USB_INVENTRA_DMA is not set
-+# CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID is not set
-+CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE=""
-+CONFIG_USB_INVENTRA_MUSB_BOARD_FILE=""
-+CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS=""
-+# CONFIG_USB_INVENTRA_HCD_POLLING is not set
-+CONFIG_USB_INVENTRA_HCD_LOGGING=0
++# CONFIG_USB_GADGET is not set
 +
 +#
 +# MMC/SD Card support
 +#
-+# CONFIG_MMC is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++CONFIG_MMC_BLOCK=m
++# CONFIG_MMC_ARMMMCI is not set
++# CONFIG_MMC_WBSD is not set
++# CONFIG_MMC_TIFM_SD is not set
++CONFIG_MMC_NOMADIK=m
++CONFIG_NOMADIK_MMC_DMA=y
++# CONFIG_NOMADIK_MMC_POLL is not set
++# CONFIG_NOMADIK_MMC_INTR is not set
 +
 +#
 +# Real Time Clock
@@ -4912,7 +5790,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_DNOTIFY=y
 +# CONFIG_AUTOFS_FS is not set
 +# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
++# CONFIG_FUSE_FS is not set
 +
 +#
 +# CD-ROM/DVD Filesystems
@@ -4923,9 +5801,9 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# DOS/FAT/NT Filesystems
 +#
-+CONFIG_FAT_FS=y
-+CONFIG_MSDOS_FS=y
-+CONFIG_VFAT_FS=y
++CONFIG_FAT_FS=m
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=m
 +CONFIG_FAT_DEFAULT_CODEPAGE=437
 +CONFIG_FAT_DEFAULT_IOCHARSET="cp437"
 +# CONFIG_NTFS_FS is not set
@@ -4952,16 +5830,6 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_BEFS_FS is not set
 +# CONFIG_BFS_FS is not set
 +# CONFIG_EFS_FS is not set
-+CONFIG_YAFFS_FS=y
-+CONFIG_YAFFS_YAFFS1=y
-+# CONFIG_YAFFS_9BYTE_TAGS is not set
-+# CONFIG_YAFFS_DOES_ECC is not set
-+CONFIG_YAFFS_YAFFS2=y
-+CONFIG_YAFFS_AUTO_YAFFS2=y
-+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 +CONFIG_JFFS2_FS=y
 +CONFIG_JFFS2_FS_DEBUG=0
 +CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -4971,7 +5839,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_JFFS2_ZLIB=y
 +CONFIG_JFFS2_RTIME=y
 +# CONFIG_JFFS2_RUBIN is not set
-+CONFIG_CRAMFS=y
++# CONFIG_CRAMFS is not set
 +# CONFIG_VXFS_FS is not set
 +# CONFIG_HPFS_FS is not set
 +# CONFIG_QNX4FS_FS is not set
@@ -5013,7 +5881,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +CONFIG_NLS=y
 +CONFIG_NLS_DEFAULT="cp437"
-+CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_CODEPAGE_437=m
 +# CONFIG_NLS_CODEPAGE_737 is not set
 +# CONFIG_NLS_CODEPAGE_775 is not set
 +# CONFIG_NLS_CODEPAGE_850 is not set
@@ -5037,7 +5905,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_NLS_CODEPAGE_1250 is not set
 +# CONFIG_NLS_CODEPAGE_1251 is not set
 +# CONFIG_NLS_ASCII is not set
-+CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_1 is not set
 +# CONFIG_NLS_ISO8859_2 is not set
 +# CONFIG_NLS_ISO8859_3 is not set
 +# CONFIG_NLS_ISO8859_4 is not set
@@ -5060,8 +5928,7 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +#
 +# Profiling support
 +#
-+CONFIG_PROFILING=y
-+CONFIG_OPROFILE=y
++# CONFIG_PROFILING is not set
 +
 +#
 +# Kernel hacking
@@ -5072,12 +5939,32 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +# CONFIG_UNUSED_SYMBOLS is not set
 +# CONFIG_DEBUG_FS is not set
 +# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_KERNEL=y
 +CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SLAB is not set
++CONFIG_DEBUG_PREEMPT=y
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++CONFIG_DEBUG_MUTEXES=y
++# CONFIG_DEBUG_RWSEMS is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
 +# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
 +CONFIG_FRAME_POINTER=y
++CONFIG_FORCED_INLINING=y
++# CONFIG_RCU_TORTURE_TEST is not set
 +# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
++# CONFIG_KGDB is not set
 +# CONFIG_DEBUG_USER is not set
++# CONFIG_DEBUG_ERRORS is not set
++# CONFIG_DEBUG_LL is not set
 +
 +#
 +# Security options
@@ -5138,11131 +6025,10285 @@ diff -Nauprw linux-2.6.20/arch/arm/configs/nhk15_defconfig ../new/linux-2.6.20/a
 +CONFIG_ZLIB_DEFLATE=y
 +CONFIG_PLIST=y
 +CONFIG_IOMAP_COPY=y
-diff -Nauprw linux-2.6.20/arch/arm/Kconfig ../new/linux-2.6.20/arch/arm/Kconfig
---- linux-2.6.20/arch/arm/Kconfig      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/Kconfig       2007-11-21 11:51:41.000000000 +0530
-@@ -119,7 +119,7 @@ menu "System Type"
- choice
-       prompt "ARM system type"
--      default ARCH_VERSATILE
-+      default ARCH_NOMADIK
- config ARCH_AAEC2000
-       bool "Agilent AAEC-2000 based"
-@@ -203,6 +203,14 @@ config ARCH_NETX
-       help
-         This enables support for systems based on the Hilscher NetX Soc
-+config ARCH_NOMADIK
-+      bool "Nomadik"
-+      select ARM_AMBA
-+      select ISA_DMA_API
-+      select ICST525
-+      help
-+        Support for ARM's NOMADIK platform.
-+
- config ARCH_H720X
-       bool "Hynix HMS720x-based"
-       select ISA_DMA_API
-@@ -381,6 +389,7 @@ source "arch/arm/mach-at91rm9200/Kconfig
- source "arch/arm/mach-netx/Kconfig"
-+source "arch/arm/mach-nomadik/Kconfig"
- # Definitions to make life easier
- config ARCH_ACORN
-       bool
-@@ -740,7 +749,7 @@ config XIP_PHYS_ADDR
- endmenu
--if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
-+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_NOMADIK )
- menu "CPU Frequency scaling"
-@@ -776,6 +785,17 @@ config CPU_FREQ_IMX
-         If in doubt, say N.
-+config CPU_FREQ_NOMADIK
-+      tristate "CPUfreq driver for ARM Nomadik CPUs"
-+      depends on ARCH_NOMADIK && CPU_FREQ && NOMADIK_NDK15 
-+      default y
-+      select NOMADIK_DMA
-+      help
-+        This enables the CPUfreq driver for ARM Nomadik CPUs.
+--- /dev/null
++++ linux-2.6.20/arch/arm/configs/nhk15_defconfig
+@@ -0,0 +1,1458 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.20
++# Fri Aug 22 11:48:56 2008
++#
++CONFIG_ARM=y
++# CONFIG_GENERIC_TIME is not set
++CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 +
-+        For details, take a look at <file:Documentation/cpu-freq>.
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
 +
-+        If in doubt, say Y.
- endmenu
- endif
-@@ -910,6 +930,7 @@ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32
- source "drivers/ide/Kconfig"
- endif
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_IPC_NS is not set
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_UTS_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_SLAB=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_SLOB is not set
 +
- source "drivers/scsi/Kconfig"
- source "drivers/ata/Kconfig"
-diff -Nauprw linux-2.6.20/arch/arm/kernel/armksyms.c ../new/linux-2.6.20/arch/arm/kernel/armksyms.c
---- linux-2.6.20/arch/arm/kernel/armksyms.c    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/armksyms.c     2007-11-21 11:51:41.000000000 +0530
-@@ -31,6 +31,13 @@ extern void __lshrdi3(void);
- extern void __modsi3(void);
- extern void __muldi3(void);
- extern void __ucmpdi2(void);
-+#ifdef CONFIG_AEABI
-+extern void __aeabi_uldivmod(void);
-+#else
-+extern void __udivdi3(void);
-+#endif
-+extern void __umoddi3(void);
-+extern void __udivmoddi4(void);
- extern void __udivsi3(void);
- extern void __umodsi3(void);
- extern void __do_div64(void);
-@@ -139,6 +146,13 @@ EXPORT_SYMBOL(__modsi3);
- EXPORT_SYMBOL(__muldi3);
- EXPORT_SYMBOL(__ucmpdi2);
- EXPORT_SYMBOL(__udivsi3);
-+#ifdef CONFIG_AEABI
-+EXPORT_SYMBOL(__aeabi_uldivmod);
-+#else
-+EXPORT_SYMBOL(__udivdi3);
-+#endif
-+EXPORT_SYMBOL(__umoddi3);
-+EXPORT_SYMBOL(__udivmoddi4);
- EXPORT_SYMBOL(__umodsi3);
- EXPORT_SYMBOL(__do_div64);
-diff -Nauprw linux-2.6.20/arch/arm/kernel/dma.c ../new/linux-2.6.20/arch/arm/kernel/dma.c
---- linux-2.6.20/arch/arm/kernel/dma.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/dma.c  2007-11-21 11:51:41.000000000 +0530
-@@ -228,6 +228,7 @@ int dma_channel_active(dmach_t channel)
- {
-       return dma_chan[channel].active;
- }
-+EXPORT_SYMBOL(dma_channel_active);
- void set_dma_page(dmach_t channel, char pagenr)
- {
-diff -Nauprw linux-2.6.20/arch/arm/kernel/entry-armv.S ../new/linux-2.6.20/arch/arm/kernel/entry-armv.S
---- linux-2.6.20/arch/arm/kernel/entry-armv.S  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/entry-armv.S   2007-11-21 11:51:41.000000000 +0530
-@@ -15,6 +15,7 @@
-  *  it to save wrong values...  Be aware!
-  */
-+#include <asm/kgdb.h>
- #include <asm/memory.h>
- #include <asm/glue.h>
- #include <asm/vfpmacros.h>
-@@ -239,6 +240,7 @@ svc_preempt:
-       beq     preempt_return                  @ go again
-       b       1b
- #endif
-+      CFI_END_FRAME(__irq_svc)
-       .align  5
- __und_svc:
-diff -Nauprw linux-2.6.20/arch/arm/kernel/irq.c ../new/linux-2.6.20/arch/arm/kernel/irq.c
---- linux-2.6.20/arch/arm/kernel/irq.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/irq.c  2007-11-21 11:51:41.000000000 +0530
-@@ -76,7 +76,19 @@ int show_interrupts(struct seq_file *p, 
-               seq_printf(p, "%3d: ", i);
-               for_each_present_cpu(cpu)
-+#ifdef CONFIG_ARCH_NOMADIK
-+              /*
-+               * Outputs Priority Level for irq, if programmed
-+               * refer: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
-+               */
-+              if (action->flags & SA_IRQPRIORITY_MASK)
-+                      seq_printf(p, "%10u:PL%02d", kstat_cpu(cpu).irqs[i],
-+                                      (int)(action->flags)>>4 & 0x0f);
-+              else 
-                       seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
-+#else
-+                      seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
-+#endif
-               seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
-               seq_printf(p, "  %s", action->name);
-               for (action = action->next; action; action = action->next)
-diff -Nauprw linux-2.6.20/arch/arm/kernel/kgdb.c ../new/linux-2.6.20/arch/arm/kernel/kgdb.c
---- linux-2.6.20/arch/arm/kernel/kgdb.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/kgdb.c 2008-10-20 13:37:44.000000000 +0530
-@@ -0,0 +1,208 @@
-+/*
-+ * arch/arm/kernel/kgdb.c
-+ *
-+ * ARM KGDB support
-+ *
-+ * Copyright (c) 2002-2004 MontaVista Software, Inc
-+ *
-+ * Authors:  George Davis <davis_g@mvista.com>
-+ *           Deepak Saxena <dsaxena@plexity.net>
-+ */
-+//#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/spinlock.h>
-+#include <linux/personality.h>
-+#include <linux/ptrace.h>
-+#include <linux/elf.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/kgdb.h>
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
 +
-+#include <asm/atomic.h>
-+#include <asm/io.h>
-+#include <asm/pgtable.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unistd.h>
-+#include <asm/ptrace.h>
-+#include <asm/traps.h>
++#
++# Block layer
++#
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
 +
-+/* Make a local copy of the registers passed into the handler (bletch) */
-+void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
-+{
-+      int regno;
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
 +
-+      /* Initialize all to zero (??) */
-+      for (regno = 0; regno < GDB_MAX_REGS; regno++)
-+              gdb_regs[regno] = 0;
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++CONFIG_ARCH_NOMADIK=y
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_NOMADIK_NDK10_CUT_A1 is not set
++# CONFIG_NOMADIK_NDK10_CUT_B06 is not set
++# CONFIG_NOMADIK_NDK10_CUT_B0 is not set
++# CONFIG_NOMADIK_NDK15_REV2_B_03 is not set
++# CONFIG_NOMADIK_NDK15_REV2_B_05 is not set
++# CONFIG_NOMADIK_NDK15_REV2_B_06 is not set
++# CONFIG_NOMADIK_NDK15_REV3_C_02 is not set
++CONFIG_NOMADIK_NHK15=y
++CONFIG_NOMADIK_TARGET="NHK15"
++CONFIG_NOMADIK_SOC="stn8815"
++CONFIG_NOMADIK_PLATFORM="nhk15"
++CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS="-D__RELEASE -D__STN_8815=40 "
++CONFIG_NOMADIK_STN8815CAS22H11=y
 +
-+      gdb_regs[_R0] = kernel_regs->ARM_r0;
-+      gdb_regs[_R1] = kernel_regs->ARM_r1;
-+      gdb_regs[_R2] = kernel_regs->ARM_r2;
-+      gdb_regs[_R3] = kernel_regs->ARM_r3;
-+      gdb_regs[_R4] = kernel_regs->ARM_r4;
-+      gdb_regs[_R5] = kernel_regs->ARM_r5;
-+      gdb_regs[_R6] = kernel_regs->ARM_r6;
-+      gdb_regs[_R7] = kernel_regs->ARM_r7;
-+      gdb_regs[_R8] = kernel_regs->ARM_r8;
-+      gdb_regs[_R9] = kernel_regs->ARM_r9;
-+      gdb_regs[_R10] = kernel_regs->ARM_r10;
-+      gdb_regs[_FP] = kernel_regs->ARM_fp;
-+      gdb_regs[_IP] = kernel_regs->ARM_ip;
-+      gdb_regs[_SP] = kernel_regs->ARM_sp;
-+      gdb_regs[_LR] = kernel_regs->ARM_lr;
-+      gdb_regs[_PC] = kernel_regs->ARM_pc;
-+      gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;
-+}
++#
++# Nomadik chip used STn8815
++#
++CONFIG_NOMADIK_GPIO=y
++CONFIG_NOMADIK_ENABLE_L2CACHE=y
++CONFIG_GPIO_PROC=y
++CONFIG_NOMADIK_DMA=y
++CONFIG_NOMADIK_SSP=y
++CONFIG_NOMADIK_MSP=y
++CONFIG_NOMADIK_MTU=m
++CONFIG_NOMADIK_MTU_SYSTEM_TICK=y
++CONFIG_NOMADIK_RTC=y
++CONFIG_NOMADIK_PM=y
++CONFIG_NOMADIK_SVA_INIT_MEM=y
++CONFIG_FORCE_MAX_ZONEORDER=13
++CONFIG_NOMADIK_SVA_MEM_SIZE=18
++CONFIG_NOMADIK_SVA_VPIP=y
++# CONFIG_NOMADIK_SAA_INIT_MEM is not set
++# CONFIG_FB_NOMADIK_VGA is not set
++# CONFIG_FB_NOMADIK_CRT is not set
++# CONFIG_FB_NOMADIK_QVGA_PORTRAIT is not set
++# CONFIG_FB_NOMADIK_QVGA_LANDSCAPE is not set
++CONFIG_FB_NOMADIK_WVGA=y
++# CONFIG_FB_NOMADIK_PANEL_8BPP is not set
++# CONFIG_FB_NOMADIK_PANEL_16BPP is not set
++# CONFIG_FB_NOMADIK_PANEL_24BPP is not set
++CONFIG_FB_NOMADIK_PANEL_24BPP_PACKED=y
++CONFIG_FB_NOMADIK_ACCLN=y
++CONFIG_FB_NOMADIK_PANEL_BPP=24
++CONFIG_FB_NOMADIK_PANEL_NAME="WVGA"
++CONFIG_FB_NOMADIK_PANEL_XRES=800
++CONFIG_FB_NOMADIK_PANEL_YRES=480
++CONFIG_FB_NOMADIK_PANEL_LFMARGIN=0xD6
++CONFIG_FB_NOMADIK_PANEL_RTMARGIN=0x27
++CONFIG_FB_NOMADIK_PANEL_UPRMARGIN=0x22
++CONFIG_FB_NOMADIK_PANEL_LWRMARGIN=0xA
++CONFIG_FB_NOMADIK_PANEL_HSLEN=0x1
++CONFIG_FB_NOMADIK_PANEL_VSLEN=0x1
++CONFIG_FB_NOMADIK_PANEL_TIM2VAL=0x031f1822
 +
-+/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
-+void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
-+{
-+      kernel_regs->ARM_r0 = gdb_regs[_R0];
-+      kernel_regs->ARM_r1 = gdb_regs[_R1];
-+      kernel_regs->ARM_r2 = gdb_regs[_R2];
-+      kernel_regs->ARM_r3 = gdb_regs[_R3];
-+      kernel_regs->ARM_r4 = gdb_regs[_R4];
-+      kernel_regs->ARM_r5 = gdb_regs[_R5];
-+      kernel_regs->ARM_r6 = gdb_regs[_R6];
-+      kernel_regs->ARM_r7 = gdb_regs[_R7];
-+      kernel_regs->ARM_r8 = gdb_regs[_R8];
-+      kernel_regs->ARM_r9 = gdb_regs[_R9];
-+      kernel_regs->ARM_r10 = gdb_regs[_R10];
-+      kernel_regs->ARM_fp = gdb_regs[_FP];
-+      kernel_regs->ARM_ip = gdb_regs[_IP];
-+      kernel_regs->ARM_sp = gdb_regs[_SP];
-+      kernel_regs->ARM_lr = gdb_regs[_LR];
-+      kernel_regs->ARM_pc = gdb_regs[_PC];
-+      kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1];
-+}
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++# CONFIG_CPU_ARM920T is not set
++CONFIG_L2CACHE_ENABLE=y
++CONFIG_CPU_ARM926T=y
++# CONFIG_CPU_ARM1020 is not set
++# CONFIG_CPU_ARM1022 is not set
++# CONFIG_CPU_ARM1026 is not set
++# CONFIG_CPU_V6 is not set
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
 +
-+static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)
-+{
-+      return (struct pt_regs *)
-+          ((unsigned long)task->thread_info + THREAD_SIZE -
-+           8 - sizeof(struct pt_regs));
-+}
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++CONFIG_ICST525=y
 +
-+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
-+                               struct task_struct *task)
-+{
-+      int regno;
-+      struct pt_regs *thread_regs;
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++CONFIG_ISA_DMA_API=y
 +
-+      /* Just making sure... */
-+      if (task == NULL)
-+              return;
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
 +
-+      /* Initialize to zero */
-+      for (regno = 0; regno < GDB_MAX_REGS; regno++)
-+              gdb_regs[regno] = 0;
++#
++# Kernel Features
++#
++CONFIG_PREEMPT=y
++CONFIG_NO_IDLE_HZ=y
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ALIGNMENT_TRAP=y
 +
-+      /* Otherwise, we have only some registers from switch_to() */
-+      thread_regs = kgdb_get_user_regs(task);
-+      gdb_regs[_R0] = thread_regs->ARM_r0;    /* Not really valid? */
-+      gdb_regs[_R1] = thread_regs->ARM_r1;    /* "               " */
-+      gdb_regs[_R2] = thread_regs->ARM_r2;    /* "               " */
-+      gdb_regs[_R3] = thread_regs->ARM_r3;    /* "               " */
-+      gdb_regs[_R4] = thread_regs->ARM_r4;
-+      gdb_regs[_R5] = thread_regs->ARM_r5;
-+      gdb_regs[_R6] = thread_regs->ARM_r6;
-+      gdb_regs[_R7] = thread_regs->ARM_r7;
-+      gdb_regs[_R8] = thread_regs->ARM_r8;
-+      gdb_regs[_R9] = thread_regs->ARM_r9;
-+      gdb_regs[_R10] = thread_regs->ARM_r10;
-+      gdb_regs[_FP] = thread_regs->ARM_fp;
-+      gdb_regs[_IP] = thread_regs->ARM_ip;
-+      gdb_regs[_SP] = thread_regs->ARM_sp;
-+      gdb_regs[_LR] = thread_regs->ARM_lr;
-+      gdb_regs[_PC] = thread_regs->ARM_pc;
-+      gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
-+}
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA1,115200n8 init=linuxrc mem=64M"
++# CONFIG_XIP_KERNEL is not set
 +
-+static int compiled_break;
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++# CONFIG_CPU_FREQ_DEBUG is not set
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
++CONFIG_CPU_FREQ_NOMADIK=y
 +
-+int kgdb_arch_handle_exception(int exception_vector, int signo,
-+                             int err_code, char *remcom_in_buffer,
-+                             char *remcom_out_buffer,
-+                             struct pt_regs *linux_regs)
-+{
-+      long addr;
-+      char *ptr;
++#
++# Floating point emulation
++#
 +
-+      switch (remcom_in_buffer[0]) {
-+      case 'c':
-+              kgdb_contthread = NULL;
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
 +
-+              /*
-+               * Try to read optional parameter, pc unchanged if no parm.
-+               * If this was a compiled breakpoint, we need to move
-+               * to the next instruction or we will just breakpoint
-+               * over and over again.
-+               */
-+              ptr = &remcom_in_buffer[1];
-+              if (kgdb_hex2long(&ptr, &addr)) {
-+                      linux_regs->ARM_pc = addr;
-+              } else if (compiled_break == 1) {
-+                      linux_regs->ARM_pc += 4;
-+              }
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
 +
-+              compiled_break = 0;
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_LEGACY is not set
++# CONFIG_PM_DEBUG is not set
++# CONFIG_PM_SYSFS_DEPRECATED is not set
++# CONFIG_APM is not set
 +
-+              return 0;
-+      }
++#
++# Networking
++#
++CONFIG_NET=y
 +
-+      return -1;
-+}
++#
++# Networking options
++#
++# CONFIG_NETDEBUG is not set
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++CONFIG_NET_KEY=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_MULTIPLE_TABLES is not set
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++CONFIG_NET_IPIP=y
++CONFIG_NET_IPGRE=y
++# CONFIG_NET_IPGRE_BROADCAST is not set
++CONFIG_IP_MROUTE=y
++# CONFIG_IP_PIMSM_V1 is not set
++# CONFIG_IP_PIMSM_V2 is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
 +
-+static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
-+{
-+      kgdb_handle_exception(1, SIGTRAP, 0, regs);
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
 +
-+      return 0;
-+}
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
 +
-+static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
-+{
-+      compiled_break = 1;
-+      kgdb_handle_exception(1, SIGTRAP, 0, regs);
++#
++# TIPC Configuration (EXPERIMENTAL)
++#
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
 +
-+      return 0;
-+}
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
 +
-+static struct undef_hook kgdb_brkpt_hook = {
-+      .instr_mask = 0xffffffff,
-+      .instr_val = KGDB_BREAKINST,
-+      .fn = kgdb_brk_fn
-+};
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++CONFIG_BT_SCO=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HIDP=m
 +
-+static struct undef_hook kgdb_compiled_brkpt_hook = {
-+      .instr_mask = 0xffffffff,
-+      .instr_val = KGDB_COMPILED_BREAK,
-+      .fn = kgdb_compiled_brk_fn
-+};
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIUSB is not set
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++CONFIG_BT_HCIVHCI=m
++# CONFIG_IEEE80211 is not set
++CONFIG_WIRELESS_EXT=y
 +
-+/*
-+ * Register our undef instruction hooks with ARM undef core.
-+ * We regsiter a hook specifically looking for the KGB break inst
-+ * and we handle the normal undef case within the do_undefinstr
-+ * handler.
-+ */
-+int kgdb_arch_init(void)
-+{
-+      register_undef_hook(&kgdb_brkpt_hook);
-+      register_undef_hook(&kgdb_compiled_brkpt_hook);
++#
++# Device Drivers
++#
 +
-+      return 0;
-+}
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_SYS_HYPERVISOR is not set
 +
-+struct kgdb_arch arch_kgdb_ops = {
-+#ifndef __ARMEB__
-+      .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
-+#else
-+      .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
-+#endif
-+};
-diff -Nauprw linux-2.6.20/arch/arm/kernel/kgdb-jmp.S ../new/linux-2.6.20/arch/arm/kernel/kgdb-jmp.S
---- linux-2.6.20/arch/arm/kernel/kgdb-jmp.S    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/kgdb-jmp.S     2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,30 @@
-+/*
-+ * arch/arm/kernel/kgdb-jmp.S
-+ *
-+ * Trivial setjmp and longjmp procedures to support bus error recovery
-+ * which may occur during kgdb memory read/write operations.
-+ *
-+ * Author: MontaVista Software, Inc. <source@mvista.com>
-+ *         source@mvista.com
-+ *
-+ * 2002-2005 (c) MontaVista Software, Inc.  This file is licensed under the
-+ * terms of the GNU General Public License version 2. This program as licensed
-+ * "as is" without any warranty of any kind, whether express or implied.
-+ */
-+#include <linux/linkage.h>
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
 +
-+ENTRY (kgdb_fault_setjmp)
-+      /* Save registers */
-+      stmia   r0, {r0-r14}
-+      str     lr,[r0, #60]
-+      mrs     r1,cpsr
-+      str     r1,[r0,#64]
-+      ldr     r1,[r0,#4]
-+      mov     r0, #0
-+      mov     pc,lr
++#
++# Memory Technology Devices (MTD)
++#
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
 +
-+ENTRY (kgdb_fault_longjmp)
-+      /* Restore registers */
-+      mov     r1,#1
-+      str     r1,[r0]
-+      ldmia   r0,{r0-pc}^
-diff -Nauprw linux-2.6.20/arch/arm/kernel/Makefile ../new/linux-2.6.20/arch/arm/kernel/Makefile
---- linux-2.6.20/arch/arm/kernel/Makefile      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/Makefile       2007-11-21 11:51:41.000000000 +0530
-@@ -19,6 +19,7 @@ obj-$(CONFIG_ARTHUR)         += arthur.o
- obj-$(CONFIG_ISA_DMA)         += dma-isa.o
- obj-$(CONFIG_PCI)             += bios32.o isa.o
- obj-$(CONFIG_SMP)             += smp.o
-+obj-$(CONFIG_KGDB)            += kgdb.o kgdb-jmp.o
- obj-$(CONFIG_OABI_COMPAT)     += sys_oabi-compat.o
- obj-$(CONFIG_CRUNCH)          += crunch.o crunch-bits.o
-diff -Nauprw linux-2.6.20/arch/arm/kernel/setup.c ../new/linux-2.6.20/arch/arm/kernel/setup.c
---- linux-2.6.20/arch/arm/kernel/setup.c       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/setup.c        2007-11-21 11:51:41.000000000 +0530
-@@ -829,6 +829,11 @@ void __init setup_arch(char **cmdline_p)
-       conswitchp = &dummy_con;
- #endif
- #endif
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
 +
-+#if   defined(CONFIG_KGDB)
-+      extern void __init early_trap_init(void);
-+      early_trap_init();
-+#endif
- }
-diff -Nauprw linux-2.6.20/arch/arm/kernel/traps.c ../new/linux-2.6.20/arch/arm/kernel/traps.c
---- linux-2.6.20/arch/arm/kernel/traps.c       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/kernel/traps.c        2007-11-21 11:51:41.000000000 +0530
-@@ -279,6 +279,7 @@ asmlinkage void do_undefinstr(struct pt_
-       unsigned int instr;
-       struct undef_hook *hook;
-       siginfo_t info;
-+      mm_segment_t fs;
-       void __user *pc;
-       /*
-@@ -288,12 +289,15 @@ asmlinkage void do_undefinstr(struct pt_
-        */
-       regs->ARM_pc -= correction;
-+      fs = get_fs();
-+      set_fs(KERNEL_DS);
-       pc = (void __user *)instruction_pointer(regs);
-       if (thumb_mode(regs)) {
-               get_user(instr, (u16 __user *)pc);
-       } else {
-               get_user(instr, (u32 __user *)pc);
-       }
-+      set_fs(fs);
-       spin_lock_irq(&undef_lock);
-       list_for_each_entry(hook, &undef_hook, node) {
-@@ -682,6 +686,13 @@ EXPORT_SYMBOL(abort);
- void __init trap_init(void)
- {
-+#if   defined(CONFIG_KGDB)
-+      return;
-+}
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_CFI_STAA=y
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
 +
-+void __init early_trap_init(void)
-+{
-+#endif
-       unsigned long vectors = CONFIG_VECTORS_BASE;
-       extern char __stubs_start[], __stubs_end[];
-       extern char __vectors_start[], __vectors_end[];
-diff -Nauprw linux-2.6.20/arch/arm/lib/gcclib.h ../new/linux-2.6.20/arch/arm/lib/gcclib.h
---- linux-2.6.20/arch/arm/lib/gcclib.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/gcclib.h  2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,25 @@
-+/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
-+/* I Molton     29/07/01 */
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_NOMADIK=y
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_PLATRAM is not set
 +
-+#define BITS_PER_UNIT  8
-+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_DATAFLASH is not set
++# CONFIG_MTD_M25P80 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
 +
-+typedef unsigned int UQItype    __attribute__ ((mode (QI)));
-+typedef          int SItype     __attribute__ ((mode (SI)));
-+typedef unsigned int USItype    __attribute__ ((mode (SI)));
-+typedef          int DItype     __attribute__ ((mode (DI)));
-+typedef          int word_type        __attribute__ ((mode (__word__)));
-+typedef unsigned int UDItype    __attribute__ ((mode (DI)));
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
 +
-+#ifdef __ARMEB__
-+  struct DIstruct {SItype high, low;};
-+#else
-+  struct DIstruct {SItype low, high;};
-+#endif
++#
++# NAND Flash Device Drivers
++#
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_NOMADIK=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++CONFIG_MTD_ONENAND=y
++# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
++CONFIG_MTD_ONENAND_GENERIC=y
++# CONFIG_MTD_ONENAND_OTP is not set
++# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
++# CONFIG_MTD_ONENAND_SIM is not set
 +
-+typedef union
-+{
-+  struct DIstruct s;
-+  DItype ll;
-+} DIunion;
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
 +
-diff -Nauprw linux-2.6.20/arch/arm/lib/longlong.h ../new/linux-2.6.20/arch/arm/lib/longlong.h
---- linux-2.6.20/arch/arm/lib/longlong.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/longlong.h        2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,184 @@
-+/* longlong.h -- based on code from gcc-2.95.3
++#
++# Plug and Play support
++#
 +
-+   definitions for mixed size 32/64 bit arithmetic.
-+   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=46080
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
 +
-+   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.
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
 +
-+   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.
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
 +
-+   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.  */
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++CONFIG_SCSI_CONSTANTS=y
++CONFIG_SCSI_LOGGING=y
++CONFIG_SCSI_SCAN_ASYNC=y
 +
-+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
 +
-+#ifndef SI_TYPE_SIZE
-+#define SI_TYPE_SIZE 32
-+#endif
++#
++# SCSI low-level drivers
++#
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
 +
-+#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.
++#
++# Serial ATA (prod) and Parallel ATA (experimental) drivers
++#
++# CONFIG_ATA is not set
 +
-+   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.
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
 +
-+   If any of these macros are left undefined for a particular CPU,
-+   C macros are used.  */
++#
++# Fusion MPT device support
++#
++# CONFIG_FUSION is not set
 +
-+#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) \
-+{register USItype __t0, __t1, __t2;                                   \
-+  __asm__ ("%@ Inlined umul_ppmm                                      \n\
-+      mov     %2, %5, lsr #16                                         \n\
-+      mov     %0, %6, lsr #16                                         \n\
-+      bic     %3, %5, %2, lsl #16                                     \n\
-+      bic     %4, %6, %0, lsl #16                                     \n\
-+      mul     %1, %3, %4                                              \n\
-+      mul     %4, %2, %4                                              \n\
-+      mul     %3, %0, %3                                              \n\
-+      mul     %0, %2, %0                                              \n\
-+      adds    %3, %4, %3                                              \n\
-+      addcs   %0, %0, #65536                                          \n\
-+      adds    %1, %1, %3, lsl #16                                     \n\
-+      adc     %0, %0, %3, lsr #16"                                    \
-+         : "=&r" ((USItype) (xh)),                                    \
-+           "=r" ((USItype) (xl)),                                     \
-+           "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
-+         : "r" ((USItype) (a)),                                       \
-+           "r" ((USItype) (b)));}
-+#define UMUL_TIME 20
-+#define UDIV_TIME 100
-+#endif /* __arm__ */
++#
++# IEEE 1394 (FireWire) support
++#
 +
-+#define __umulsidi3(u, v) \
-+  ({DIunion __w;                                                      \
-+    umul_ppmm (__w.s.high, __w.s.low, u, v);                          \
-+    __w.ll; })
++#
++# I2O device support
++#
 +
-+#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)
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
 +
-+#define UDIV_NEEDS_NORMALIZATION 1
-+#define udiv_qrnnd __udiv_qrnnd_c
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
 +
-+extern const UQItype __clz_tab[];
-+#define count_leading_zeros(count, x) \
-+  do {                                                                        \
-+    USItype __xr = (x);                                                       \
-+    USItype __a;                                                      \
-+                                                                      \
-+    if (SI_TYPE_SIZE <= 32)                                           \
-+      {                                                                       \
-+      __a = __xr < ((USItype)1<<2*__BITS4)                            \
-+        ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)                \
-+        : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);  \
-+      }                                                                       \
-+    else                                                              \
-+      {                                                                       \
-+      for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)                 \
-+        if (((__xr >> __a) & 0xff) != 0)                              \
-+          break;                                                      \
-+      }                                                                       \
-+                                                                      \
-+    (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);          \
-+  } while (0)
-diff -Nauprw linux-2.6.20/arch/arm/lib/Makefile ../new/linux-2.6.20/arch/arm/lib/Makefile
---- linux-2.6.20/arch/arm/lib/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/Makefile  2007-11-21 11:51:41.000000000 +0530
-@@ -13,7 +13,7 @@ lib-y                := backtrace.o changebit.o csumip
-                  testchangebit.o testclearbit.o testsetbit.o        \
-                  ashldi3.o ashrdi3.o lshrdi3.o muldi3.o             \
-                  ucmpdi2.o lib1funcs.o div64.o sha1.o               \
--                 io-readsb.o io-writesb.o io-readsl.o io-writesl.o
-+                 io-readsb.o io-writesb.o io-readsl.o io-writesl.o udivdi3.o \
- mmu-y := clear_user.o copy_page.o getuser.o putuser.o
-diff -Nauprw linux-2.6.20/arch/arm/lib/udivdi3.c ../new/linux-2.6.20/arch/arm/lib/udivdi3.c
---- linux-2.6.20/arch/arm/lib/udivdi3.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/lib/udivdi3.c 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,246 @@
-+/* More subroutines needed by GCC output code on some machines.  */
-+/* Compile this one with gcc.  */
-+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
 +
-+This file is part of GNU CC.
++#
++# Ethernet (1000 Mbit)
++#
 +
-+GNU CC 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.
++#
++# Ethernet (10000 Mbit)
++#
 +
-+GNU CC 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.
++#
++# Token Ring devices
++#
 +
-+You should have received a copy of the GNU General Public License
-+along with GNU CC; see the file COPYING.  If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA.  */
++#
++# Wireless LAN (non-hamradio)
++#
++CONFIG_NET_RADIO=y
++# CONFIG_NET_WIRELESS_RTNETLINK is not set
 +
-+/* As a special exception, if you link this library with other files,
-+   some of which are compiled with GCC, to produce an executable,
-+   this library does not by itself cause the resulting executable
-+   to be covered by the GNU General Public License.
-+   This exception does not however invalidate any other reasons why
-+   the executable file might be covered by the GNU General Public License.
-+ */
-+/* support functions required by the kernel. based on code from gcc-2.95.3 */
-+/* I Molton     29/07/01 */
++#
++# Obsolete Wireless cards support (pre-802.11)
++#
++# CONFIG_STRIP is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_HOSTAP is not set
 +
-+#include "gcclib.h"
-+#include "longlong.h"
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
 +
-+const UQItype __clz_tab[] =
-+{
-+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-+};
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
 +
-+UDItype
-+__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
-+{
-+  DIunion ww;
-+  DIunion nn, dd;
-+  DIunion rr;
-+  USItype d0, d1, n0, n1, n2;
-+  USItype q0, q1;
-+  USItype b, bm;
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
 +
-+  nn.ll = n;
-+  dd.ll = d;
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
 +
-+  d0 = dd.s.low;
-+  d1 = dd.s.high;
-+  n0 = nn.s.low;
-+  n1 = nn.s.high;
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_KEYPAD_NOMADIK=y
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_UCB1400 is not set
++# CONFIG_TOUCHSCREEN_NOMADIK is not set
++CONFIG_TOUCHSCREEN_NOMADIK_TS2003=y
++# CONFIG_INPUT_MISC is not set
 +
-+  if (d1 == 0)
-+    {
-+      if (d0 > n1)
-+        {
-+          /* 0q = nn / 0D */
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
 +
-+          count_leading_zeros (bm, d0);
++#
++# Character devices
++#
++CONFIG_VT=y
++# CONFIG_VT_CONSOLE is not set
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
 +
-+          if (bm != 0)
-+            {
-+              /* Normalize, i.e. make the most significant bit of the
-+                 denominator set.  */
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
 +
-+              d0 = d0 << bm;
-+              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
-+              n0 = n0 << bm;
-+            }
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++CONFIG_SERIAL_AMBA_PL011=y
++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
 +
-+          udiv_qrnnd (q0, n0, n1, n0, d0);
-+          q1 = 0;
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
 +
-+          /* Remainder in n0 >> bm.  */
-+        }
-+      else
-+        {
-+          /* qq = NN / 0d */
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
 +
-+          if (d0 == 0)
-+            d0 = 1 / d0;        /* Divide intentionally by zero.  */
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
 +
-+          count_leading_zeros (bm, d0);
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_CHARDEV=y
 +
-+          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).
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
 +
-+                 This special case is necessary, not an optimization.
-+                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_NOMADIK=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_PCA_ISA is not set
 +
-+              n1 -= d0;
-+              q1 = 1;
-+            }
-+          else
-+            {
-+              /* Normalize.  */
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
 +
-+              b = SI_TYPE_SIZE - bm;
++#
++# SPI support
++#
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
 +
-+              d0 = d0 << bm;
-+              n2 = n1 >> b;
-+              n1 = (n1 << bm) | (n0 >> b);
-+              n0 = n0 << bm;
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_BITBANG is not set
++CONFIG_NOMADIK_SPI=y
 +
-+              udiv_qrnnd (q1, n1, n2, n1, d0);
-+            }
++#
++# SPI Protocol Masters
++#
 +
-+          /* n1 != d0...  */
++#
++# Dallas's 1-wire bus
++#
++# CONFIG_W1 is not set
 +
-+          udiv_qrnnd (q0, n0, n1, n0, d0);
++#
++# Hardware Monitoring support
++#
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_ABITUGURU is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ASB100 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_FSCHER is not set
++# CONFIG_SENSORS_FSCPOS is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++CONFIG_SENSORS_LIS3LV02DL=m
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
 +
-+          /* Remainder in n0 >> bm.  */
-+        }
++#
++# Misc devices
++#
++CONFIG_STMPE_NOMADIK=y
++CONFIG_SIF_NOMADIK=y
++CONFIG_ETM_NOMADIK=m
++# CONFIG_TIFM_CORE is not set
++CONFIG_BATT_NOMADIK=y
++#
++# LED devices
++#
++# CONFIG_NEW_LEDS is not set
 +
-+      if (rp != 0)
-+        {
-+          rr.s.low = n0 >> bm;
-+          rr.s.high = 0;
-+          *rp = rr.ll;
-+        }
-+    }
-+  else
-+    {
-+      if (d1 > n1)
-+        {
-+          /* 00 = nn / DD */
++#
++# LED drivers
++#
 +
-+          q0 = 0;
-+          q1 = 0;
++#
++# LED Triggers
++#
 +
-+          /* Remainder in n1n0.  */
-+          if (rp != 0)
-+            {
-+              rr.s.low = n0;
-+              rr.s.high = n1;
-+              *rp = rr.ll;
-+            }
-+        }
-+      else
-+        {
-+          /* 0q = NN / dd */
++#
++# Multimedia devices
++#
++CONFIG_VIDEO_DEV=y
++# CONFIG_VIDEO_V4L1 is not set
++CONFIG_VIDEO_V4L1_COMPAT=y
++CONFIG_VIDEO_V4L2=y
 +
-+          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).
++#
++# Video Capture Adapters
++#
 +
-+                 This special case is necessary, not an optimization.  */
++#
++# Video Capture Adapters
++#
++# CONFIG_VIDEO_ADV_DEBUG is not set
++CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
++# CONFIG_VIDEO_VIVI is not set
++# CONFIG_VIDEO_SAA5246A is not set
++# CONFIG_VIDEO_SAA5249 is not set
 +
-+              /* 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;
++#
++# V4L USB devices
++#
++# CONFIG_VIDEO_PVRUSB2 is not set
++# CONFIG_VIDEO_USBVISION is not set
++CONFIG_VIDEO_NOMADIK=y
 +
-+              q1 = 0;
++#
++# Radio Adapters
++#
++# CONFIG_USB_DSBR is not set
 +
-+              if (rp != 0)
-+                {
-+                  rr.s.low = n0;
-+                  rr.s.high = n1;
-+                  *rp = rr.ll;
-+                }
-+            }
-+          else
-+            {
-+              USItype m1, m0;
-+              /* Normalize.  */
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
 +
-+              b = SI_TYPE_SIZE - bm;
++#
++# NOMADIK Audio Video Drivers(SAA and SVA)
++#
++CONFIG_NOMADIK_SAA=m
++CONFIG_NOMADIK_SVA=m
++CONFIG_NOMADIK_OGL=m
++# CONFIG_USB_DABUSB is not set
 +
-+              d1 = (d1 << bm) | (d0 >> b);
-+              d0 = d0 << bm;
-+              n2 = n1 >> b;
-+              n1 = (n1 << bm) | (n0 >> b);
-+              n0 = n0 << bm;
++#
++# Graphics support
++#
++CONFIG_FIRMWARE_EDID=y
++CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++# CONFIG_FB_TILEBLITTING is not set
++CONFIG_FB_ARMCLCD=y
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
 +
-+              udiv_qrnnd (q0, n1, n2, n1, d1);
-+              umul_ppmm (m1, m0, q0, d0);
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
 +
-+              if (m1 > n1 || (m1 == n1 && m0 > n0))
-+                {
-+                  q0--;
-+                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
-+                }
++#
++# Logo configuration
++#
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 +
-+              q1 = 0;
++#
++# Sound
++#
++CONFIG_NOMADIK_ACODEC=y
++# CONFIG_NOMADIK_STW5094 is not set
++CONFIG_NOMADIK_STW5095=y
++CONFIG_SOUND=y
 +
-+              /* 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;
-+                }
-+            }
-+        }
-+    }
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
 +
-+  ww.s.low = q0;
-+  ww.s.high = q1;
-+  return ww.ll;
-+}
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
 +
-+UDItype
-+#ifdef CONFIG_AEABI
-+__aeabi_uldivmod (UDItype n, UDItype d)
-+#else
-+__udivdi3 (UDItype n, UDItype d)
-+#endif
-+{
-+  return __udivmoddi4 (n, d, (UDItype *) 0);
-+}
++#
++# ALSA ARM devices
++#
++CONFIG_SND_NOMADIK_ALSA=m
++CONFIG_SND_ARMAACI=y
 +
-+UDItype
-+__umoddi3 (UDItype u, UDItype v)
-+{
-+  UDItype w;
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
 +
-+  (void) __udivmoddi4 (u ,v, &w);
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
 +
-+  return w;
-+}
++#
++# HID Devices
++#
++CONFIG_HID=y
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/clock.c ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.c
---- linux-2.6.20/arch/arm/mach-nomadik/clock.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.c  2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,127 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/clock.c
-+ *
-+ *  Copyright (C) 2004 ARM Limited.
-+ *  Written by Deep Blue Solutions Limited.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/errno.h>
-+#include <linux/err.h>
-+#include <linux/string.h>
-+#include <linux/clk.h>
-+#include <linux/mutex.h>
++#
++# USB support
++#
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++#CONFIG_USB_DEBUG is not set
 +
-+#include <asm/semaphore.h>
-+#include <asm/hardware/icst525.h>
-+#include "clock.h"
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_BANDWIDTH=y
++CONFIG_USB_DYNAMIC_MINORS=y
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
 +
-+static LIST_HEAD(clocks);
-+static DEFINE_MUTEX(clocks_mutex);
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
 +
-+struct clk *clk_get(struct device *dev, const char *id)
-+{
-+      struct clk *p, *clk = ERR_PTR(-ENOENT);
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
 +
-+      mutex_lock(&clocks_mutex);
-+      list_for_each_entry(p, &clocks, node) {
-+              if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-+                      clk = p;
-+                      break;
-+              }
-+      }
-+      mutex_unlock(&clocks_mutex);
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
 +
-+      return clk;
-+}
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++#CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
 +
-+EXPORT_SYMBOL(clk_get);
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++# CONFIG_USB_AIPTEK is not set
++# CONFIG_USB_WACOM is not set
++# CONFIG_USB_ACECAD is not set
++# CONFIG_USB_KBTAB is not set
++# CONFIG_USB_POWERMATE is not set
++# CONFIG_USB_TOUCHSCREEN is not set
++# CONFIG_USB_YEALINK is not set
++# CONFIG_USB_XPAD is not set
++# CONFIG_USB_ATI_REMOTE is not set
++# CONFIG_USB_ATI_REMOTE2 is not set
++# CONFIG_USB_KEYSPAN_REMOTE is not set
++# CONFIG_USB_APPLETOUCH is not set
 +
-+void clk_put(struct clk *clk)
-+{
-+      module_put(clk->owner);
-+}
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
 +
-+EXPORT_SYMBOL(clk_put);
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET_MII is not set
++# CONFIG_USB_USBNET is not set
++CONFIG_USB_MON=y
 +
-+int clk_enable(struct clk *clk)
-+{
-+      return 0;
-+}
++#
++# USB port drivers
++#
 +
-+EXPORT_SYMBOL(clk_enable);
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
 +
-+void clk_disable(struct clk *clk)
-+{
-+}
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++CONFIG_USB_TEST=y
 +
-+EXPORT_SYMBOL(clk_disable);
++#
++# USB DSL modem support
++#
 +
-+unsigned long clk_get_rate(struct clk *clk)
-+{
-+      return clk->rate;
-+}
++#
++# USB Gadget Support
++#
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_AT91 is not set
++CONFIG_USB_GADGET_DUMMY_HCD=y
++CONFIG_USB_DUMMY_HCD=m
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++# CONFIG_USB_ETH is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_MIDI_GADGET is not set
++CONFIG_USB_INVENTRA_HCD=m
++CONFIG_USB_INVENTRA_HCD_HOST=y
++# CONFIG_USB_INVENTRA_HCD_GADGET_API is not set
++# CONFIG_USB_INVENTRA_HCD_OTG is not set
++# CONFIG_USB_INVENTRA_HCD_OTG_GSTORAGE is not set
++# CONFIG_USB_INVENTRA_STATIC_CONFIG is not set
++# CONFIG_USB_INVENTRA_DMA is not set
++# CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID is not set
++CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE=""
++CONFIG_USB_INVENTRA_MUSB_BOARD_FILE=""
++CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS=""
++# CONFIG_USB_INVENTRA_HCD_POLLING is not set
++CONFIG_USB_INVENTRA_HCD_LOGGING=0
 +
-+EXPORT_SYMBOL(clk_get_rate);
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
 +
-+long clk_round_rate(struct clk *clk, unsigned long rate)
-+{
-+      return 0;
-+}
++#
++# Real Time Clock
++#
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
 +
-+EXPORT_SYMBOL(clk_round_rate);
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
 +
-+int clk_set_rate(struct clk *clk, unsigned long rate)
-+{
-+      clk->rate = rate;
-+      return 0;
-+}
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
 +
-+EXPORT_SYMBOL(clk_set_rate);
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="cp437"
++# CONFIG_NTFS_FS is not set
 +
-+/*
-+ * These are fixed clocks.
-+ */
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_CONFIGFS_FS is not set
 +
-+static struct clk uart_clk = {
-+      .name = "UARTCLK",
-+      .rate = 48000000,
-+};
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
 +
-+static struct clk clcd_clk = {
-+      .name = "CLCDCLK",
-+      .rate = 48000000,
-+};
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++CONFIG_NFS_V4=y
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
 +
-+int clk_register(struct clk *clk)
-+{
-+      mutex_lock(&clocks_mutex);
-+      list_add(&clk->node, &clocks);
-+      mutex_unlock(&clocks_mutex);
-+      return 0;
-+}
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
 +
-+EXPORT_SYMBOL(clk_register);
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="cp437"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
 +
-+void clk_unregister(struct clk *clk)
-+{
-+      mutex_lock(&clocks_mutex);
-+      list_del(&clk->node);
-+      mutex_unlock(&clocks_mutex);
-+}
++#
++# Distributed Lock Manager
++#
++# CONFIG_DLM is not set
 +
-+EXPORT_SYMBOL(clk_unregister);
++#
++# Profiling support
++#
++CONFIG_PROFILING=y
++CONFIG_OPROFILE=y
 +
-+static int __init clk_init(void)
-+{
-+      clk_register(&uart_clk);
-+      clk_register(&clcd_clk);
-+      return 0;
-+}
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
++# CONFIG_DEBUG_USER is not set
 +
-+arch_initcall(clk_init);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/clock.h ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.h
---- linux-2.6.20/arch/arm/mach-nomadik/clock.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/clock.h  2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,25 @@
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_LRW is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Hardware crypto devices
++#
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=m
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_IOMAP_COPY=y
+--- linux-2.6.20.orig/arch/arm/kernel/Makefile
++++ linux-2.6.20/arch/arm/kernel/Makefile
+@@ -17,10 +17,11 @@ obj-$(CONFIG_FIQ)          += fiq.o
+ obj-$(CONFIG_MODULES)         += armksyms.o module.o
+ obj-$(CONFIG_ARTHUR)          += arthur.o
+ obj-$(CONFIG_ISA_DMA)         += dma-isa.o
+ obj-$(CONFIG_PCI)             += bios32.o isa.o
+ obj-$(CONFIG_SMP)             += smp.o
++obj-$(CONFIG_KGDB)            += kgdb.o kgdb-jmp.o
+ obj-$(CONFIG_OABI_COMPAT)     += sys_oabi-compat.o
+ obj-$(CONFIG_CRUNCH)          += crunch.o crunch-bits.o
+ AFLAGS_crunch-bits.o          := -Wa,-mcpu=ep9312
+--- linux-2.6.20.orig/arch/arm/kernel/armksyms.c
++++ linux-2.6.20/arch/arm/kernel/armksyms.c
+@@ -29,10 +29,17 @@ extern void __ashrdi3(void);
+ extern void __divsi3(void);
+ extern void __lshrdi3(void);
+ extern void __modsi3(void);
+ extern void __muldi3(void);
+ extern void __ucmpdi2(void);
++#ifdef CONFIG_AEABI
++extern void __aeabi_uldivmod(void);
++#else
++extern void __udivdi3(void);
++#endif
++extern void __umoddi3(void);
++extern void __udivmoddi4(void);
+ extern void __udivsi3(void);
+ extern void __umodsi3(void);
+ extern void __do_div64(void);
+ extern void __aeabi_idiv(void);
+@@ -137,10 +144,17 @@ EXPORT_SYMBOL(__divsi3);
+ EXPORT_SYMBOL(__lshrdi3);
+ EXPORT_SYMBOL(__modsi3);
+ EXPORT_SYMBOL(__muldi3);
+ EXPORT_SYMBOL(__ucmpdi2);
+ EXPORT_SYMBOL(__udivsi3);
++#ifdef CONFIG_AEABI
++EXPORT_SYMBOL(__aeabi_uldivmod);
++#else
++EXPORT_SYMBOL(__udivdi3);
++#endif
++EXPORT_SYMBOL(__umoddi3);
++EXPORT_SYMBOL(__udivmoddi4);
+ EXPORT_SYMBOL(__umodsi3);
+ EXPORT_SYMBOL(__do_div64);
+ #ifdef CONFIG_AEABI
+ EXPORT_SYMBOL(__aeabi_idiv);
+--- linux-2.6.20.orig/arch/arm/kernel/dma.c
++++ linux-2.6.20/arch/arm/kernel/dma.c
+@@ -226,10 +226,11 @@ EXPORT_SYMBOL(disable_dma);
+  */
+ int dma_channel_active(dmach_t channel)
+ {
+       return dma_chan[channel].active;
+ }
++EXPORT_SYMBOL(dma_channel_active);
+ void set_dma_page(dmach_t channel, char pagenr)
+ {
+       printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
+ }
+--- linux-2.6.20.orig/arch/arm/kernel/entry-armv.S
++++ linux-2.6.20/arch/arm/kernel/entry-armv.S
+@@ -13,10 +13,11 @@
+  *
+  *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
+  *  it to save wrong values...  Be aware!
+  */
++#include <asm/kgdb.h>
+ #include <asm/memory.h>
+ #include <asm/glue.h>
+ #include <asm/vfpmacros.h>
+ #include <asm/arch/entry-macro.S>
+ #include <asm/thread_notify.h>
+@@ -237,10 +238,11 @@ svc_preempt:
+       ldr     r0, [tsk, #TI_FLAGS]            @ get new tasks TI_FLAGS
+       tst     r0, #_TIF_NEED_RESCHED
+       beq     preempt_return                  @ go again
+       b       1b
+ #endif
++      CFI_END_FRAME(__irq_svc)
+       .align  5
+ __und_svc:
+       svc_entry
+--- linux-2.6.20.orig/arch/arm/kernel/irq.c
++++ linux-2.6.20/arch/arm/kernel/irq.c
+@@ -74,11 +74,23 @@ int show_interrupts(struct seq_file *p, 
+               if (!action)
+                       goto unlock;
+               seq_printf(p, "%3d: ", i);
+               for_each_present_cpu(cpu)
++#ifdef CONFIG_ARCH_NOMADIK
++              /*
++               * Outputs Priority Level for irq, if programmed
++               * refer: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt
++               */
++              if (action->flags & SA_IRQPRIORITY_MASK)
++                      seq_printf(p, "%10u:PL%02d", kstat_cpu(cpu).irqs[i],
++                                      (int)(action->flags)>>4 & 0x0f);
++              else
+                       seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
++#else
++                      seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
++#endif
+               seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
+               seq_printf(p, "  %s", action->name);
+               for (action = action->next; action; action = action->next)
+                       seq_printf(p, ", %s", action->name);
+--- /dev/null
++++ linux-2.6.20/arch/arm/kernel/kgdb-jmp.S
+@@ -0,0 +1,30 @@
 +/*
-+ *  linux/arch/arm/mach-nomadik/clock.h
++ * arch/arm/kernel/kgdb-jmp.S
 + *
-+ *  Copyright (C) 2004 ARM Limited.
-+ *  Written by Deep Blue Solutions Limited.
++ * Trivial setjmp and longjmp procedures to support bus error recovery
++ * which may occur during kgdb memory read/write operations.
 + *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * Author: MontaVista Software, Inc. <source@mvista.com>
++ *         source@mvista.com
++ *
++ * 2002-2005 (c) MontaVista Software, Inc.  This file is licensed under the
++ * terms of the GNU General Public License version 2. This program as licensed
++ * "as is" without any warranty of any kind, whether express or implied.
 + */
-+struct module;
-+struct icst525_params;
++#include <linux/linkage.h>
 +
-+struct clk {
-+      struct list_head        node;
-+      unsigned long           rate;
-+      struct module           *owner;
-+      const char              *name;
-+      const struct icst525_params *params;
-+      void                    *data;
-+      void                    (*setvco)(struct clk *, struct icst525_vco vco);
-+};
++ENTRY (kgdb_fault_setjmp)
++      /* Save registers */
++      stmia   r0, {r0-r14}
++      str     lr,[r0, #60]
++      mrs     r1,cpsr
++      str     r1,[r0,#64]
++      ldr     r1,[r0,#4]
++      mov     r0, #0
++      mov     pc,lr
 +
-+int clk_register(struct clk *clk);
-+void clk_unregister(struct clk *clk);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/cpu.c ../new/linux-2.6.20/arch/arm/mach-nomadik/cpu.c
---- linux-2.6.20/arch/arm/mach-nomadik/cpu.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/cpu.c    2008-07-04 23:45:03.000000000 +0530
-@@ -0,0 +1,293 @@
++ENTRY (kgdb_fault_longjmp)
++      /* Restore registers */
++      mov     r1,#1
++      str     r1,[r0]
++      ldmia   r0,{r0-pc}^
+--- /dev/null
++++ linux-2.6.20/arch/arm/kernel/kgdb.c
+@@ -0,0 +1,208 @@
 +/*
-+ *  linux/arch/arm/mach-nomadik/cpu.c
-+ *
-+ *  Copyright (C) STMicroelectronics
++ * arch/arm/kernel/kgdb.c
 + *
++ * ARM KGDB support
 + *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
++ * Copyright (c) 2002-2004 MontaVista Software, Inc
 + *
-+ * CPU freq driver
++ * Authors:  George Davis <davis_g@mvista.com>
++ *           Deepak Saxena <dsaxena@plexity.net>
 + */
-+#include <linux/module.h>
++//#include <linux/config.h>
 +#include <linux/types.h>
 +#include <linux/kernel.h>
-+#include <linux/cpufreq.h>
-+#include <linux/slab.h>
++#include <linux/signal.h>
 +#include <linux/sched.h>
-+#include <linux/smp.h>
++#include <linux/mm.h>
++#include <linux/spinlock.h>
++#include <linux/personality.h>
++#include <linux/ptrace.h>
++#include <linux/elf.h>
++#include <linux/interrupt.h>
 +#include <linux/init.h>
++#include <linux/kgdb.h>
 +
-+#include <asm/hardware.h>
++#include <asm/atomic.h>
 +#include <asm/io.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/i2c.h>
-+#include <asm/arch/power.h>
-+
-+#include <asm/arch/debug.h>
-+
-+#define CPUFREQ_NAME             "CPUFREQ"
-+
-+#ifndef CPUFREQ_DEBUG
-+#define CPUFREQ_DEBUG 0
-+#endif
-+
-+#define NMDK_DEBUG      CPUFREQ_DEBUG /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  CPUFREQ_NAME  /* msg header represents this module */
-+#define NMDK_DBG        KERN_ERR      /* message level */
-+
-+
-+#define PLL1_CRYSTAL_FREQ_KHZ (192 * 100)
-+#define CALC_FREQ(pll1_nmul, pll1_pdiv)   (PLL1_CRYSTAL_FREQ_KHZ * (pll1_nmul + 2)) / (1 << pll1_pdiv);
-+
-+static struct cpufreq_driver nomadik_driver;
-+static unsigned int nomadik_get(unsigned int cpu);
-+
-+extern unsigned int nomadik_freq_to_idx(unsigned int freq);
-+extern unsigned int nomadik_idx_to_freq(unsigned int idx);
-+extern u32 nomadik_setsys_freq(u32 freq_idx);
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/unistd.h>
++#include <asm/ptrace.h>
++#include <asm/traps.h>
 +
-+/*
-+ * Validate the speed policy.
-+ */
-+static int nomadik_verify_policy(struct cpufreq_policy *policy)
++/* Make a local copy of the registers passed into the handler (bletch) */
++void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
 +{
++      int regno;
 +
-+      nmdk_dbg_ftrace();
-+      cpufreq_verify_within_limits(policy,
-+                                   policy->cpuinfo.min_freq,
-+                                   policy->cpuinfo.max_freq);
-+
-+      policy->min = NOMADIK_CPUFREQ_MIN;
-+      policy->max = NOMADIK_CPUFREQ_MAX;
-+
-+      cpufreq_verify_within_limits(policy,
-+                                   policy->cpuinfo.min_freq,
-+                                   policy->cpuinfo.max_freq);
++      /* Initialize all to zero (??) */
++      for (regno = 0; regno < GDB_MAX_REGS; regno++)
++              gdb_regs[regno] = 0;
 +
-+      return 0;
++      gdb_regs[_R0] = kernel_regs->ARM_r0;
++      gdb_regs[_R1] = kernel_regs->ARM_r1;
++      gdb_regs[_R2] = kernel_regs->ARM_r2;
++      gdb_regs[_R3] = kernel_regs->ARM_r3;
++      gdb_regs[_R4] = kernel_regs->ARM_r4;
++      gdb_regs[_R5] = kernel_regs->ARM_r5;
++      gdb_regs[_R6] = kernel_regs->ARM_r6;
++      gdb_regs[_R7] = kernel_regs->ARM_r7;
++      gdb_regs[_R8] = kernel_regs->ARM_r8;
++      gdb_regs[_R9] = kernel_regs->ARM_r9;
++      gdb_regs[_R10] = kernel_regs->ARM_r10;
++      gdb_regs[_FP] = kernel_regs->ARM_fp;
++      gdb_regs[_IP] = kernel_regs->ARM_ip;
++      gdb_regs[_SP] = kernel_regs->ARM_sp;
++      gdb_regs[_LR] = kernel_regs->ARM_lr;
++      gdb_regs[_PC] = kernel_regs->ARM_pc;
++      gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;
 +}
 +
-+static int nomadik_set_target(struct cpufreq_policy *policy,
-+                            unsigned int target_freq, unsigned int relation)
++/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
++void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
 +{
-+      cpumask_t cpus_allowed;
-+      int cpu = policy->cpu;
-+      struct cpufreq_freqs freqs;
-+      unsigned int freq_idx;
-+      unsigned int new_voltage, cur_voltage;
-+      unsigned char vcore_data;
-+      int result;
-+
-+      nmdk_dbg2("%s called with target_freq = %d relation = %d\n",
-+                (__FUNCTION__), target_freq, relation);
-+      /*
-+       * Save this threads cpus_allowed mask.
-+       */
-+      cpus_allowed = current->cpus_allowed;
-+
-+      /*
-+       * Bind to the specified CPU.  When this call returns,
-+       * we should be running on the right CPU.
-+       */
-+      set_cpus_allowed(current, cpumask_of_cpu(cpu));
-+      BUG_ON(cpu != smp_processor_id());
-+
-+      freqs.old = nomadik_get(policy->cpu);
-+
-+      freq_idx = nomadik_freq_to_idx(target_freq);
-+
-+      switch (relation) {
-+      case CPUFREQ_RELATION_L:
-+              if (nomadik_idx_to_freq(freq_idx) > policy->max)
-+                      freq_idx--;
-+              break;
-+      case CPUFREQ_RELATION_H:
-+              if ((nomadik_idx_to_freq(freq_idx) > target_freq) &&
-+                  (nomadik_idx_to_freq(freq_idx - 1) >= policy->min))
-+                      freq_idx--;
-+              break;
-+      }
-+
-+      freqs.new = nomadik_idx_to_freq(freq_idx);
-+      freqs.cpu = policy->cpu;
-+
-+      nmdk_dbg2(" freqs.new  = %d\n", freqs.new);
-+      if (freqs.old == freqs.new) {
-+              set_cpus_allowed(current, cpus_allowed);
-+              return 0;
-+      }
-+
-+#if 0
-+      if ( freq_idx == 0)
-+      {
-+              nomadik_normal_to_slow = 1;
-+              nomadik_slow_to_normal = 0;
-+      }
-+      if (freqs.old == 19200 )
-+      {
-+              nomadik_slow_to_normal = 1;
-+              nomadik_normal_to_slow = 0;
-+
-+      }
-+#endif
-+
-+      cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++      kernel_regs->ARM_r0 = gdb_regs[_R0];
++      kernel_regs->ARM_r1 = gdb_regs[_R1];
++      kernel_regs->ARM_r2 = gdb_regs[_R2];
++      kernel_regs->ARM_r3 = gdb_regs[_R3];
++      kernel_regs->ARM_r4 = gdb_regs[_R4];
++      kernel_regs->ARM_r5 = gdb_regs[_R5];
++      kernel_regs->ARM_r6 = gdb_regs[_R6];
++      kernel_regs->ARM_r7 = gdb_regs[_R7];
++      kernel_regs->ARM_r8 = gdb_regs[_R8];
++      kernel_regs->ARM_r9 = gdb_regs[_R9];
++      kernel_regs->ARM_r10 = gdb_regs[_R10];
++      kernel_regs->ARM_fp = gdb_regs[_FP];
++      kernel_regs->ARM_ip = gdb_regs[_IP];
++      kernel_regs->ARM_sp = gdb_regs[_SP];
++      kernel_regs->ARM_lr = gdb_regs[_LR];
++      kernel_regs->ARM_pc = gdb_regs[_PC];
++      kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1];
++}
 +
-+      new_voltage = nomadik_freq_to_voltage(freqs.new);
-+      cur_voltage = g_nomadik_voltage;
-+      nmdk_dbg2(" new  voltage = %d\n", new_voltage);
-+      nmdk_dbg2(" old  voltage = %d\n", cur_voltage);
++static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)
++{
++      return (struct pt_regs *)
++          ((unsigned long)task->thread_info + THREAD_SIZE -
++           8 - sizeof(struct pt_regs));
++}
 +
-+      if (new_voltage > cur_voltage) {
++void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
++                               struct task_struct *task)
++{
++      int regno;
++      struct pt_regs *thread_regs;
 +
-+              vcore_data = new_voltage;
++      /* Just making sure... */
++      if (task == NULL)
++              return;
 +
-+              result =
-+                  nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
-+                                             0x1E, 1);
-+              if (unlikely(result)) {
-+                      nmdk_error("i2c write error with ret = %d\n", result);
-+                      goto err1;
++      /* Initialize to zero */
++      for (regno = 0; regno < GDB_MAX_REGS; regno++)
++              gdb_regs[regno] = 0;
 +
-+              } else
-+                      nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
++      /* Otherwise, we have only some registers from switch_to() */
++      thread_regs = kgdb_get_user_regs(task);
++      gdb_regs[_R0] = thread_regs->ARM_r0;    /* Not really valid? */
++      gdb_regs[_R1] = thread_regs->ARM_r1;    /* "               " */
++      gdb_regs[_R2] = thread_regs->ARM_r2;    /* "               " */
++      gdb_regs[_R3] = thread_regs->ARM_r3;    /* "               " */
++      gdb_regs[_R4] = thread_regs->ARM_r4;
++      gdb_regs[_R5] = thread_regs->ARM_r5;
++      gdb_regs[_R6] = thread_regs->ARM_r6;
++      gdb_regs[_R7] = thread_regs->ARM_r7;
++      gdb_regs[_R8] = thread_regs->ARM_r8;
++      gdb_regs[_R9] = thread_regs->ARM_r9;
++      gdb_regs[_R10] = thread_regs->ARM_r10;
++      gdb_regs[_FP] = thread_regs->ARM_fp;
++      gdb_regs[_IP] = thread_regs->ARM_ip;
++      gdb_regs[_SP] = thread_regs->ARM_sp;
++      gdb_regs[_LR] = thread_regs->ARM_lr;
++      gdb_regs[_PC] = thread_regs->ARM_pc;
++      gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
++}
 +
-+#ifdef CPUFREQ_DEBUG 
-+              vcore_data = 0;
++static int compiled_break;
 +
-+              result =
-+                  nomadik_i2c_read_register(I2C_TOUAREG_CLIENT, &vcore_data,
-+                                             0x1E, 1);
-+              if (unlikely(result)) {
-+                      nmdk_error("i2c read error with ret = %d\n", result);
-+                      goto err1;
++int kgdb_arch_handle_exception(int exception_vector, int signo,
++                             int err_code, char *remcom_in_buffer,
++                             char *remcom_out_buffer,
++                             struct pt_regs *linux_regs)
++{
++      long addr;
++      char *ptr;
 +
-+              } else
-+                      nmdk_dbg2("i2c read vcore_data = 0x%x\n", vcore_data);
++      switch (remcom_in_buffer[0]) {
++      case 'c':
++              kgdb_contthread = NULL;
 +
-+              if ( vcore_data != new_voltage )
-+              {
-+                      printk("i2c had not written correctly\n");
-+                      goto err1;
++              /*
++               * Try to read optional parameter, pc unchanged if no parm.
++               * If this was a compiled breakpoint, we need to move
++               * to the next instruction or we will just breakpoint
++               * over and over again.
++               */
++              ptr = &remcom_in_buffer[1];
++              if (kgdb_hex2long(&ptr, &addr)) {
++                      linux_regs->ARM_pc = addr;
++              } else if (compiled_break == 1) {
++                      linux_regs->ARM_pc += 4;
 +              }
-+#endif
-+              g_nomadik_voltage = new_voltage;
-+      }
-+
-+      nomadik_setsys_freq(freq_idx);
-+
-+      if (new_voltage < cur_voltage) {
-+
-+              vcore_data = new_voltage;
-+              result =
-+                  nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
-+                                             0x1E, 1);
-+      /**
-+       * Here even if we are not able to set lower voltage. Still system can 
-+       * work with previous voltage
-+       */
-+
-+              if (unlikely(result)) {
-+                      nmdk_error("i2c write error with ret = %d\n", result);
-+                      goto err1;
-+
-+              } else
-+                      nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
-+              g_nomadik_voltage = new_voltage;
-+
-+      }
-+
-+      err1:
 +
-+      /*
-+       * Restore the CPUs allowed mask.
-+       */
-+      set_cpus_allowed(current, cpus_allowed);
++              compiled_break = 0;
 +
-+      cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-+#if CPUFREQ_DEBUG 
-+      {
-+      int j;
-+      for(j=0; j <= 0x124; j+=4)
-+              printk("sdmc[%x] = %x\n", j, readl(0xf0110000 + j ));
++              return 0;
 +      }
-+#endif
 +
-+      return 0;
++      return -1;
 +}
 +
-+#define SRC_PLL_FREQ_OFFSET 0x14
-+static unsigned int nomadik_get(unsigned int cpu)
++static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
 +{
-+      cpumask_t cpus_allowed;
-+      unsigned int current_freq;
-+      unsigned char __iomem *src_base;
-+      unsigned long pll_reg;
-+      unsigned int pll1_nmul, pll1_pdiv;
-+
-+      nmdk_dbg_ftrace();
-+      cpus_allowed = current->cpus_allowed;
-+
-+      set_cpus_allowed(current, cpumask_of_cpu(cpu));
-+      BUG_ON(cpu != smp_processor_id());
-+      src_base = (unsigned char *)IO_ADDRESS(NOMADIK_SRC_BASE);
-+      if ( ( readl(src_base) & 0x78 )  == 0x20 )
-+      {
-+              pll_reg = readl(src_base + SRC_PLL_FREQ_OFFSET);
-+              pll1_pdiv = pll_reg & 0x7;
-+              pll1_nmul = (pll_reg >> 8) & 0x3f;
-+              current_freq = CALC_FREQ(pll1_nmul, pll1_pdiv);
-+      }
-+      else
-+              current_freq = NOMADIK_CPUFREQ_MIN;
-+
-+      set_cpus_allowed(current, cpus_allowed);
-+      nmdk_dbg2("Current_freq = %d\n", current_freq);
-+      nmdk_dbg2("pll1_nmul = 0x%x pll1_pdiv = 0x%x\n", pll1_nmul, pll1_pdiv);
++      kgdb_handle_exception(1, SIGTRAP, 0, regs);
 +
-+      g_nomadik_voltage = nomadik_freq_to_voltage(current_freq);
-+      nmdk_dbg2("g_nomadik_voltage = %x\n", g_nomadik_voltage);
-+      return current_freq;
++      return 0;
 +}
 +
-+static int nomadik_cpufreq_init(struct cpufreq_policy *policy)
++static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
 +{
-+
-+      /* set default policy and cpuinfo */
-+      policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-+      policy->cpuinfo.max_freq = NOMADIK_CPUFREQ_MAX;
-+      policy->cpuinfo.min_freq = NOMADIK_CPUFREQ_MIN;
-+      policy->cpuinfo.transition_latency = NOMADIK_CPUFREQ_TRANS_LATENCY;
-+      policy->cur = policy->min = policy->max = nomadik_get(policy->cpu);
-+      nmdk_dbg2("max cpu freq = %d min cpu freq = %d\n", NOMADIK_CPUFREQ_MAX,
-+                NOMADIK_CPUFREQ_MIN);
++      compiled_break = 1;
++      kgdb_handle_exception(1, SIGTRAP, 0, regs);
 +
 +      return 0;
 +}
 +
-+static struct cpufreq_driver nomadik_driver = {
-+      .verify = nomadik_verify_policy,
-+      .target = nomadik_set_target,
-+      .get = nomadik_get,
-+      .init = nomadik_cpufreq_init,
-+      .name = "nomadik-cpufreq",
++static struct undef_hook kgdb_brkpt_hook = {
++      .instr_mask = 0xffffffff,
++      .instr_val = KGDB_BREAKINST,
++      .fn = kgdb_brk_fn
 +};
 +
-+static int __init nomadik_cpu_init(void)
-+{
-+      return cpufreq_register_driver(&nomadik_driver);
-+}
++static struct undef_hook kgdb_compiled_brkpt_hook = {
++      .instr_mask = 0xffffffff,
++      .instr_val = KGDB_COMPILED_BREAK,
++      .fn = kgdb_compiled_brk_fn
++};
 +
-+static void __exit nomadik_cpu_exit(void)
++/*
++ * Register our undef instruction hooks with ARM undef core.
++ * We regsiter a hook specifically looking for the KGB break inst
++ * and we handle the normal undef case within the do_undefinstr
++ * handler.
++ */
++int kgdb_arch_init(void)
 +{
-+      cpufreq_unregister_driver(&nomadik_driver);
-+}
-+
-+MODULE_AUTHOR("Manish Rathi");
-+MODULE_DESCRIPTION("cpufreq driver for ARM Nomadik CPUs");
-+MODULE_LICENSE("GPL");
-+
-+module_init(nomadik_cpu_init);
-+module_exit(nomadik_cpu_exit);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl ../new/linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl
---- linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl        2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,55 @@
-+#! /usr/bin/perl
-+#
-+# gen_nomadik_kconfig.pl: Generates Kconfig in arch/arm/mach-nomadik/ considering all board specific Kconfig files.
++      register_undef_hook(&kgdb_brkpt_hook);
++      register_undef_hook(&kgdb_compiled_brkpt_hook);
 +
-+$VAR=@ARGV;
-+if (@ARGV != 1) 
-+{
-+      print "Usage: ./create_kconfig.pl <filepath>\n";
-+      print "example: ./create_kconfig.pl arch/arm/mach-nomadik\n";
-+      exit(1);
++      return 0;
 +}
 +
-+$KPATH=@ARGV[0];
-+
-+@temp=split(/mach-/, $KPATH);
-+@temp1=split(/\//, @temp[1]);
-+$mach=@temp1[0];
-+$machuc=uc($mach);
++struct kgdb_arch arch_kgdb_ops = {
++#ifndef __ARMEB__
++      .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
++#else
++      .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
++#endif
++};
+--- linux-2.6.20.orig/arch/arm/kernel/setup.c
++++ linux-2.6.20/arch/arm/kernel/setup.c
+@@ -827,10 +827,15 @@ void __init setup_arch(char **cmdline_p)
+       conswitchp = &vga_con;
+ #elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+ #endif
+ #endif
 +
-+if ( -e "$KPATH/Kconfig" ) {
-+      exit(0);
++#if   defined(CONFIG_KGDB)
++      extern void __init early_trap_init(void);
++      early_trap_init();
++#endif
+ }
+ static int __init topology_init(void)
+ {
+--- linux-2.6.20.orig/arch/arm/kernel/traps.c
++++ linux-2.6.20/arch/arm/kernel/traps.c
+@@ -277,25 +277,29 @@ asmlinkage void do_undefinstr(struct pt_
+ {
+       unsigned int correction = thumb_mode(regs) ? 2 : 4;
+       unsigned int instr;
+       struct undef_hook *hook;
+       siginfo_t info;
++      mm_segment_t fs;
+       void __user *pc;
+       /*
+        * According to the ARM ARM, PC is 2 or 4 bytes ahead,
+        * depending whether we're in Thumb mode or not.
+        * Correct this offset.
+        */
+       regs->ARM_pc -= correction;
++      fs = get_fs();
++      set_fs(KERNEL_DS);
+       pc = (void __user *)instruction_pointer(regs);
+       if (thumb_mode(regs)) {
+               get_user(instr, (u16 __user *)pc);
+       } else {
+               get_user(instr, (u32 __user *)pc);
+       }
++      set_fs(fs);
+       spin_lock_irq(&undef_lock);
+       list_for_each_entry(hook, &undef_hook, node) {
+               if ((instr & hook->instr_mask) == hook->instr_val &&
+                   (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
+@@ -680,10 +684,17 @@ void abort(void)
+ }
+ EXPORT_SYMBOL(abort);
+ void __init trap_init(void)
+ {
++#if   defined(CONFIG_KGDB)
++      return;
 +}
 +
-+open (KCONFIG, "> $KPATH/Kconfig") || die "Can't open file: $!";
-+$Kconfig_data="# Automatically generated Kconfig: don't edit\n# To add new board support create $KPATH/<board>_Kconfig file\n\nif ARCH_$machuc\n\nchoice\n\nprompt \"$mach target board\"\n\n";
-+print KCONFIG $Kconfig_data;
-+
-+@filenames =qx(ls $KPATH/*_Kconfig);
-+foreach $filename(@filenames)
-+      {
-+              @temp=split(/mach-$mach\//, $filename);
-+              @temp1=split(/_Kconfig/, @temp[1]);
-+              $filename=@temp1[0];
-+              chomp($filename);
-+              $filenameuc=uc($filename);
-+              $usc="_";
-+              print KCONFIG "config $machuc$usc$filenameuc\n\tbool \"$filename\"\n\thelp\n\t\tSupprots $filename target board for $mach platform\n\n";
-+      };
-+
-+print KCONFIG "endchoice\n\n";
-+
-+@filenames =qx(ls $KPATH/*_Kconfig);
-+foreach $filename(@filenames)
-+      {
-+              chomp($filename);
-+              print KCONFIG "source \"$filename\"\n\n";
-+      };
++void __init early_trap_init(void)
++{
++#endif
+       unsigned long vectors = CONFIG_VECTORS_BASE;
+       extern char __stubs_start[], __stubs_end[];
+       extern char __vectors_start[], __vectors_end[];
+       extern char __kuser_helper_start[], __kuser_helper_end[];
+       int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+--- linux-2.6.20.orig/arch/arm/lib/Makefile
++++ linux-2.6.20/arch/arm/lib/Makefile
+@@ -11,11 +11,11 @@ lib-y              := backtrace.o changebit.o csumip
+                  strncpy_from_user.o strnlen_user.o                 \
+                  strchr.o strrchr.o                                 \
+                  testchangebit.o testclearbit.o testsetbit.o        \
+                  ashldi3.o ashrdi3.o lshrdi3.o muldi3.o             \
+                  ucmpdi2.o lib1funcs.o div64.o sha1.o               \
+-                 io-readsb.o io-writesb.o io-readsl.o io-writesl.o
++                 io-readsb.o io-writesb.o io-readsl.o io-writesl.o udivdi3.o \
+ mmu-y := clear_user.o copy_page.o getuser.o putuser.o
+ # the code in uaccess.S is not preemption safe and
+ # probably faster on ARMv3 only
+--- /dev/null
++++ linux-2.6.20/arch/arm/lib/gcclib.h
+@@ -0,0 +1,25 @@
++/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
++/* I Molton     29/07/01 */
 +
-+if ( -e "$KPATH/Kconfig-$mach" ) {
-+      print KCONFIG "source \"$KPATH/Kconfig-$mach\"\n";
-+}
++#define BITS_PER_UNIT  8
++#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
 +
-+print KCONFIG "endif\n\n";
-+close KCONFIG;
++typedef unsigned int UQItype    __attribute__ ((mode (QI)));
++typedef          int SItype     __attribute__ ((mode (SI)));
++typedef unsigned int USItype    __attribute__ ((mode (SI)));
++typedef          int DItype     __attribute__ ((mode (DI)));
++typedef          int word_type        __attribute__ ((mode (__word__)));
++typedef unsigned int UDItype    __attribute__ ((mode (DI)));
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S ../new/linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S
---- linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S     2008-10-20 13:37:44.000000000 +0530
-@@ -0,0 +1,655 @@
-+/*
-+ * arch/arm/mach-nomadik/deep_sleep.S
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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
-+ *
-+ */
++#ifdef __ARMEB__
++  struct DIstruct {SItype high, low;};
++#else
++  struct DIstruct {SItype low, high;};
++#endif
 +
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/entry-macro.S>
++typedef union
++{
++  struct DIstruct s;
++  DItype ll;
++} DIunion;
 +
-+.global nomadik_deep_sleep
-+.extern L2dummyPointer
-+ 
-+nomadik_deep_sleep:
-+      /*Store all the general purpose registers along with the link register*/
-+      stmfd sp!,{r0-r12,lr}
+--- /dev/null
++++ linux-2.6.20/arch/arm/lib/longlong.h
+@@ -0,0 +1,184 @@
++/* longlong.h -- based on code from gcc-2.95.3
 +
-+      /* save the first parameter passed to function nomadik_deep_sleep to r12*/
-+      mov r12,r0
-+      
-+      /* save the second parameter passed to function nomadik_deep_sleep to the variable addr - mpmc_base*/
-+      ldr r11, =mpmc_base
-+      str r1,[r11]
-+      
-+      /* save the third parameter passed to function nomadik_deep_sleep to the variable addr - backup_ram_base  */
-+      ldr r11, =backup_ram_base
-+      str r2,[r11]
++   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.
 +
-+      
-+      ldr r11, =backup_ram_store
-+      mov r10,#0x250
-+      add r10, r2, r10
-+      str r10, [r11, #0x0]
++   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.
 +
-+#ifdef DEEP_SLEEP_DEBUG
-+      /*Clean entire DCache using test and clean*/
-+clean_dcache_start:
-+      mrc p15,0,r15,c7,c14,3
-+      bne clean_dcache_start
++   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.  */
 +
-+      /* Invalidate I cache and Dcache */
-+      mov r0,#0
-+      mcr p15,0,r0,c7,c7,0
++/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
 +
-+      /*Drain Write Buffers*/
-+      mov r0,#0
-+      mcr p15,0,r0,c7,c10,4
++#ifndef SI_TYPE_SIZE
++#define SI_TYPE_SIZE 32
 +#endif
-+      
-+      /* Storing the enabled values of VIC */
-+      ldr r0, =vic_base
-+      ldr r0, [r0,#0x0]
-+
-+      ldr r1, [r0,#0xC]       /* Interrupt sslection register */
-+      ldr r2, [r0, #0x2C]
-+      ldr r3, [r0, #0x10]     /* Interrupt Enable register */
-+      ldr r4, [r0, #0x30]
-+      ldr r5, [r0, #0x54]     /* Default VAR */
-+      stmfd sp!, {r1-r5}
 +
++#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.
 +
-+      ldr r1,[r0,#0x100]
-+      ldr r2,[r0,#0x104]
-+      ldr r3,[r0,#0x108]
-+      ldr r4,[r0,#0x10C]
-+      ldr r5,[r0,#0x110]
-+      ldr r6,[r0,#0x114]
-+      ldr r7,[r0,#0x118]
-+      ldr r8,[r0,#0x11C]
-+      ldr r9,[r0,#0x120]
-+      ldr r10,[r0,#0x124]
-+      ldr r11,[r0,#0x128]
-+      stmfd sp!,{r1-r11}
++   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.
 +
-+      ldr r1,[r0,#0x12C]
-+      ldr r2,[r0,#0x130]
-+      ldr r3,[r0,#0x134]
-+      ldr r4,[r0,#0x138]
-+      ldr r5,[r0,#0x13C]
-+      ldr r6,[r0,#0x200]
-+      ldr r7,[r0,#0x204]
-+      ldr r8,[r0,#0x208]
-+      ldr r9,[r0,#0x20C]
-+      ldr r10,[r0,#0x210]
-+      ldr r11,[r0,#0x214]
-+      stmfd sp!,{r1-r11}
++   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.
 +
-+      ldr r1,[r0,#0x218]
-+      ldr r2,[r0,#0x21C]
-+      ldr r3,[r0,#0x220]
-+      ldr r4,[r0,#0x224]
-+      ldr r5,[r0,#0x228]
-+      ldr r6,[r0,#0x22C]
-+      ldr r7,[r0,#0x230]
-+      ldr r8,[r0,#0x234]
-+      ldr r9,[r0,#0x238]
-+      ldr r10,[r0,#0x23C]
-+      stmfd sp!,{r1-r10}
++   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.  */
 +
-+      mrc p15,0, r0,c5,c0,0 /* FSR--Domain Fault */ 
-+      mrc p15,0, r1,c5,c0,1  /* FSR--Instruction Fault */
-+      
-+      mrc p15,0, r2,c6,c0,0 /* FAR */
-+      
-+      mrc p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
-+      mrc p15,0, r4,c9,c0,1 /* Read ICache Lockdown */
-+      
-+      mrc p15,0, r5,c9,c1,0 /* Read Data TLB  */
-+      mrc p15,0, r6,c9,c1,1 /* Read Instruction TCM region register */
-+      
-+      mrc p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
-+      
-+      mrc p15,0, r8,c13,c0,0 /* FCSE--PID */
-+      mrc p15,0, r9,c13,c0,1 /* Context-ID */
-+      
-+      /* Save all these registers onto the stack */
-+      stmfd sp!, {r0-r9}
-+              
-+      /*Move sp to non banked register. sp is not shared in banked modes.*/
-+      mov r6, sp 
-+              
-+      /* Store the two user mode registers*/
-+      sub r6,r6,#0x8
-+      stmia r6, {sp, lr}^ 
-+      mov r0,r0
++#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) \
++{register USItype __t0, __t1, __t2;                                   \
++  __asm__ ("%@ Inlined umul_ppmm                                      \n\
++      mov     %2, %5, lsr #16                                         \n\
++      mov     %0, %6, lsr #16                                         \n\
++      bic     %3, %5, %2, lsl #16                                     \n\
++      bic     %4, %6, %0, lsl #16                                     \n\
++      mul     %1, %3, %4                                              \n\
++      mul     %4, %2, %4                                              \n\
++      mul     %3, %0, %3                                              \n\
++      mul     %0, %2, %0                                              \n\
++      adds    %3, %4, %3                                              \n\
++      addcs   %0, %0, #65536                                          \n\
++      adds    %1, %1, %3, lsl #16                                     \n\
++      adc     %0, %0, %3, lsr #16"                                    \
++         : "=&r" ((USItype) (xh)),                                    \
++           "=r" ((USItype) (xl)),                                     \
++           "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
++         : "r" ((USItype) (a)),                                       \
++           "r" ((USItype) (b)));}
++#define UMUL_TIME 20
++#define UDIV_TIME 100
++#endif /* __arm__ */
 +
-+      /* Save current mode with interrupts disabled*/
-+      mrs r7, cpsr
-+      stmfd r6!, {r7} 
-+      bic r7,r7,#0xf
++#define __umulsidi3(u, v) \
++  ({DIunion __w;                                                      \
++    umul_ppmm (__w.s.high, __w.s.low, u, v);                          \
++    __w.ll; })
 +
-+      /* move the first par from r12 to r3 */
-+      mov r3,r12
-+      
-+      /** Following are the registers that are used
-+              R6:-  Stack Pointer
-+              R7:-  CPSR Value [IRQ Disabled , FIQ Disabled, Mode bit Cleared]
-+              R8:-  Virtual Address of Backup SRAM (0xA0010250) 
-+              R9:-  UART1 Base Register [Debug Device Base Register]
-+              R10:- MPMC Base Register
-+              R11:- SRC Base Register
-+              R12:- PMU Base Register
-+      */
-+                      
-+      ldr r8,=backup_ram_store 
-+      ldr r8, [r8,#0]
++#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)
 +
-+      ldr r9,=uart1_base
-+      ldr r9, [r9,#0]
-+      
-+      ldr r10,=mpmc_base
-+      ldr r10, [r10,#0]
++#define UDIV_NEEDS_NORMALIZATION 1
++#define udiv_qrnnd __udiv_qrnnd_c
 +
-+      ldr r11,=src_base       
-+      ldr r11, [r11,#0]
++extern const UQItype __clz_tab[];
++#define count_leading_zeros(count, x) \
++  do {                                                                        \
++    USItype __xr = (x);                                                       \
++    USItype __a;                                                      \
++                                                                      \
++    if (SI_TYPE_SIZE <= 32)                                           \
++      {                                                                       \
++      __a = __xr < ((USItype)1<<2*__BITS4)                            \
++        ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)                \
++        : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);  \
++      }                                                                       \
++    else                                                              \
++      {                                                                       \
++      for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)                 \
++        if (((__xr >> __a) & 0xff) != 0)                              \
++          break;                                                      \
++      }                                                                       \
++                                                                      \
++    (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);          \
++  } while (0)
+--- /dev/null
++++ linux-2.6.20/arch/arm/lib/udivdi3.c
+@@ -0,0 +1,246 @@
++/* More subroutines needed by GCC output code on some machines.  */
++/* Compile this one with gcc.  */
++/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
 +
-+      ldr r12,=pmu_base
-+      ldr r12, [r12,#0]
-+      
-+      /*Store the jump back address at this location (physical Address) */
-+      ldr r0, =backup_ram_base 
-+      ldr r0, [r0,#0]
++This file is part of GNU CC.
 +
-+      ldr r1, =after_deep_sleep
-+      mov r2, #0xC0000000 
-+      sub     r1, r1, r2 /* Change from VA to PA */
-+      
-+      str r1, [r0]
-+                 
-+    /*Enter FIQ mode-Interrupt disabled and save the banked registers*/
-+    orr r0,r7,#0x1 
-+    msr cpsr_cxsf,r0 
-+    
-+    mrs r0,spsr 
-+    stmfd r6!, {r0,r8-r14}  /* store r8 to r14 and spsr */
-+    
-+    /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
-+    orr r0,r7,#0x2
-+    msr cpsr_cxsf,r0 /* enter IRQ mode with IRQ/FIQ disable */
-+    
-+    mrs r0,spsr
-+    stmfd r6!, {r0,r13,r14}
-+    
++GNU CC 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.
 +
-+    /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
-+    orr r0,r7,#0x7
-+    msr cpsr_cxsf,r0 
-+    
-+    mrs r0,spsr
-+    stmfd r6!, {r0,r13,r14}
-+    
-+ 
-+    /*Enter Undef Mode-IRQ/FIQ disable. Save r13,r14 and spsr */
-+    orr r0,r7,#0xB
-+    msr cpsr_cxsf,r0 
-+    
-+    mrs r0,spsr
-+    stmfd r6!, {r0,r13,r14}
-+ 
++GNU CC 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.
 +
-+      /*Store the top of stack [VA] in the Scratch-Pad Register*/
-+      str r6,[r12,#0x14]
-+      
-+      /*Go back in SVC mode*/
-+      orr r0,r7,#0x3
-+      msr cpsr_cxsf,r0
-+      
-+      /* Store MMU registers */
-+      /*Domain Register on Back-up RAM structure*/
-+      mrc p15,0,r0,c3,c0,0
-+      str r0,[r8]
-+      
-+      /*TTB Register*/
-+      mrc p15,0,r0,c2,c0,0
-+      str r0,[r8,#0x4]
-+      
-+      /*MMU Enable Register*/
-+      mrc p15,0,r0,c1,c0,0
-+      str r0,[r8,#0x8]
-+      
-+      /* Virtual Address of MMU Enable*/
-+      adr r0,mmu_enabled
-+      str r0,[r8,#0xC]
++You should have received a copy of the GNU General Public License
++along with GNU CC; see the file COPYING.  If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.  */
 +
++/* As a special exception, if you link this library with other files,
++   some of which are compiled with GCC, to produce an executable,
++   this library does not by itself cause the resulting executable
++   to be covered by the GNU General Public License.
++   This exception does not however invalidate any other reasons why
++   the executable file might be covered by the GNU General Public License.
++ */
++/* support functions required by the kernel. based on code from gcc-2.95.3 */
++/* I Molton     29/07/01 */
 +
-+      /*Clear the Remap bit from SRC-Register*/
-+      ldr r0,[r11]
-+      bic r0,r0,#0x100
-+      str r0,[r11]
-+      
-+      /*Enable the Mode Status Register*/
-+      mov r0,#0 
-+      str r0,[r11,#0x8]
-+      
-+      /* Clear the PMU bit - for entering the deep sleep mode instead sleep*/
-+      ldr r0,[r12]
-+      bic r0,r0,#0x10
-+      str r0,[r12]
-+      
-+      /*Store the value of Scratch-Pad Register*/
-+      ldr r0,=backup_ram_base_phys    
-+      ldr r0,[r0,#0x0]
-+      str r0,[r12,#0x10]
-+      
-+      /*Program to wake-up in Normal mode*/   
-+      ldr r0,[r11,#0x4]
-+      bic r0,r0,#0xf
-+      orr r0,r0,#0x9
-+      str r0,[r11,#0x4]
++#include "gcclib.h"
++#include "longlong.h"
 +
-+      /*Clean entire DCache using test and clean*/
-+clean_dcache:
-+      mrc p15,0,r15,c7,c10,3
-+      bne clean_dcache
-+      
-+      /*Drain Write Buffers*/
-+      mov r0,#0
-+      mcr p15,0,r0,c7,c10,4
++const UQItype __clz_tab[] =
++{
++  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
++  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
++  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
++  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
++  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
++};
 +
-+      ldr r0, =L2dummyPointer
-+      ldr r0, [r0]
-+      mov r1, #0
-+      cmp r1, r0
-+      stmneia r0!,{r1-r8}     
++UDItype
++__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
++{
++  DIunion ww;
++  DIunion nn, dd;
++  DIunion rr;
++  USItype d0, d1, n0, n1, n2;
++  USItype q0, q1;
++  USItype b, bm;
 +
-+#ifdef CONFIG_L2CACHE_ENABLE
-+      v_l2_cache_clean_and_invalidate r0, r1
-+      v_l2_cache_sync r0, r1
-+      v_l2_cache_disable r0,r1
++  nn.ll = n;
++  dd.ll = d;
 +
-+#endif
++  d0 = dd.s.low;
++  d1 = dd.s.high;
++  n0 = nn.s.low;
++  n1 = nn.s.high;
 +
++  if (d1 == 0)
++    {
++      if (d0 > n1)
++        {
++          /* 0q = nn / 0D */
 +
-+      /* Prefetch certain instructions in the cache.  */
-+    adr r4, cache_prefetch_start
-+      adr r5, cache_prefetch_end
-+      mvn r1,#0x1F
-+      ands r4,r1,r4
-+fetch_loop:
-+      mcr p15, 0, r4, c7, c13,1
-+      cmp r4,r5
-+      addls r4, r4, #0x20
-+      bls fetch_loop
++          count_leading_zeros (bm, d0);
 +
-+              
-+cache_prefetch_start:
-+      ldr r10, =mpmc_base
-+      ldr r10,[r10,#0x0]
-+              
-+/* Check sdram is idle */
-+poll_loop:
-+      ldr r1,[r10, #0x4]
-+      ands r1,r1,#0x1
-+      cmp r1,#0
-+      bne poll_loop
++          if (bm != 0)
++            {
++              /* Normalize, i.e. make the most significant bit of the
++                 denominator set.  */
 +
-+      /*Put SDRAM in self-refresh mode*/      
-+      ldr r1,[r10, #0x20]
-+      bic r1,r1,#0x1
-+      orr r1,r1,#0x04
-+      str r1,[r10, #0x20]
++              d0 = d0 << bm;
++              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
++              n0 = n0 << bm;
++            }
 +
-+      /*Wait for SDRAM to go in self-refresh*/
-+wait:
-+      ldr r1,[r10,#0x4]
-+      and r1,r1,#0x4
-+      cmp r1,#0x0
-+      beq wait
++          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);
 +
-+      /*Move system to sleep mode*/
-+      ldr r1,[r11]
-+      bic r1, r1, #0x7
-+      str r1,[r11]
++          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).
 +
-+goto_sleep:
-+      ldr r1,[r11]
-+      and r1,r1,#0x78
-+      cmp r1,#0x0
-+      bne goto_sleep
++                 This special case is necessary, not an optimization.
++                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
 +
-+      
-+      nop
-+      nop
-+      nop
-+      nop
++              n1 -= d0;
++              q1 = 1;
++            }
++          else
++            {
++              /* Normalize.  */
 +
++              b = SI_TYPE_SIZE - bm;
 +
++              d0 = d0 << bm;
++              n2 = n1 >> b;
++              n1 = (n1 << bm) | (n0 >> b);
++              n0 = n0 << bm;
 +
++              udiv_qrnnd (q1, n1, n2, n1, d0);
++            }
 +
-+/* For deepsleep this much pre-fetch is enough */ 
-+cache_prefetch_end:
-+      mov r0, r0
-+      mov r0, r0
-+      mov r0, r0
-+      mov r0, r0
++          /* n1 != d0...  */
 +
++          udiv_qrnnd (q0, n0, n1, n0, d0);
 +
-+after_deep_sleep:
-+/* Restore the MMU registers */
++          /* Remainder in n0 >> bm.  */
++        }
++
++      if (rp != 0)
++        {
++          rr.s.low = n0 >> bm;
++          rr.s.high = 0;
++          *rp = rr.ll;
++        }
++    }
++  else
++    {
++      if (d1 > n1)
++        {
++          /* 00 = nn / DD */
 +
-+      
++          q0 = 0;
++          q1 = 0;
 +
-+      ldr r8,=backup_ram_store_phys
-+      mov r9, #0xC0000000
-+      sub r8, r8, r9  /* Change from VA to PA */
-+      ldr r8, [r8,#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.  */
 +
-+out_of_sleep:
-+ /*Domain Register*/
-+      ldr r0,[r8, #0x0]
-+      mcr p15,0,r0,c3,c0,0
-+      
-+      /*TTB Register*/
-+      ldr r0,[r8,#0x4]
-+      mcr p15,0,r0,c2,c0,0
++              /* 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;
 +
-+      /* Virtual Address of mmu_enabled*/
-+      ldr r4, [r8, #0xC]
++              if (rp != 0)
++                {
++                  rr.s.low = n0;
++                  rr.s.high = n1;
++                  *rp = rr.ll;
++                }
++            }
++          else
++            {
++              USItype m1, m0;
++              /* Normalize.  */
 +
-+      /*MMU Enable Register*/
-+      ldr r1, [r8,#0x8]
-+      mcr p15,0,r1,c1,c0,0
++              b = SI_TYPE_SIZE - bm;
 +
-+      mov pc,r4
-+      mov r0, r0
-+      mov r0, r0
-+      mov r0, r0
-+      mov r0, r0
-+      
++              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);
 +
-+mmu_enabled:
++              if (m1 > n1 || (m1 == n1 && m0 > n0))
++                {
++                  q0--;
++                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
++                }
 +
-+#ifdef DEEP_SLEEP_DEBUG
-+      ldr r9, =uart1_base
-+      ldr r9, [r9,#0]
++              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;
++}
++
++UDItype
++#ifdef CONFIG_AEABI
++__aeabi_uldivmod (UDItype n, UDItype d)
++#else
++__udivdi3 (UDItype n, UDItype d)
 +#endif
++{
++  return __udivmoddi4 (n, d, (UDItype *) 0);
++}
 +
-+      ldr r11, =src_base
-+      ldr r11, [r11,#0]
-+      ldr r12, =pmu_base
-+      ldr r12, [r12,#0]
-+      ldr r10, =mpmc_base
-+      ldr r10, [r10,#0]       
++UDItype
++__umoddi3 (UDItype u, UDItype v)
++{
++  UDItype w;
 +
++  (void) __udivmoddi4 (u ,v, &w);
 +
++  return w;
++}
 +
-+      /* Move system to Normal Mode */
-+      ldr r1,[r11]
-+      orr r1,r1,#0x4
-+      bic r1,r1,#0x3
-+      str r1,[r11]
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik
+@@ -0,0 +1,267 @@
++if ARCH_NOMADIK
 +
++# The GPIO_PIN_23 is shared between MMC and MSP0.
++# by default this pin is used for MMC for NOMADIK_NDK15_REV2_B_03 target
++# to use this pin for MSP it should be configured 'n'
++config NOMADIK_NDK15_REV2_MMC
++      bool
++      default y if NOMADIK_NDK15_REV2_B_03
 +
-+      /*Wait for the system to move in normal mode*/
-+wait_norm1:
-+      ldr r0,[r11, #0x0]
-+      and r0,r0,#0x78
-+      cmp r0, #0x20
-+      bne wait_norm1
++config NOMADIK_NDK10_CUTA
++      bool
++      default y if NOMADIK_NDK10_CUT_A1
 +
-+      
-+      /* Remove the chip from Interrupt mode */
-+      ldr r0,[r11, #0x4]
-+      bic r0,r0,#0x1
-+        str r0,[r11, #0x4]
++config NOMADIK_NDK10_CUTB
++      bool
++      default y if (NOMADIK_NDK10_CUT_B0 || NOMADIK_NDK10_CUT_B06)
 +
-+      /* Clear the interrupt mode status bit*/
-+      mov r0, #0x0
-+      str r0, [r11, #0x8]
++config NOMADIK_GPIO
++      bool
++      default y
 +
-+      /* For CLCD Refresh issue */
-+      ldr r1, =0x00000005     /* Loading the value with timeout so as to avoid flickering on CLCD */
-+      str r1, [r10, #0x408]
++config NOMADIK_ENABLE_L2CACHE
++      bool "Enable L2 Cache controller"
++      depends on (NOMADIK_NDK15 || NOMADIK_NHK15)
++      default y if NOMADIK_STN8815CAS22H11
++      select L2CACHE_ENABLE
++      help
++              Nomadik Chip version for this platfrom supports L2 Cache
++              by default it is enabled, if you want to check system
++              performanence without L2 Cache, then say no here
 +
++config GPIO_PROC
++      bool
++      default y
++      depends on NOMADIK_GPIO
 +
-+      /* Stack Restoration Routine */
-+      ldr r6,[r12,#0x14]
++config NOMADIK_DMA
++      tristate "NOMADIK DMA SUPPORT"
++      depends on ISA_DMA_API
++      default y
++      help
++              Nomadik DMA low level driver for standrd DMA interface
 +
-+      /* Store the value of cpsr in r7*/
-+      mrs r7,cpsr 
-+      orr r7,r7,#0xC0 /*Not Needed*/
-+      bic r7,r7,#0xf
-+              
-+      /*Move to undef mode and restore everything*/
-+    orr r0,r7,#0xB
-+    msr cpsr_cxsf,r0 
-+    
-+    ldmfd r6!, {r0,r13,r14}
-+    msr spsr_cxsf,r0
-+        
-+    /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
-+    orr r0,r7,#0x7
-+    msr cpsr_cxsf,r0 
-+    
-+    ldmfd r6!, {r0,r13,r14}
-+    msr spsr_cxsf,r0
-+        
-+     /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
-+    orr r0,r7,#0x2
-+    msr cpsr_cxsf,r0 
-+    
-+    ldmfd r6!, {r0,r13,r14}
-+    msr spsr_cxsf,r0
-+     
-+    
-+    /*Enter FIQ mode-Interrupt disabled and save the banked registers. Save: r8-r14 and spsr*/
-+    orr r0,r7,#0x1 
-+    msr cpsr_cxsf,r0 
-+    
-+    ldmfd r6!, {r0,r8-r14} 
-+    msr spsr_cxsf,r0
-+        
-+    /* Here we will restore our cpsr..IRQ/FIQ Disabled*/
-+    ldr r0, [r6]
-+    msr cpsr_cxsf, r0
-+    add r6, r6,#4
-+      
-+    /*Now only two user-mode registers are left*/
-+    ldmia r6,{sp, lr}^ 
-+    mov r0,r0
-+    add r6,r6,#8
-+    
-+    /*Restore sp*/
-+    mov sp,r6
-+    
-+    
-+    /*ReStore the remaining items*/
-+    ldmfd sp!, {r0-r9}
-+    
-+    mcr p15,0, r0,c5,c0,0 /*FSR--Domain Fault */ 
-+      mcr p15,0, r1,c5,c0,1 /*FSR--Instruction Fault */
++config NOMADIK_SSP
++      tristate "NOMADIK SSP SUPPORT"
++      depends on (NOMADIK_DMA && NOMADIK_SPI)
++      default m
++      help
++              Depends on Nomadik DMA driver and SPI driver
 +
-+      mcr p15,0, r2,c6,c0,0 /* FAR */
-+      
-+      mcr p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
-+      mcr p15,0, r4,c9,c0,1  /* Read ICache Lockdown */
-+      
-+      mcr p15,0, r5,c9,c1,0 /* Read Data TLB  */
-+      mcr p15,0, r6,c9,c1,1 /* Read Instruction Lockdown */
-+      
-+      mcr p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
-+      
-+      mcr p15,0, r8,c13,c0,0 /* FCSE--PID */
-+      mcr p15,0, r9,c13,c0,1  /* Context-ID */
++config NOMADIK_MSP
++      tristate "NOMADIK MSP SUPPORT"
++      depends on (NOMADIK_DMA && NOMADIK_SPI)
++      default m
++      help
++              Depends on Nomadik DMA driver and SPI driver
 +
++config NOMADIK_MTU
++      tristate "NOMADIK MTU SUPPORT"
++      default m
++      help
++              The driver offers 8 MTU units tobe used.
++              In case of module only MTU1 unit will be
++              available with 4 timers:
++                      MTU1_T0, MTU1_T1, MTU1_T2 & MTU1_T3
 +
-+      
++config NOMADIK_MTU_SYSTEM_TICK
++      bool "NOMADIK MTU SYSTEM TICK SUPPORT"
++      depends on NOMADIK_MTU
++      help
++              This will prevent the system tick to be used through MTU.
++      default y
 +
++config NOMADIK_RTC
++      bool "NOMADIK RTC/RTT SUPPORT"
++      default y
++      help
++              The driver offers RTC and RTT support.
++              The RTC can be used through /dev/rtc interface for real
++              time calculations, alarms, long delays if required
++              If unsure say Y here.
 +
++config NOMADIK_PM
++      bool "NOMADIK POWER MANAGEMENT SUPPORT"
++      depends on ( (NOMADIK_NHK15 || NOMADIK_NDK15) && NOMADIK_RTC )
++      default y
++      select  PM if NOMADIK_PM
++      help
++              Nomadik Power Management Driver
 +
-+      /* ReStoring the enabled values of VIC */
-+      ldr r0, =vic_base
-+      ldr r0, [r0,#0]
++config NOMADIK_SVA_INIT_MEM
++      bool "NOMADIK SVA MEMORY at initialisation"
++      default n
++      help
++              The driver uses physically contiguous memory allocated
++              at kernel initialisation time.
++              If unsure say N here.
 +
-+      ldmfd sp!,{r1-r10}
-+      str r1,[r0,#0x218]
-+      str r2,[r0,#0x21C]
-+      str r3,[r0,#0x220]
-+      str r4,[r0,#0x224]
-+      str r5,[r0,#0x228]
-+      str r6,[r0,#0x22C]
-+      str r7,[r0,#0x230]
-+      str r8,[r0,#0x234]
-+      str r9,[r0,#0x238]
-+      str r10,[r0,#0x23C]
++config FORCE_MAX_ZONEORDER
++      int "Maximum zone order"
++      default "13"
++      help
++        For use cases having large memory requirements choosing a
++        larger memory size is advised.
 +
++config NOMADIK_SVA_MEM_SIZE
++      int "SVA initial memory size" if NOMADIK_SVA_INIT_MEM
++      default "4"
++      help
++        For use cases having large memory requirements choosing a
++        larger memory size is advised.
 +
-+      ldmfd sp!,{r1-r11}
-+      str r1,[r0,#0x12C]
-+      str r2,[r0,#0x130]
-+      str r3,[r0,#0x134]
-+      str r4,[r0,#0x138]
-+      str r5,[r0,#0x13C]
-+      str r6,[r0,#0x200]
-+      str r7,[r0,#0x204]
-+      str r8,[r0,#0x208]
-+      str r9,[r0,#0x20C]
-+      str r10,[r0,#0x210]
-+      str r11,[r0,#0x214]
++config NOMADIK_SVA_VPIP
++    bool "NOMADIK SVA VPIP support"
++    default y
++    help
++        This enables the support for VPIP in SVA driver. This allows to
++        create IRP services in SVA to grab the images from sensor CCP0.
++        Warning: This disables Ethernet & MTD devices.
 +
++config NOMADIK_SAA_INIT_MEM
++      bool "NOMADIK SAA MEMORY at initialisation"
++      default n
++      help
++              The SAA driver uses physically contiguous memory allocated
++              at kernel initialisation time.
++              If unsure say N here.
 +
++#Configuration for default display setup
++choice
++      prompt "Default Display Type"
++      depends on FB
++      default FB_NOMADIK_QVGA_PORTRAIT
 +
-+      ldmfd sp!,{r1-r11}
-+      str r1,[r0,#0x100]
-+      str r2,[r0,#0x104]
-+      str r3,[r0,#0x108]
-+      str r4,[r0,#0x10C]
-+      str r5,[r0,#0x110]
-+      str r6,[r0,#0x114]
-+      str r7,[r0,#0x118]
-+      str r8,[r0,#0x11C]
-+      str r9,[r0,#0x120]
-+      str r10,[r0,#0x124]
-+      str r11,[r0,#0x128]
++config FB_NOMADIK_VGA
++      bool "CLCD VGA"
 +
-+      ldmfd sp!, {r1-r5}
-+      str r1, [r0,#0xC]       /* Interrupt sslection register */
-+      str r2, [r0, #0x2C]
-+      str r3, [r0, #0x10]     /* Interrupt Enable register */
-+      str r4, [r0, #0x30]
-+      str r5, [r0, #0x54]     /* Default VAR */
-+      
++config FB_NOMADIK_CRT
++      bool "CRT VGA"
 +
++config FB_NOMADIK_QVGA_PORTRAIT
++      bool "CLCD QVGA Portrait"
 +
-+      /*Clean entire DCache using test and clean*/
-+clean_dcache_end:
-+      mrc p15,0,r15,c7,c14,3
-+      bne clean_dcache_end
++config FB_NOMADIK_QVGA_LANDSCAPE
++      bool "CLCD QVGA Landscape"
 +
-+      
-+      /* Invalidate I cache and Dcache */
-+      mov r0,#0
-+      mcr p15,0,r0,c7,c7,0
++config FB_NOMADIK_WVGA
++        bool "CLCD WVGA"
++endchoice
 +
-+      /*Drain Write Buffers*/
-+      mov r0,#0
-+      mcr p15,0,r0,c7,c10,4
++choice
++        prompt "Default Display BPP"
++        depends on FB
++        default FB_NOMADIK_PANEL_24BPP_PACKED
 +
-+      mov r0,#0
-+      mcr     p15, 0, r0, c8, c7, 0           @ invalidate I & D TLBs
++config FB_NOMADIK_PANEL_8BPP
++        bool "8 BPP"
 +
-+      mov r0,#0
-+      mov r0,#0
-+      mov r0,#0
-+      mov r0,#0
++config FB_NOMADIK_PANEL_16BPP
++        bool "16 BPP"
 +
++config FB_NOMADIK_PANEL_24BPP
++        bool "24 BPP"
 +
-+#ifdef DEEP_SLEEP_DEBUG
-+      ldr r0, =uart1_base
-+      ldr r0, [r0,#0x0]
-+      mov r1, #0x65
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+      mov r1, #0x66
-+      str r1, [r0]
-+#endif
-+      
-+    
-+/*Try to go back also...FIQ Disabled...IRQ Disabled*/
-+    ldmfd sp!,{r0-r12,pc}
++config FB_NOMADIK_PANEL_24BPP_PACKED
++        bool "24 BPP Packed"
 +
++endchoice
 +
-+uart1_phys:
-+      .word 0x101FB000
-+src_phys:
-+      .word 0x101E0000
-+backup_ram_store_phys:
-+      .word 0x80010250 
-+mtu0_base:
-+      .word 0xf01E2000
++config FB_NOMADIK_ACCLN
++      bool "Nomadik Graphics Acceleration"
++      tristate
++      depends on FB
++      default y
++      help
++        enable hw accln for graphics on nomadik
 +
-+uart1_base:
-+      .word 0xf01FB000
-+src_base:
-+      .word 0xf01E0000
-+pmu_base:
-+      .word 0xf01E9000
-+fsmc_base:
-+      .word 0xf0100000
-+backup_ram_base_phys:
-+      .word 0x80010000
-+vic_base: 
-+      .word 0xf0140000
-+mpmc_base:
-+      .word 0xf0110000
-+backup_ram_store:
-+      .word 0x80010250        
-+backup_ram_base:
-+      .word 0x80010000
-+.end
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/dfs.S ../new/linux-2.6.20/arch/arm/mach-nomadik/dfs.S
---- linux-2.6.20/arch/arm/mach-nomadik/dfs.S   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/dfs.S    2008-07-28 15:20:41.000000000 +0530
-@@ -0,0 +1,355 @@
-+/*
-+ * arch/arm/mach-nomadik/sleep.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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
-+ *
-+ * Low-level Nomadik DFS support 
-+ */
++config FB_NOMADIK_PANEL_BPP
++      int
++      default 16 if !FB
++      default 8 if FB_NOMADIK_PANEL_8BPP
++      default 16 if FB_NOMADIK_PANEL_16BPP
++      default 24 if FB_NOMADIK_PANEL_24BPP_PACKED
++      default 32 if FB_NOMADIK_PANEL_24BPP
 +
-+.align 5
-+.globl dfs
++config FB_NOMADIK_PANEL_NAME
++      string
++      default "VGA" if !FB
++      default "VGA" if FB_NOMADIK_VGA
++      default "CRT" if FB_NOMADIK_CRT
++      default "QVGA_Portrait" if FB_NOMADIK_QVGA_PORTRAIT
++      default "QVGA_Landscape" if FB_NOMADIK_QVGA_LANDSCAPE
++      default "WVGA" if FB_NOMADIK_WVGA
 +
++config FB_NOMADIK_PANEL_XRES
++      int
++      default 800 if FB_NOMADIK_WVGA
++      default 640 if !FB
++      default 640 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT)
++      default 240 if FB_NOMADIK_QVGA_PORTRAIT
++      default 320 if FB_NOMADIK_QVGA_LANDSCAPE
 +
-+dfs:
-+      stmfd sp!,{r4-r12,lr}
++config FB_NOMADIK_PANEL_YRES
++      int
++      default 480 if !FB
++      default 480 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT || FB_NOMADIK_WVGA)
++      default 320 if FB_NOMADIK_QVGA_PORTRAIT
++      default 240 if FB_NOMADIK_QVGA_LANDSCAPE
 +
-+      str r3,  bkup_adr_base 
-+      add r4, r3, #8
-+      str r4,  bkup_adr 
-+      add r4, r3, #0x1c8
-+      str r4,  bkup_data 
-+      add r4, r3, #0x388
-+      str r4,  bkup_action 
-+      add r4, r3, #0x3f8
-+      str r4,  bkup_size 
++config FB_NOMADIK_PANEL_LFMARGIN
++      hex
++      default 0xD6 if FB_NOMADIK_WVGA
++      default 0x21 if !FB
++      default 0x21 if FB_NOMADIK_VGA
++      default 0x29 if FB_NOMADIK_CRT
++      default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
-+      ldr r9, bkup_size       
-+      ldr r9,[r9]
-+      ldr r10,bkup_adr
-+      ldr r11,bkup_data
-+      ldr r12,bkup_action
++config FB_NOMADIK_PANEL_RTMARGIN
++      hex
++      default 0x27 if FB_NOMADIK_WVGA
++      default 0x40 if !FB
++      default 0x40 if FB_NOMADIK_VGA
++      default 0x09 if FB_NOMADIK_CRT
++      default 0x2f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
-+      mrc p15, 0, r3, c10, c0, 0      /* read the lockdown register */
-+      orr r3, r3, #1                  /* set the preserved bit */
-+      mcr p15, 0, r3, c10, c0, 0      /* write to the lockdown register */
-+      
++config FB_NOMADIK_PANEL_UPRMARGIN
++      hex
++      default 0x22 if FB_NOMADIK_WVGA
++      default 0x07 if !FB
++      default 0x07 if FB_NOMADIK_VGA
++      default 0x19 if FB_NOMADIK_CRT
++      default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
++config FB_NOMADIK_PANEL_LWRMARGIN
++      hex
++      default 0xA if FB_NOMADIK_WVGA
++      default 0x24 if !FB
++      default 0x24 if FB_NOMADIK_VGA
++      default 0x02 if FB_NOMADIK_CRT
++      default 0x0f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
++config FB_NOMADIK_PANEL_HSLEN
++      hex
++      default 0x1 if FB_NOMADIK_WVGA
++      default 0x40 if !FB
++      default 0x40 if FB_NOMADIK_VGA
++      default 0x61 if FB_NOMADIK_CRT
++      default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
-+      ldr r4, mpmc_base                       
-+      mcr p15, 0, r4, c8, c7, 1       
-+      ldr r4, [r4]    
-+      mrc p15, 0, r3, c10, c0, 0      
-+                              
-+      
-+      ldr r4, src_base        
-+      mcr p15, 0, r4, c8, c7, 1       
-+      ldr r4, [r4]                            
-+      mrc p15, 0, r3, c10, c0, 0      
-+      
-+      ldr r4, bkup_adr_base
-+      mcr p15, 0, r4, c8, c7, 1
-+      ldr r4, [r4]    
-+      mrc p15, 0, r3, c10, c0, 0      
-+      
-+      
-+      bic r3, r3, #1                          /* clear preserve bit */
-+      mcr p15, 0, r3, c10, c0, 0      /* write to the lockdown register */    
-+              
-+      ldr r7,mpmc_base
-+      ldr r8,src_base         
++config FB_NOMADIK_PANEL_VSLEN
++      hex
++      default 0x1 if FB_NOMADIK_WVGA
++      default 0x19 if !FB
++      default 0x19 if FB_NOMADIK_VGA
++      default 0x02 if FB_NOMADIK_CRT
++      default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
-+/*
-+      mov r7, #0xf0
-+      lsl r7, #8
-+      orr r7, r7, #0x11
-+      lsl r7, #16
++config FB_NOMADIK_PANEL_TIM2VAL
++      hex
++      default 0x031f1822 if FB_NOMADIK_WVGA
++      default 0x027f1800 if !FB
++      default 0x027f1800 if (FB_NOMADIK_VGA)
++      default 0x027f3800 if (FB_NOMADIK_CRT)
++      default 0x00ef1804 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++#Configuration for default display setup ends here
 +
-+      mov r8, #0xf0
-+      lsl r8, #8
-+      orr r8, r8, #0x1e
-+      lsl r8, #16
-+*/
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/Makefile
+@@ -0,0 +1,166 @@
++#
++# Makefile for the linux kernel.
++#
 +
++ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
++include $(TOPDIR)/.config
++endif
 +
-+      /* Prefetch certain instructions in the cache.  */
-+    adr r4, cache_prefetch_start1
-+      adr r5, cache_prefetch_end1
-+      mvn r3,#0x1F
-+      ands r4,r3,r4
-+fetch_loop:
-+      mcr p15, 0, r4, c7, c13,1
-+      cmp r4,r5
-+      addls r4, r4, #0x20
-+      bls fetch_loop
++# Object file lists.
 +
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
++TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
++SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
++PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
++NMDK_EXTRA_CFLAGS = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
 +
++EXTRA_CFLAGS-y                        := $(NMDK_EXTRA_CFLAGS)
++EXTRA_CFLAGS-$(CONFIG_NOMADIK_MTU)    += -DCONFIG_MTU0
++CFLAGS += $(EXTRA_CFLAGS-y)
 +
-+cache_prefetch_start1:
-+      
-+      /**
-+       *Put SDRAM in self-refresh mode
-+       */
-+      ldr r3,[r7, #0x20]
-+      orr r3,r3,#0x04
-+      str r3,[r7, #0x20]
++# NMDKDBG_FLAGS maintainence for all Nomadik debuging strategy
++# Add new entry for new component to be supported here
++NMDKDBG_FLAGS :=
 +
++ifdef VIC_DEBUG
++NMDKDBG_FLAGS += -DVIC_DEBUG=$(VIC_DEBUG)
++endif
 +
-+      /**
-+       *Wait for SDRAM to go in self-refresh
-+       */
-+wait_till_selfrefresh :
-+      ldr r3,[r7,#0x4]
-+      and r3,r3,#0x4
-+      cmp r3,#0x0
-+      beq wait_till_selfrefresh
++ifdef RTC_DEBUG
++NMDKDBG_FLAGS += -DRTC_DEBUG=$(RTC_DEBUG)
++endif
 +
++ifdef GPIO_DEBUG
++NMDKDBG_FLAGS += -DGPIO_DEBUG=$(GPIO_DEBUG)
++endif
 +
-+      /**
-+       * Stop the DLL, leave SDMC on
-+       */
-+      ldr r3,[r7]
-+      bic r3,r3,#0x2
-+      str r3,[r7]
++ifdef DMA_DEBUG
++NMDKDBG_FLAGS += -DDMA_DEBUG=$(DMA_DEBUG)
++endif
 +
-+      /**
-+       *Move the system in Slow mode
-+       */
-+      ldr r3,[r8]
-+      bic r3,r3,#0x7
-+      orr r3,r3,#0x2
-+      str r3,[r8]
++ifdef EPIO_DEBUG
++NMDKDBG_FLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG)
++endif
 +
-+wait_till_slow_mode:
-+      ldr r3,[r8]
-+      and r3,r3,#0x78
-+      cmp r3,#0x10
-+      bne wait_till_slow_mode
-+      
-+      ldr r3,[r8]
-+      bic r3,r3,#0x6000
-+      orr r3,r3,r2,LSL #13
-+      str r3,[r8]
++ifdef SPI_DEBUG
++NMDKDBG_FLAGS += -DSPI_DEBUG=$(SPI_DEBUG)
++endif
 +
-+      ldr r3,[r8,#0x14]
-+      bic r3,r3,#0x3F00
-+      bic r3,r3,#0x7
-+      orr r3,r3,r0
-+      orr r3,r3,r1,LSL #8
-+      str r3,[r8,#0x14]
-+      
-+      /**
-+       *Move the system in Normal mode
-+       */
-+      ldr r0,[r8, #0x0]
-+      ldr r1, =0xfffffff8
-+      and r0,r0,r1
-+      orr r0,r0,#0x4
-+      str r0,[r8, #0x0]
-+      
-+wait_till_normal_mode:
-+      ldr r0,[r8, #0x0]
-+      and r0,r0,#0x78
-+      cmp r0, #0x20
-+      bne wait_till_normal_mode
-+ 
-+ 
-+#define ACTION_WRITE  0x01
-+#define ACTION_WRITE_AND      0x02
-+#define ACTION_WRITE_OR       0x03
-+#define ACTION_READ   0x04
-+#define ACTION_POLL   0x05
-+#define ACTION_POLL_AND       0x06
-+#define ACTION_POLL_OR        0x07
-+#define ACTION_WAIT   0x08
-+
-+/*
-+      ldr r12,bkup_size
-+      ldr r9,[r12]
-+      
-+      ldr r10,bkup_adr
-+      ldr r11,bkup_data
-+      ldr r12,bkup_action
-+*/
-+      
-+
-+      mov r8,#0x0
-+loop1:
-+      cmp r8,r9
-+      beq end1
-+      
-+      ldr r7,[r10]
-+      ldr r6,[r11]
-+      ldr r5,[r12]
++ifdef SSP_DEBUG
++NMDKDBG_FLAGS += -DSSP_DEBUG=$(SSP_DEBUG)
++endif
 +
-+      mov r2,r8
-+      and r2,r2,#0x3
-+      mov r2,r2,LSL #0x3
-+      mov r5,r5,LSR r2
-+      and r5,r5,#0xFF
++ifdef MSP_DEBUG
++NMDKDBG_FLAGS += -DMSP_DEBUG=$(MSP_DEBUG)
++endif
 +
-+      
-+      /**
-+        Decide action to be taken
-+       */
-+      ldr r4,=ACTION_WRITE    
-+      cmp r5,r4
-+      beq action_write
-+      ldr r4,=ACTION_WRITE_AND
-+      cmp r5,r4
-+      beq action_write_and
-+      ldr r4,=ACTION_WRITE_OR
-+      cmp r5,r4
-+      beq action_write_or
-+      ldr r4,=ACTION_READ
-+      cmp r5,r4
-+      beq action_read
-+      ldr r4,=ACTION_POLL
-+      cmp r5,r4
-+      beq action_poll
-+      ldr r4,=ACTION_POLL_AND
-+      cmp r5,r4
-+      beq action_poll_and
-+      ldr r4,=ACTION_POLL_OR
-+      cmp r5,r4
-+      beq action_poll_or
-+      ldr r4,=ACTION_WAIT
-+      cmp r5,r4
-+      beq action_wait
-+      b action_end
-+action_write:
-+#if 0
-+      mov r4, #0xf0
-+      lsl r4, #8
-+      orr r4, #0x1f
-+      lsl r4, #8
-+      orr r4, #0xb0
-+      lsl r4, #8
++ifdef KEYPAD_DEBUG
++NMDKDBG_FLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG)
++endif
 +
-+      mov r3, #0x73
-+      str r3, [r4]
-+#endif
-+      str r6,[r7]
-+      b action_end
-+action_write_and:
++ifdef TOUCHP_DEBUG
++NMDKDBG_FLAGS += -DTOUCHP_DEBUG=$(TOUCHP_DEBUG)
++endif
 +
-+      b action_end
-+action_write_or:
-+      ldr r3,[r7]
-+      orr r3,r3,r6
-+      str r3,[r7]
-+      b action_end
-+action_read:
-+      ldr r3,[r7]
-+      b action_end
-+action_poll:
-+      b action_end
-+action_poll_and:
-+      b action_end
-+action_poll_or:
-+      b action_end
-+action_wait:
-+      cmp r6,#0x0
-+      beq action_end
-+      sub r6,r6,#0x1
-+      b action_wait
-+action_end:
-+      
-+      add r10,r10,#0x4
-+      add r11,r11,#0x4
-+      /**
-+       * Determine if r8 is multiple of 4 and r12 must be increased
-+       */
-+      mov r2,r8
-+      and r2,r2,#0x3
-+      cmp r2,#0x3
-+      bne incr8
-+      add r12,r12,#0x4
-+incr8:
-+      add r8,r8,#0x01
-+      b loop1
-+end1:
++ifdef POWER_DEBUG
++NMDKDBG_FLAGS += -DPOWER_DEBUG=$(POWER_DEBUG)
++endif
 +
-+      mov r10, #0xf0
-+      lsl r10, #8
-+      orr r10, r10, #0x11
-+      lsl r10, #16
++ifdef PM_DEBUG
++NMDKDBG_FLAGS += -DPM_DEBUG=$(PM_DEBUG)
++endif
 +
++ifdef CPUFREQ_DEBUG
++NMDKDBG_FLAGS += -DCPUFREQ_DEBUG=$(CPUFREQ_DEBUG)
++endif
 +
++ifdef SLEEP_DEBUG
++NMDKDBG_FLAGS += -DSLEEP_DEBUG=$(SLEEP_DEBUG)
++endif
 +
++ifdef SVA_DEBUG
++NMDKDBG_FLAGS += -DSVA_DEBUG=$(SVA_DEBUG)
++endif
++#export the nomadik debug flags for driver/* build
++CFLAGS += $(NMDKDBG_FLAGS)
 +
-+      ldr r1,[r10]
-+      orr r1,r1,#0x2
-+      str r1,[r10]
-+      
-+      /* Wait for the DLL to lock */
-+waitlock:
-+      ldr r1,[r10,#0x4]
-+      and r1,r1,#0x8
-+      cmp r1,#0x0
-+      beq waitlock
-+ 
-+      /* Exit DDR-SDRAM from self-refresh mode */
-+      ldr r1,[r10, #0x20]
-+      bic r1,r1,#0x04 
-+      str r1,[r10, #0x20]
++obj-y := gpio.o clock.o timer.o irq.o fsmc.o
 +
-+      /* Wait for DDR-SDRAM to exit from self-refresh */
-+loop_refresh:
-+      ldr r1,[r10,#0x4]
-+      and r1,r1,#0x4
-+      cmp r1,#0x4
-+      beq loop_refresh
-+      
++obj-y += $(SOC_NAME)_devices.o
++obj-y += $(PLATFORM_NAME)_devices.o
 +
-+    ldmfd sp!,{r4-r12,pc}
++# Soc Specific modules
 +
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
++obj-$(CONFIG_NOMADIK_PM)      += sleep.o deep_sleep.o soft_sleep.o  normal.o slow.o pm.o
 +
-+cache_prefetch_end1 :  /* This is the end of the code to be copied into eSRAM */
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
-+mov r0,r0
++ifeq ($(CONFIG_NOMADIK_PM),y)
++obj-y += power.o
++endif
 +
-+bkup_adr_base :
-+      .word 0x80010000
-+bkup_adr :
-+      .word 0x80010008
-+bkup_data :
-+      .word 0x800101C8
-+bkup_action :
-+      .word 0x80010388
-+bkup_size :
-+      .word 0x800103F8
-+src_base :
-+      .word 0xf01E0000
-+mpmc_base :
-+      .word 0xf0110000
-+uart1_base :
-+      .word 0xf01fb000
-+      
++ifeq ($(CONFIG_L2CACHE_ENABLE),y)
++obj-y += l2cc.o
++endif
++ifeq ($(CONFIG_CPU_FREQ_NOMADIK),y)
++obj-y += power.o slow.o
++endif
 +
++obj-$(CONFIG_CPU_FREQ_NOMADIK)        += cpu.o dfs.o
++obj-$(CONFIG_NOMADIK_DMA)       += nmdkmod_DMA.o
++obj-$(CONFIG_NOMADIK_SSP)       += nmdkmod_ssp.o
++obj-$(CONFIG_NOMADIK_MSP)     += nmdkmod_msp.o
++obj-$(CONFIG_NOMADIK_MTU)     += nmdkmod_mtu.o
++obj-$(CONFIG_NOMADIK_RTC)     += nmdkmod_rtc.o
 +
++nmdkmod_gpio-objs             := gpio.o
++nmdkmod_DMA-objs      := dma.o
++nmdkmod_ssp-objs              := ssp.o
++nmdkmod_msp-objs      := msp.o
++nmdkmod_mtu-objs      := mtu.o
++nmdkmod_rtc-objs      := rtc.o
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/dma.c ../new/linux-2.6.20/arch/arm/mach-nomadik/dma.c
---- linux-2.6.20/arch/arm/mach-nomadik/dma.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/dma.c    2008-07-04 23:45:04.000000000 +0530
-@@ -0,0 +1,1337 @@
-+/*
-+ * arch/arm/mach-nomadik/dma.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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
-+ *
-+ * Nomadik DMA driver to support standard APIs.
-+ * the API details can be found at ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
-+ *
-+ * Author : Prafulla WADASKAR <prafulla.wadaskar@st.com>
-+ */
-+#define DMA_VER "2.1.0"
++# Auto board configuration/dependency resolution
++#include $(TOPDIR)/.config
 +
-+#include <linux/module.h>     /* module functions */
-+#include <linux/slab.h>
-+#include <linux/mman.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>               /* For wait queues */
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/spinlock.h>   /* spinlocks */
-+#include <linux/errno.h>      /* err nos */
-+#include <linux/sched.h>      /* wait macros */
-+#include <linux/mm.h>         /* GFP flags */
-+#include <linux/amba/bus.h>   /* Amba device register */
-+#include <linux/cpufreq.h>
-+#include <asm/page.h>
-+#include <asm/dma.h>
-+#include <asm/fiq.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>               /* for cli etc */
-+#include <asm/hardware.h>
-+#include <asm/hardware/iomd.h>
-+#include <asm/mach/dma.h>
-+#include <asm/mach/irq.h>
-+#include <asm/arch/defs.h>
-+#include <asm/arch/memory.h>
-+#include <asm/arch/debug.h>
++SOC_HEADER  = include/asm-arm/arch-nomadik/soc_devices.h
++PDEV_HEADER = include/asm-arm/arch-nomadik/board_devices.h
 +
-+#define DMA_NAME              "DMA"
++$(TOPDIR)/.platform:
++      $(Q)echo "Generating $@"
++      $(Q)echo $(CONFIG_NOMADIK_PLATFORM) > $@
 +
-+#ifndef DMA_DEBUG
-+#define DMA_DEBUG 0
-+#endif
++$(TOPDIR)/.soc:
++      $(Q)echo "Generating $@"
++      $(Q)echo $(CONFIG_NOMADIK_SOC) > $@
 +
-+#define NMDK_DEBUG    DMA_DEBUG       /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  DMA_NAME      /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++$(TOPDIR)/.target:
++      $(Q)echo "Generating $@"
++      $(Q)echo $(CONFIG_NOMADIK_TARGET) > $@
 +
-+/* Macros used to identify standard dma structure elements for Nomadik implimentation*/
-+#define dmaconfig_pipeadr(x)  ((x)->dma_base)
++$(TOPDIR)/$(PDEV_HEADER):
++      $(Q)echo "Generating SYMLINK $(PDEV_HEADER) -> $(PLATFORM_NAME)_devices.h"
++      $(Q)rm -rf $@
++      $(Q)ln -s $(PLATFORM_NAME)_devices.h $@
 +
-+#define dmaconfig_defconfig(x)        ((x)->buf.page)
-+#define dmaconfig_config(x)   ((x)->buf.offset)
-+#define dmaconfig_usrconfig(x)        ((x)->buf.dma_address)
-+#define dmaconfig_mode(x)     ((x)->buf.length)
++$(TOPDIR)/$(SOC_HEADER):
++      $(Q)echo "Generating SYMLINK $(SOC_HEADER) -> $(SOC_NAME)_devices.h"
++      $(Q)rm -rf $@
++      $(Q)ln -s $(SOC_NAME)_devices.h $@
 +
-+#define dmaconfig_srcadr(x)   ((x)->cur_sg.dma_address)
-+#define dmaconfig_destadr(x)  ((x)->cur_sg.length)
++# machprepare kjhsdk dfsdf
++machprepare: $(TOPDIR)/.platform $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/$(SOC_HEADER)
 +
-+/*
-+ * Constants used for DMA channel priority processing
-+ */
-+#define QUEUE_ID 0x80
-+#define POLICY_CHECK_END 0xff
-+const u8 policy_mem2mem[10] ={15,14,13,12,
-+                      QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
-+                      POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_undefined[34] ={11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,
-+                      QUEUE_ID+11,QUEUE_ID+10,QUEUE_ID+9,QUEUE_ID+8,
-+                      QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
-+                      QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
-+                      QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
-+                      POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_high[34] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
-+                      QUEUE_ID+0,QUEUE_ID+1,QUEUE_ID+2,QUEUE_ID+3,
-+                      QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
-+                      QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
-+                      QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
-+                      POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_normal[34] ={4,5,6,7,8,9,10,11,3,2,1,0,12,13,14,15,
-+                      QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
-+                      QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
-+                      QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
-+                      QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
-+                      POLICY_CHECK_END, POLICY_CHECK_END};
-+const u8 policy_low[34] ={8,9,10,11,7,6,5,4,3,2,1,0,12,13,14,15,
-+                      QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
-+                      QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
-+                      QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
-+                      QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
-+                      POLICY_CHECK_END, POLICY_CHECK_END};
++# machprepare kjhsdk j
++machclean:
++      $(Q)rm -rf *mod.o *.mod.c *.o *.ko
 +
++machmrproper:
++      $(Q)rm -rf $(TOPDIR)/$(SOC_HEADER) $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/arch/arm/mach-nomadik/Kconfig $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/.platform
 +
-+static char dmach_name[MAX_DMA_CHANNELS * MAX_DMA_CHNAME_SIZE];
-+static struct dma_soc_data *socdat;
-+static struct dmach_lli *p_lli_pipe[MAX_DMA_HWCHANNELS];
-+struct dmach_lli *lli_ptr_log = NULL;
-+struct dmach_lli *lli_ptr_phy = NULL;
-+#define nomadik_dma_lli_phy_to_logical(x)     ((struct dmach_lli *)((u32)(x + (lli_ptr_log - lli_ptr_phy)) & ~0x01)) 
++#This will resolve any machin specific dependency for configuration
++#This will generate Kconfig file if not present
++machconfig:
++ifneq ($(wildcard $(TOPDIR)/arch/arm/mach-nomadik/Kconfig), $(TOPDIR)/arch/arm/mach-nomadik/Kconfig)
++      @echo "Generating $(TOPDIR)/arch/arm/mach-nomadik/Kconfig"
++      @./create_kconfig.pl $(TOPDIR)/arch/arm/mach-nomadik
++endif
 +
-+#define nomadik_dmach_is_active_n_enabled(x) (x & 0x00020001)
-+#define nomadik_dma_is_pipe_busy(pipe)                (p_lli_pipe[pipe])
-+#define nomadik_dma_mark_pipe_busy(pipe)      (p_lli_pipe[pipe] = (void *)0xffffffff)
++# end of Auto board configuration/dependency resolution
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot
+@@ -0,0 +1,4 @@
++   zreladdr-y := 0x00008000
++params_phys-y := 0x00000100
++initrd_phys-y := 0x00800000
 +
-+/**
-+ * nomadik_dma_channel_of_pipe - To get dma channel irq for provided pipe address
-+ * @pipeadr: pipe address w.r.to which channel irq needs for foundout
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/clock.c
+@@ -0,0 +1,127 @@
++/*
++ *  linux/arch/arm/mach-nomadik/clock.c
 + *
-+ * finds the pipe number assoicated with channel
-+ * if any transfer is already scheduled on a pipe, returns the channel irq of scheduled DMA 
-+ * if pipe is free, returns null
-+ */
-+static int nomadik_dma_channel_of_pipe(struct dmach_register *pipeadr)
-+{
-+      u32 pipe;
-+      struct dma_struct * dma;
-+      
-+      pipe= (((u32)pipeadr & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
-+      if ((u32 *)pipeadr > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
-+      if (p_lli_pipe[pipe]) {
-+              if (p_lli_pipe[pipe]->mem2.dma) {
-+                      dma = p_lli_pipe[pipe]->mem2.dma;
-+                      return dma->dma_irq;
-+              } else return 0;
-+      }
-+      return 0;
-+}
-+
-+/**
-+ * nomadik_dma_allocate_llis - Allocates requested number of LLIs
-+ * @count: No of LLI buffers requested
++ *  Copyright (C) 2004 ARM Limited.
++ *  Written by Deep Blue Solutions Limited.
 + *
-+ * reserves the requested number of llis from internal lli poolf
-+ * link them with DMAble LLI addresses so that can be used directly by DMA h/w
-+ * return the point of first lli
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
 + */
-+static struct dmach_lli *nomadik_dma_allocate_llis(u32 count)
-+{
-+      struct dmach_lli *p_lli = lli_ptr_log;
-+      struct dmach_lli *p_lli_phy = lli_ptr_phy;
-+      struct dmach_lli *p_lli_phylast = (struct dmach_lli *)0x01;
-+      unsigned long flags;
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/errno.h>
++#include <linux/err.h>
++#include <linux/string.h>
++#include <linux/clk.h>
++#include <linux/mutex.h>
 +
-+      nmdk_dbg_ftrace();
-+      if (!(p_lli) || !(count)) return (struct dmach_lli *)NULL;
-+      if (count > MAX_DMA_LLIS) return (struct dmach_lli *)NULL;
-+      flags = claim_dma_lock();
-+      do {
-+              if (p_lli == (lli_ptr_log + MAX_DMA_LLIS-2)) {
-+                      nmdk_error("unable to find free lli.. rechecking...");
-+                      p_lli = lli_ptr_log;
-+                      p_lli_phy = lli_ptr_phy;
-+              }
-+              p_lli++; p_lli_phy++;
-+              if (!(p_lli->mem3.next)) {
-+                      p_lli->mem3.next = p_lli_phylast;
-+                      count--;
-+                      p_lli_phylast = (struct dmach_lli *)((u32)p_lli_phy + 0x01);
-+              }
-+      } while (count);
-+      release_dma_lock(flags);
-+      return p_lli;   
-+}
++#include <asm/semaphore.h>
++#include <asm/hardware/icst525.h>
++#include "clock.h"
 +
-+/**
-+ * nomadik_dma_deallocate_llis - deallocates/frees the provided lli list
-+ * @p_lli: pointer to the first lli
-+ *
-+ * frees all llis in the provided lli list
-+ */
-+static void nomadik_dma_deallocate_llis(struct dmach_lli *p_lli)
++static LIST_HEAD(clocks);
++static DEFINE_MUTEX(clocks_mutex);
++
++struct clk *clk_get(struct device *dev, const char *id)
 +{
-+      struct dmach_lli *p_lli_bkup;
++      struct clk *p, *clk = ERR_PTR(-ENOENT);
 +
-+      nmdk_dbg_ftrace();
-+      while (p_lli) {
-+              if (!(p_lli)) break;
-+              if (!(p_lli->mem3.next)) break;
-+              if ((u32)p_lli->mem3.next == 0x01) {
-+                      p_lli->mem3.next = (struct dmach_lli *)NULL;
++      mutex_lock(&clocks_mutex);
++      list_for_each_entry(p, &clocks, node) {
++              if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
++                      clk = p;
 +                      break;
 +              }
-+              p_lli_bkup = nomadik_dma_lli_phy_to_logical(p_lli->mem3.next);
-+              p_lli->mem3.next = (struct dmach_lli *)NULL;
-+              p_lli = p_lli_bkup;
 +      }
++      mutex_unlock(&clocks_mutex);
++
++      return clk;
 +}
 +
-+/**
-+ * nomadik_dma_schedule_xfer_on_pipe - Schedules DMA transfer lli on a pipe
-+ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
-+ * @p_lli: pointer to the lli to be scheduled
-+ *
-+ * finds out the pipe no associated with a pipe
-+ * checkes whether pipe is free or busy
-+ * if free then
-+ *    Configures the pipe with LLI data
-+ *    clears any pending interrupt on a pipe
-+ *    marks pipe as busy
-+ *    Enables DMA to strat transfer
-+ * if pipe is busy then 
-+ *    queues the lli on the pipe
-+ */
-+static void nomadik_dma_schedule_xfer_on_pipe(volatile struct dmach_register *p_pipe, struct dmach_lli *p_lli)
++EXPORT_SYMBOL(clk_get);
++
++void clk_put(struct clk *clk)
 +{
-+      u32 pipe, i;
-+      struct dmach_lli *p_lli_hw, *p_lli_curr;
-+      volatile struct dma_register *p_dma_reg;
++      module_put(clk->owner);
++}
 +
-+      nmdk_dbg_ftrace();
-+      i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
-+      pipe = i*2;
-+      if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
-+      
-+      p_lli->mem1.p_lli_qh = (struct dmach_lli *)NULL; /*Marked this lli as last in queue*/
-+      p_lli_curr = p_lli_pipe[pipe];
-+      mb();
-+      if ((p_lli_curr != (void*)0xffffffff) && (p_lli_curr != NULL) ) {
-+              while (p_lli_curr->mem1.p_lli_qh) {
-+                      nmdk_dbg2("currlli(%p) next_lli (%p)", p_lli_curr, p_lli_curr->mem1.p_lli_qh);
-+                      p_lli_curr = p_lli_curr->mem1.p_lli_qh; /*go thr lli headers to point last lli head */
-+              }
-+              p_lli_curr->mem1.p_lli_qh = p_lli;
-+              nmdk_dbg2("lli(%p) is queued on PIPE %d at %p", p_lli, pipe, p_lli_curr);
-+      } else {
-+              /* clear any pending interrupt on this pipe if any */
-+              p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
-+              p_dma_reg->tcicr |= 1UL<<i;
-+              p_dma_reg->eicr |= 1UL<<i;
-+              nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
++EXPORT_SYMBOL(clk_put);
 +
-+              /* program pipe for a transfer*/
-+              p_lli_pipe[pipe] = p_lli;
-+              p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
-+              p_pipe->sadr = p_lli_hw->mem1.sadr;
-+              p_pipe->dadr = p_lli_hw->mem2.dadr;
-+              p_pipe->lli = p_lli_hw->mem3.next;
-+              p_pipe->cr = p_lli_hw->mem4.cr;
-+              nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
-+                      (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
-+              mb();
-+              p_pipe->cfg = p_lli->mem4.cfg;
-+      }
++int clk_enable(struct clk *clk)
++{
++      return 0;
 +}
 +
-+/**
-+ * nomadik_dma_free_procesed_pipe - Frees processed LLI on a pipe
-+ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
-+ *
-+ * finds out the pipe no associated with a pipe
-+ * checkes whether pipe is free or busy, if free then just returns
-+ * frees the allocated llis for a pipe
-+ * checks whether any transfer is queued on a pipe
-+ * if the queue is not empty then
-+ *    Configures queues lli as current lli
-+ *    Configures the pipe with LLI data
-+ *    clears any pending interrupt on a pipe
-+ *    marks pipe as busy
-+ *    Enables DMA to strat transfer
-+ * if the queue is empty then 
-+ *    marks the pipe as free if not reserved by requesting DMA Channel
-+ *    otherwise marks the pipe as free  
-+ */
-+static void nomadik_dma_free_procesed_pipe(volatile struct dmach_register *p_pipe)
++EXPORT_SYMBOL(clk_enable);
++
++void clk_disable(struct clk *clk)
 +{
-+      u32 pipe;
-+      struct dmach_lli *p_lli;
-+      dma_t *dma;
-+      struct dmach_lli *p_lli_hw;
-+      volatile struct dma_register *p_dma_reg;
-+      u32 i;
++}
 +
-+      nmdk_dbg_ftrace();
-+      i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
-+      pipe = i*2;
-+      if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
++EXPORT_SYMBOL(clk_disable);
 +
-+      /* free lli of processed pipe*/
-+      if ((p_lli_pipe[pipe] != (void *)0xffffffff) && (p_lli_pipe[pipe] != NULL) ) {
-+              dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
-+              p_lli = p_lli_pipe[pipe]->mem1.p_lli_qh;
-+              nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
-+              mb();
-+              if (p_lli) {
-+                      /* clear any pending interrupt on this pipe if any */
-+                      p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
-+                      /*p_dma_reg->tcicr |= 1UL<<i;*/
-+                      p_dma_reg->eicr |= 1UL<<i;
-+                      nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
-+                      
-+                      /* program pipe for a transfer*/
-+                      p_lli_pipe[pipe] = p_lli;
-+                      p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
-+                      p_pipe->sadr = p_lli_hw->mem1.sadr;
-+                      p_pipe->dadr = p_lli_hw->mem2.dadr;
-+                      p_pipe->lli = p_lli_hw->mem3.next;
-+                      p_pipe->cr = p_lli_hw->mem4.cr;
-+                      nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
-+                              (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
-+                      mb();
-+                      p_pipe->cfg = p_lli->mem4.cfg;
++unsigned long clk_get_rate(struct clk *clk)
++{
++      return clk->rate;
++}
 +
-+                      nmdk_dbg2("Scheduling queued transfer on pipe %d (lli(%p))", pipe,
-+                              p_lli_pipe[pipe]);
-+              } else {
-+                      if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
-+                              p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
-+                      else { 
-+                              p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
-+                              dmaconfig_pipeadr(dma) = (u32)0;
-+                      }
-+              }
-+      }
++EXPORT_SYMBOL(clk_get_rate);
++
++long clk_round_rate(struct clk *clk, unsigned long rate)
++{
++      return 0;
 +}
 +
-+/* removes all allocated requests on the pipe */
-+/**
-+ * nomadik_dma_flush_pipe - Removes all scheduled and queued transfers on a pipe
-+ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
-+ *
-+ * finds out the pipe no associated with a pipe
-+ * stops current transfer
-+ * traverse through lli heads and flush all queued llis including scheduled one
-+ * marks the pipe as free 
++EXPORT_SYMBOL(clk_round_rate);
++
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++      clk->rate = rate;
++      return 0;
++}
++
++EXPORT_SYMBOL(clk_set_rate);
++
++/*
++ * These are fixed clocks.
 + */
-+static void nomadik_dma_flush_pipe(volatile struct dmach_register *p_pipe)
++
++static struct clk uart_clk = {
++      .name = "UARTCLK",
++      .rate = 48000000,
++};
++
++static struct clk clcd_clk = {
++      .name = "CLCDCLK",
++      .rate = 48000000,
++};
++
++int clk_register(struct clk *clk)
 +{
-+      u32 pipe;
-+      struct dmach_lli *p_lli_qh = (struct dmach_lli *)NULL;
-+      dma_t *dma;
++      mutex_lock(&clocks_mutex);
++      list_add(&clk->node, &clocks);
++      mutex_unlock(&clocks_mutex);
++      return 0;
++}
 +
-+      nmdk_dbg_ftrace();
-+      pipe= (((u32)p_pipe & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
-+      if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
++EXPORT_SYMBOL(clk_register);
 +
-+      if ((u32)p_lli_pipe[pipe] == 0xffffffff) goto nextt;
-+      while (p_lli_pipe[pipe] != 0) {
-+              dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
-+              p_lli_qh = p_lli_pipe[pipe]->mem1.p_lli_qh;
-+              nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
-+              p_lli_pipe[pipe] = p_lli_qh;
-+              nmdk_dbg2("Flushed lli (%p) for pipe %d", p_lli_pipe[pipe], pipe);
-+      };
-+      nextt:
-+//    if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
-+//            p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
-+//    else 
-+              p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
++void clk_unregister(struct clk *clk)
++{
++      mutex_lock(&clocks_mutex);
++      list_del(&clk->node);
++      mutex_unlock(&clocks_mutex);
 +}
 +
-+/**
-+ * nomadik_dma_check_update_userconfig - updates config as per user configs
-+ * @dma: DMA channel structure pointer 
-+ *
-+ * checks the user configuration 
-+ * if some use configuration is provided by clinet driver during 
-+ * configuration then abstracts it and updates Channel configuration
-+ * data accordingly
-+ */
-+static void nomadik_dma_check_update_userconfig(dma_t *dma)
++EXPORT_SYMBOL(clk_unregister);
++
++static int __init clk_init(void)
 +{
-+      nmdk_dbg_ftrace();
-+      if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_BSIZE_CONFIGURED) {
-+              dmaconfig_config(dma) &= ~(DMA_BSIZE_256);
-+              dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_BSIZE_256);
-+      }
-+      if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_BSIZE_CONFIGURED) {
-+              dmaconfig_config(dma) &= ~(DMA_BSIZE_256<<3);
-+              dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_BSIZE_256<<3);
-+      }
-+      if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_WIDTH_CONFIGURED) {
-+              dmaconfig_config(dma) &= ~(DMA_WIDTH_NA);
-+              dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_WIDTH_NA);
-+      }
-+      if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_WIDTH_CONFIGURED) {
-+              dmaconfig_config(dma) &= ~(DMA_WIDTH_NA<<3);
-+              dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_WIDTH_NA<<3);
-+      }
-+      nmdk_dbg("usrconfig =%08x, config = %08x", (u32)dmaconfig_usrconfig(dma), (u32)dmaconfig_config(dma));
++      clk_register(&uart_clk);
++      clk_register(&clcd_clk);
++      return 0;
 +}
 +
-+/**
-+ * nomadik_dma_usrdevconfig - updates user configuration as per type
-+ * @config: user configuration information 
-+ * @type: src or destincation peripharal indicator (0= means src) 
++arch_initcall(clk_init);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/clock.h
+@@ -0,0 +1,25 @@
++/*
++ *  linux/arch/arm/mach-nomadik/clock.h
 + *
-+ * checks provided configuration and returns configuration converting
-+ * it for soruce or destination peripharal. this API is provided to
-+ * facilitate and mistake proffing the configuration by client driver
++ *  Copyright (C) 2004 ARM Limited.
++ *  Written by Deep Blue Solutions Limited.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
 + */
-+u32 __nomadik_dma_usrdevconfig(u32 config, int type)
-+{
-+      u32 val =0;
-+      if (type == 0) { /*src*/
-+              if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
-+                      val |= DMA_SRC_BSIZE_CONFIGURED;
-+                      val |= (config & DMA_BSIZE_256);
-+              }
-+              if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
-+                      val |= DMA_SRC_WIDTH_CONFIGURED;
-+                      val |= (config & DMA_WIDTH_NA);
-+              }
-+      } else { /*dest*/
-+              if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
-+                      val |= DMA_DEST_BSIZE_CONFIGURED;
-+                      val |= (config & DMA_BSIZE_256)<<3;
-+              }
-+              if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
-+                      val |= DMA_DEST_WIDTH_CONFIGURED;
-+                      val |= (config & DMA_WIDTH_NA)<<3;
-+              }
-+      }
-+      return (val);
-+}
-+EXPORT_SYMBOL(__nomadik_dma_usrdevconfig);
++struct module;
++struct icst525_params;
 +
-+/**
-+ * nomadik_dmach_configure - configures DMA Channel processing default and user configuration
-+ * @srcdmadev: name of srouce DMAble device IP  
-+ * @destdmadev: name of dest DMAble device IP  
-+ * @dma: DMA channel data structure pointer 
++struct clk {
++      struct list_head        node;
++      unsigned long           rate;
++      struct module           *owner;
++      const char              *name;
++      const struct icst525_params *params;
++      void                    *data;
++      void                    (*setvco)(struct clk *, struct icst525_vco vco);
++};
++
++int clk_register(struct clk *clk);
++void clk_unregister(struct clk *clk);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/cpu.c
+@@ -0,0 +1,293 @@
++/*
++ *  linux/arch/arm/mach-nomadik/cpu.c
 + *
-+ * finds out the defult configuration for src and dest devices scanning the config_tbl
-+ * prepares DMA configuration from default config of src and dest dmadevices and user
-+ * configuration
-+ * return 0 on cusess, negative value on failure
++ *  Copyright (C) STMicroelectronics
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * CPU freq driver
 + */
-+static int nomadik_dmach_configure(char *src_dmadev, char *dest_dmadev, dma_t *dma)
-+{
-+      int i;
-+      uint8 flag =0;
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/cpufreq.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/init.h>
 +
-+      nmdk_dbg_ftrace();
-+      dmaconfig_config(dma) = 0;
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/mach-types.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/power.h>
 +
-+      for (i=0; i < socdat->config_tbl_size; i++) {
-+              if (!(strcmp (src_dmadev, (socdat->config_tbl[i].id)))) {
-+                      dmaconfig_config(dma) |= (u32) (socdat->config_tbl[i].config &
-+                              (DMA_AHB_M1 | DMA_DEV_BOTH_DMACS_CANBE_USED | DMA_ADR_INC |
-+                               DMA_WIDTH_NA | DMA_BSIZE_256 |
-+                               DMA_REQUEST_LINE(31)));
-+                      flag |=0x01;
-+              }
-+              if (!(strcmp(dest_dmadev,(socdat->config_tbl[i].id)))) {
-+                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config
-+                                                       & DMA_DEV_BOTH_DMACS_CANBE_USED)<<2));
-+                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_AHB_M1)<<1));
-+                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_ADR_INC)<<1)); /*DI bit*/
-+                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_WIDTH_NA)<<3));
-+                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_BSIZE_256)<<3));
-+                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_REQUEST_LINE(31))<<5));
-+                      flag |=0x02;
-+              }
-+              if ((flag & 0x03) == 0x03) {
-+                      nomadik_dma_check_update_userconfig(dma);
-+                      nmdk_dbg("conf(%08x), mode=%08x", dmaconfig_config(dma), dmaconfig_mode(dma));
-+                      return(0);
-+              }
-+      }
-+      nmdk_error("unable to configure dmachanel");
-+      return(-1);
-+}
++#include <asm/arch/debug.h>
 +
-+/**
-+ * nomadik_dma_find_dmahwpipe - Finds and returns free and compatible DMA pipe
-+ * @dma: DMA channel data structure pointer 
-+ *
-+ * searches a free pipe as per channel priority policy manager
-+ * (refer ./Documentation//arm/STM-Nomadik/dma_user_guide.txt)
-+ * checks the configuration for the pipe suitability for transfer
-+ * selects the pipe and mark it as busy
-+ * returns pipe address if selected
-+ * returns NULL in case of unavailability of pipe
++#define CPUFREQ_NAME             "CPUFREQ"
++
++#ifndef CPUFREQ_DEBUG
++#define CPUFREQ_DEBUG 0
++#endif
++
++#define NMDK_DEBUG      CPUFREQ_DEBUG /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  CPUFREQ_NAME  /* msg header represents this module */
++#define NMDK_DBG        KERN_ERR      /* message level */
++
++
++#define PLL1_CRYSTAL_FREQ_KHZ (192 * 100)
++#define CALC_FREQ(pll1_nmul, pll1_pdiv)   (PLL1_CRYSTAL_FREQ_KHZ * (pll1_nmul + 2)) / (1 << pll1_pdiv);
++
++static struct cpufreq_driver nomadik_driver;
++static unsigned int nomadik_get(unsigned int cpu);
++
++extern unsigned int nomadik_freq_to_idx(unsigned int freq);
++extern unsigned int nomadik_idx_to_freq(unsigned int idx);
++extern u32 nomadik_setsys_freq(u32 freq_idx);
++
++/*
++ * Validate the speed policy.
 + */
-+static struct dmach_register *nomadik_dma_find_dmahwpipe(dma_t *dma)
++static int nomadik_verify_policy(struct cpufreq_policy *policy)
 +{
-+      int i;
-+      u8 *p_pipe;
-+      volatile struct dmach_register *p_dmach_reg;
-+      volatile struct dma_register *p_dma_reg;
-+      unsigned long flags;
 +
 +      nmdk_dbg_ftrace();
++      cpufreq_verify_within_limits(policy,
++                                   policy->cpuinfo.min_freq,
++                                   policy->cpuinfo.max_freq);
 +
-+      flags = claim_dma_lock();
-+      /* channel priority setup */
-+      if ( MEM_TO_MEM == (u32)dmaconfig_mode(dma)) {
-+              p_pipe = (void *)policy_mem2mem;
-+      }
-+      else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_HIGH) {
-+              p_pipe = (void *)policy_high;
-+      }
-+      else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_NORMAL) {
-+              p_pipe = (void *)policy_normal;
-+      }
-+      else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_LOW) {
-+              p_pipe = (void *)policy_low;
-+      }
-+      else { /* DMA_EXCH_PRIORITY_UNDEFINED) */
-+              p_pipe = (void *)policy_undefined;
-+      }
-+      do {
-+              i = *p_pipe & ~QUEUE_ID;
-+              /** Advanced Pipe selection strategy, under development */
-+              /* skip if pipe is busy and not requested on queued pipe */
-+              if (nomadik_dma_is_pipe_busy(i) && (!(*p_pipe & QUEUE_ID))) continue;
-+              /* skip if pipe is busy with infinite dma xfer */
-+              if (nomadik_dma_is_pipe_busy(i) &&
-+                   ((dmaconfig_config((dma_t *)p_lli_pipe[i]->mem2.dma)) & DMA_INFINITE_XFER)) continue;
-+              if (i & 0x01) {
-+                      if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)))
-+                               != (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)) ) continue;
-+                      p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA1].chip_data;
-+              } else {
-+                      if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)))
-+                               != (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)) ) continue;
-+                      p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA0].chip_data;
-+              }
-+              p_dmach_reg = (struct dmach_register *)&p_dma_reg->dmach[i/2];
-+              nomadik_dma_mark_pipe_busy(*p_pipe & ~QUEUE_ID);
-+              nmdk_dbg("DMAHW PIPE%d assigned for Dma Channel %d",i, DMACH_FOR_IRQNO(dma->dma_irq));
-+              release_dma_lock(flags);
-+              return (void *)p_dmach_reg;
-+      } while ((*(++p_pipe)) != POLICY_CHECK_END); 
-+      release_dma_lock(flags);
-+      nmdk_error("All HW DMA Chanels busy...");
-+      return NULL;
++      policy->min = NOMADIK_CPUFREQ_MIN;
++      policy->max = NOMADIK_CPUFREQ_MAX;
++
++      cpufreq_verify_within_limits(policy,
++                                   policy->cpuinfo.min_freq,
++                                   policy->cpuinfo.max_freq);
++
++      return 0;
 +}
 +
-+/**
-+ * nomadik_dma_req - low level method for request_dma API
-+ * @channel: DMA channel number 
-+ * @dma: DMA channel data structure pointer 
-+ *
-+ * Check for configuration is passed by client
-+ * prepares basic channel configuration from dma info provided by client
-+ * generate dmach id string from src and dest dmadevtypes 
-+ * find and reserved a pipe in case of reserved mode requested by client
-+ * returns NULL in case of sucess, negative value in case for failure
-+ */
-+static int nomadik_dma_req(dmach_t channel, dma_t *dma)
++static int nomadik_set_target(struct cpufreq_policy *policy,
++                            unsigned int target_freq, unsigned int relation)
 +{
-+      struct nmdk_dma_info *dma_info = 
-+              (struct nmdk_dma_info *)dma->device_id;
-+      int error;
++      cpumask_t cpus_allowed;
++      int cpu = policy->cpu;
++      struct cpufreq_freqs freqs;
++      unsigned int freq_idx;
++      unsigned int new_voltage, cur_voltage;
++      unsigned char vcore_data;
++      int result;
 +
-+      nmdk_dbg_ftrace();
++      nmdk_dbg2("%s called with target_freq = %d relation = %d\n",
++                (__FUNCTION__), target_freq, relation);
++      /*
++       * Save this threads cpus_allowed mask.
++       */
++      cpus_allowed = current->cpus_allowed;
 +
-+      if (! dma->device_id) {
-+              nmdk_error("nmdk_dma_info structptr not passed");
-+              return (-DMA_CONFIG_INFO_NOT_PASSED);
++      /*
++       * Bind to the specified CPU.  When this call returns,
++       * we should be running on the right CPU.
++       */
++      set_cpus_allowed(current, cpumask_of_cpu(cpu));
++      BUG_ON(cpu != smp_processor_id());
++
++      freqs.old = nomadik_get(policy->cpu);
++
++      freq_idx = nomadik_freq_to_idx(target_freq);
++
++      switch (relation) {
++      case CPUFREQ_RELATION_L:
++              if (nomadik_idx_to_freq(freq_idx) > policy->max)
++                      freq_idx--;
++              break;
++      case CPUFREQ_RELATION_H:
++              if ((nomadik_idx_to_freq(freq_idx) > target_freq) &&
++                  (nomadik_idx_to_freq(freq_idx - 1) >= policy->min))
++                      freq_idx--;
++              break;
 +      }
 +
-+      dmaconfig_mode(dma) = (u32)dma_info->mode;
-+      dmaconfig_usrconfig(dma) = (u32)dma_info->config;
++      freqs.new = nomadik_idx_to_freq(freq_idx);
++      freqs.cpu = policy->cpu;
 +
-+      /* Prepare dmach configuration form dma_info*/
-+      switch((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
-+              case MEM_TO_MEM:
-+                      dma_info->srcdevtype = "mem";
-+                      dma_info->destdevtype = "mem";
-+                      break;
-+              case FLOW_CNTRL_PERIPH(MEM_TO_PERIPH):
-+              case MEM_TO_PERIPH:
-+                      dma_info->srcdevtype = "mem";
-+                      break;
-+              case FLOW_CNTRL_PERIPH(PERIPH_TO_MEM):
-+              case PERIPH_TO_MEM:
-+                      dma_info->destdevtype = "mem";
-+                      break;
-+              case FLOW_CNTRL_SRC_PERIPH(PERIPH_TO_PERIPH):
-+              case FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH):
-+              case PERIPH_TO_PERIPH:
-+                      break;
-+              default:
-+                      nmdk_error("Invalid DMA mode");
-+                      error =-1;
-+                      goto err_exit;
++      nmdk_dbg2(" freqs.new  = %d\n", freqs.new);
++      if (freqs.old == freqs.new) {
++              set_cpus_allowed(current, cpus_allowed);
++              return 0;
 +      }
-+      
-+      if (! dma_info->srcdevtype) {
-+              nmdk_error("srcdevtype not specified");
-+              error =-DMA_SRC_DEVICE_NOT_CONFIGURED;
-+              goto err_exit;
++
++#if 0
++      if ( freq_idx == 0)
++      {
++              nomadik_normal_to_slow = 1;
++              nomadik_slow_to_normal = 0;
 +      }
-+      if (! dma_info->destdevtype) {
-+              nmdk_error("destdevtype not specified");
-+              error =-DMA_DEST_DEVICE_NOT_CONFIGURED;
-+              goto err_exit;
++      if (freqs.old == 19200 )
++      {
++              nomadik_slow_to_normal = 1;
++              nomadik_normal_to_slow = 0;
++
 +      }
-+      error = nomadik_dmach_configure(dma_info->srcdevtype, dma_info->destdevtype, dma);
-+      if (error) goto err_exit;
-+      
-+      /* generate dmach id string from src and dest dmadevtypes */
-+      sprintf(dmach_name + (channel * MAX_DMA_CHNAME_SIZE ),
-+              "dmaclbk-%s->%s", dma_info->srcdevtype, dma_info->destdevtype);
-+      dma->device_id = dmach_name + (channel * MAX_DMA_CHNAME_SIZE) + 8;
++#endif
 +
-+      if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) {
-+              dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
-+              if ((u32)dmaconfig_pipeadr(dma)) {
-+                      nmdk_dbg("pipe (%p) reserved for channel %d",
-+                      (void *)dmaconfig_pipeadr(dma), channel);
-+              } else {
-+                      nmdk_error("could not reserve dmach hw pipe");
-+                      error =-1;
-+                      goto err_exit;
-+              }
-+      } else  dmaconfig_pipeadr(dma) = (u32)NULL;
-+      dma->state = NMDK_DMA_CONFIGURED;
-+      return(0);
++      cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 +
-+  err_exit:
-+      return(error);
-+}
++      new_voltage = nomadik_freq_to_voltage(freqs.new);
++      cur_voltage = g_nomadik_voltage;
++      nmdk_dbg2(" new  voltage = %d\n", new_voltage);
++      nmdk_dbg2(" old  voltage = %d\n", cur_voltage);
 +
-+/**
-+ * nomadik_dma_en - low level method for enable_dma API
-+ * @channel: DMA channel number 
-+ * @dma: DMA channel data structure pointer 
-+ *
-+ * Checks for channel configured properly
-+ * allocates llis for transfer
-+ * programm llis for transfer data
-+ * checks if the pipe is already available with channel
-+ * if not the find and allocates a free pipe for a transfer
-+ * program dmach irqname if not set by client
-+ * schedules a transfer on a pipe
-+ */
-+static void nomadik_dma_en(dmach_t channel, dma_t *dma)
-+{
-+      struct dmach_lli *p_lli_start = (struct dmach_lli *)NULL;
-+      struct dmach_lli *p_lli_curr;
-+      struct dmach_lli *p_lli_next;
++      if (new_voltage > cur_voltage) {
 +
-+      unsigned long flags;
-+      u32 dmacnt, dmacnt_chkval, tmpcnt;
++              vcore_data = new_voltage;
 +
-+      nmdk_dbg_ftrace();
++              result =
++                  nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
++                                             0x1E, 1);
++              if (unlikely(result)) {
++                      nmdk_error("i2c write error with ret = %d\n", result);
++                      goto err1;
 +
-+/*    if (dma->invalid) {
-+              if (dma->mode) {
-+                      if (((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH) ==
-+                          (dma->mode & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
-+                              dmaconfig_mode(dma) = (u32)dma->mode; 
-+                      }
-+              }
-+      } else {
-+        exit_invl_parms:
-+              nmdk_error("enable request without parameters");
-+              goto exit_en
-+      }
-+      if (dma->addr) dmaconfig_srcadr(x) = dma->addr;
-+      if (dma->speed) dmaconfig_destadr(x) = (u32)dma->speed;
-+*/
++              } else
++                      nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
 +
-+      if (!(dma->sg)) {
-+              if (!(dma->addr)) {
-+                      nmdk_error("srcadr not set");
-+                      goto exit_en;
-+              }
-+              if (!(dma->speed)) {
-+                      nmdk_error("destadr not set");
-+                      goto exit_en;
-+              }
-+      }
++#ifdef CPUFREQ_DEBUG
++              vcore_data = 0;
 +
-+      /*set transfer size = count/src_width */
-+      dmacnt = dma->count/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
-+      nmdk_dbg("total count = %d, dma count =%d",(u32)dma->count, dmacnt);
-+      tmpcnt = 0;
-+      dmacnt_chkval = 0x0ff0;
++              result =
++                  nomadik_i2c_read_register(I2C_TOUAREG_CLIENT, &vcore_data,
++                                             0x1E, 1);
++              if (unlikely(result)) {
++                      nmdk_error("i2c read error with ret = %d\n", result);
++                      goto err1;
 +
-+      if (dma->sg) {
-+              /*Scatter gather list implimentation */
-+              if (dma->sgcount == 0) {
-+                      nmdk_error("Empty scatter gather list");
-+                      goto exit_en;
-+              }
-+              if ((((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_MEM ) ||
-+                       (((u32)dmaconfig_mode(dma) & 0x03) == PERIPH_TO_PERIPH )) {
-+                      nmdk_error("Unsupported mode for scatter gather");
-+                      goto exit_en;
-+              }
-+              p_lli_start = nomadik_dma_allocate_llis(dma->sgcount +1);
-+              p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
-+#ifdef SCATERGATHER_MMC_DEBUG
-+              if (dma->sgcount > 1) {
-+                      dmaconfig_config(dma) |= 0x0f0007fe;
-+                      nmdk_dbg("sc_count=%d , config=%08x", dma->sgcount, dmaconfig_config(dma));
-+                      if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
-+                              printk("===%p", dma_alloc_coherent( NULL , 4096, &dma->speed, GFP_DMA | GFP_KERNEL ));
++              } else
++                      nmdk_dbg2("i2c read vcore_data = 0x%x\n", vcore_data);
 +
-+                      } else {
-+                              printk("==%p",dma_alloc_coherent( NULL , 4096, &dma->addr, GFP_DMA | GFP_KERNEL ));
-+                      }
-+                      dmaconfig_mode(dma) = 0;
++              if ( vcore_data != new_voltage )
++              {
++                      printk("i2c had not written correctly\n");
++                      goto err1;
 +              }
 +#endif
-+              tmpcnt = dma->count;
-+              while (dma->sgcount) {
-+                      nmdk_dbg("tmpcnt %d, sg_len %d", tmpcnt, dma->sg->length);
-+                      p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
-+                      if (!(dma->sg->dma_address)) {
-+                              nmdk_error("sg list not dma mapped");
-+                              goto exit_en;
-+                      }
-+                      if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
-+                              p_lli_curr->mem1.sadr = dma->sg->dma_address;
-+                              if (!(dma->speed)) {
-+                                      nmdk_error("destadr not set");
-+                                      goto exit_en;
-+                              }
-+                              p_lli_curr->mem2.dadr = (dma_addr_t)dma->speed;
-+                      } else {
-+                              if (!(dma->addr)) {
-+                                      nmdk_error("srcadr not set");
-+                                      goto exit_en;
-+                              }
-+                              p_lli_curr->mem1.sadr = (dma_addr_t)dma->addr;
-+                              p_lli_curr->mem2.dadr = dma->sg->dma_address;
-+                      }
-+                      if (tmpcnt > dma->sg->length) {
-+                              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+                                        (dma->sg->length/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
-+                      } else {
-+                              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+                                        (tmpcnt/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
-+                      }
-+                      tmpcnt -= dma->sg->length;
-+                      dma->sgcount--; dma->sg++;
-+                      if (dma->sgcount == 0) p_lli_curr->mem4.cr |= (1<<31);
-+                      p_lli_curr = p_lli_next;
-+              }
-+      } else if ((u32)dmaconfig_mode(dma) & DMA_DOUBLE_BUFFERED ) {
-+              p_lli_start = nomadik_dma_allocate_llis(3);
-+              p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
-+              p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
++              g_nomadik_voltage = new_voltage;
++      }
 +
-+              dmacnt /= 2;
-+              dmacnt_chkval = dmacnt;
-+              /*fill next lli structure */
-+              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | dmacnt_chkval);
-+              p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
-+              p_lli_curr->mem2.dadr = dma->speed;
-+              p_lli_next->mem4.cr = p_lli_curr->mem4.cr;
-+              p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
-+              p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
-+              if (p_lli_next->mem4.cr & DMA_ADR_INC) p_lli_next->mem1.sadr += dma->count/2;
-+              if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1)) p_lli_next->mem2.dadr += dma->count/2;
++      nomadik_setsys_freq(freq_idx);
 +
-+              if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
-+                      p_lli_next->mem3.next = p_lli_start->mem3.p_lli_hw;
-+              } else {
-+                      p_lli_next->mem4.cr |= (1<<31); 
-+              }
-+      } /*mode & DMA_DOUBLE_BUFFERED*/
-+      else {
-+              tmpcnt = dmacnt/dmacnt_chkval;
-+              p_lli_start = nomadik_dma_allocate_llis(tmpcnt + 2);
-+              p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
-+              p_lli_next = p_lli_curr;
++      if (new_voltage < cur_voltage) {
++
++              vcore_data = new_voltage;
++              result =
++                  nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &vcore_data,
++                                             0x1E, 1);
++      /**
++       * Here even if we are not able to set lower voltage. Still system can
++       * work with previous voltage
++       */
++
++              if (unlikely(result)) {
++                      nmdk_error("i2c write error with ret = %d\n", result);
++                      goto err1;
++
++              } else
++                      nmdk_dbg2("i2c write vcore_data = 0x%x\n", vcore_data);
++              g_nomadik_voltage = new_voltage;
 +
-+              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+                               ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
-+              dmacnt -= dmacnt_chkval;
-+              p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
-+              p_lli_curr->mem2.dadr = dma->speed;
-+              while(tmpcnt) {
-+                      p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
-+                      /*fill next lli structure */
-+                      p_lli_next->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
-+                                       ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
-+                      p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
-+                      p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
-+                      if (p_lli_next->mem4.cr & DMA_ADR_INC)
-+                              p_lli_next->mem1.sadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
-+                      if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1))
-+                              p_lli_next->mem2.dadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
-+                      
-+                      p_lli_curr = p_lli_next;
-+                      dmacnt -= dmacnt_chkval;
-+                      tmpcnt--;
-+              }
-+              p_lli_curr->mem4.cr |= (1<<31);
-+              if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
-+                      p_lli_curr->mem3.next = p_lli_start->mem3.p_lli_hw;
-+              } else {
-+                      p_lli_curr->mem4.cr |= (1<<31); 
-+              }
 +      }
-+      nmdk_dbg("lli_start(%p)", p_lli_start);
-+      p_lli_start->mem2.dma = (void *)dma;                                    /*dma associated with this lii*/
-+      p_lli_start->mem4.cfg = (((u32)dmaconfig_config(dma) & 0x000007fe) | /* set src/dest dma periph request line numbers */
-+                         ((u32)dmaconfig_mode(dma)<<11 & (7<<11)) |   /* set flow control and xter type*/
-+                         (0x0000c001));                       /*enable interrupts and start xfer*/
 +
-+      /* if channel is reserved use predefined hwpipe else find free
-+       * h/w pipe to schedule dma
-+       * if h/w pipe is not available the que the request
++      err1:
++
++      /*
++       * Restore the CPUs allowed mask.
 +       */
-+      if (!((u32)dmaconfig_pipeadr(dma))) {
-+              dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
-+              if (dmaconfig_pipeadr(dma)) {
-+                      nmdk_dbg("channel %d allocated pipe p_dmach_reg(%p) ",channel, (void *)dmaconfig_pipeadr(dma));
-+              } else {
-+                      nmdk_error("enable requested aborted...No pipe available...");
-+                      goto exit_en;
-+              }
-+      }
-+      /* program dmach irqname if not set by client */
-+      if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
-+              if (!(socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name))
-+                      socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name =
-+                              (dmach_name + (channel * MAX_DMA_CHNAME_SIZE));
++      set_cpus_allowed(current, cpus_allowed);
 +
-+      mb();
-+      flags = claim_dma_lock();
-+      nomadik_dma_schedule_xfer_on_pipe((void *)dmaconfig_pipeadr(dma), p_lli_start);
-+      release_dma_lock(flags);
-+      dma->state = NMDK_DMA_ENABLED;
-+      if ((u32)dmaconfig_mode(dma) & DMA_QUEUE_ENABLED) dma->active = 0;
-+      return;
++      cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++#if CPUFREQ_DEBUG
++      {
++      int j;
++      for(j=0; j <= 0x124; j+=4)
++              printk("sdmc[%x] = %x\n", j, readl(0xf0110000 + j ));
++      }
++#endif
 +
-+exit_en:
-+      if (p_lli_start) nomadik_dma_deallocate_llis(p_lli_start);      
-+      return;
++      return 0;
 +}
 +
-+/**
-+ * nomadik_dma_dis - low level method for disable_dma API
-+ * @channel: DMA channel number 
-+ * @dma: DMA channel data structure pointer 
-+ *
-+ * disables a transfer on a pipe if associated with a requested channel
-+ */
-+static void nomadik_dma_dis(dmach_t channel, dma_t *dma)
++#define SRC_PLL_FREQ_OFFSET 0x14
++static unsigned int nomadik_get(unsigned int cpu)
 +{
-+      struct dmach_register *p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
-+      unsigned long flags;
++      cpumask_t cpus_allowed;
++      unsigned int current_freq;
++      unsigned char __iomem *src_base;
++      unsigned long pll_reg;
++      unsigned int pll1_nmul, pll1_pdiv;
 +
 +      nmdk_dbg_ftrace();
++      cpus_allowed = current->cpus_allowed;
 +
-+      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
-+      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+      flags = claim_dma_lock();
-+      nmdk_dbg("Channel %d disabled on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+      p_dmach_reg->cfg &= ~0x0000c001;
-+      release_dma_lock(flags);
-+      dma->state = NMDK_DMA_DISABLED;
++      set_cpus_allowed(current, cpumask_of_cpu(cpu));
++      BUG_ON(cpu != smp_processor_id());
++      src_base = (unsigned char *)IO_ADDRESS(NOMADIK_SRC_BASE);
++      if ( ( readl(src_base) & 0x78 )  == 0x20 )
++      {
++              pll_reg = readl(src_base + SRC_PLL_FREQ_OFFSET);
++              pll1_pdiv = pll_reg & 0x7;
++              pll1_nmul = (pll_reg >> 8) & 0x3f;
++              current_freq = CALC_FREQ(pll1_nmul, pll1_pdiv);
++      }
++      else
++              current_freq = NOMADIK_CPUFREQ_MIN;
++
++      set_cpus_allowed(current, cpus_allowed);
++      nmdk_dbg2("Current_freq = %d\n", current_freq);
++      nmdk_dbg2("pll1_nmul = 0x%x pll1_pdiv = 0x%x\n", pll1_nmul, pll1_pdiv);
++
++      g_nomadik_voltage = nomadik_freq_to_voltage(current_freq);
++      nmdk_dbg2("g_nomadik_voltage = %x\n", g_nomadik_voltage);
++      return current_freq;
 +}
 +
-+static void nomadik_dma_fr(dmach_t channel, dma_t *dma)
++static int nomadik_cpufreq_init(struct cpufreq_policy *policy)
 +{
-+      nmdk_dbg_ftrace();
-+      nomadik_dma_dis(channel, dma);
-+      if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
-+              free_irq(IRQNO_FOR_DMACH(channel), socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->dev_id);
-+      if (dmaconfig_pipeadr(dma)) nomadik_dma_flush_pipe((void *)dmaconfig_pipeadr(dma));
++
++      /* set default policy and cpuinfo */
++      policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
++      policy->cpuinfo.max_freq = NOMADIK_CPUFREQ_MAX;
++      policy->cpuinfo.min_freq = NOMADIK_CPUFREQ_MIN;
++      policy->cpuinfo.transition_latency = NOMADIK_CPUFREQ_TRANS_LATENCY;
++      policy->cur = policy->min = policy->max = nomadik_get(policy->cpu);
++      nmdk_dbg2("max cpu freq = %d min cpu freq = %d\n", NOMADIK_CPUFREQ_MAX,
++                NOMADIK_CPUFREQ_MIN);
++
++      return 0;
 +}
 +
-+/* find the available dma chanel and requests the same */
-+/**
-+ * request_available_dma - Wrapper over request_dma API 
-+ * @dmach_config_info: DMA channel number 
-+ * @dma: DMA channel data structure pointer 
-+ *
-+ * Wrapper over request_dma API for free and available DMA channel search
-+ * returns DMA Channel number , negative error value in case of failure
-+ */
-+int request_available_dma(struct nmdk_dma_info * dmach_config_info)
-+{
-+      dmach_t channel;
-+      int error;
++static struct cpufreq_driver nomadik_driver = {
++      .verify = nomadik_verify_policy,
++      .target = nomadik_set_target,
++      .get = nomadik_get,
++      .init = nomadik_cpufreq_init,
++      .name = "nomadik-cpufreq",
++};
 +
-+      /*removed locks as detected by spinlock debugging on*/
-+      for (channel = 0; channel < (MAX_DMA_CHANNELS - 1); channel++) {
-+              error = request_dma(channel, (char *)dmach_config_info);
-+              if (-EBUSY == error) continue;
-+              if (error < 0) {
-+                      nmdk_error("Request DMA error");
-+                      return error;
-+              } else {
-+                      nmdk_dbg("Dma Chanel %d is available and allocated", channel);
-+                      return channel;
-+              }
-+      }
-+      nmdk_error("All DMA Channels occupied....");
-+      return -DMA_ALLCHANELS_OCCUPIED;
++static int __init nomadik_cpu_init(void)
++{
++      return cpufreq_register_driver(&nomadik_driver);
 +}
-+EXPORT_SYMBOL(request_available_dma);
 +
-+/**
-+ * suspend_dma - Pauses DMA transfer for this channel
-+ * @channel: DMA channel number 
-+ *
-+ * This API will pause current dma if it is ongoing
-+ * also this API is used to pause all active on going DMA channels involved
-+ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
-+ */
-+void suspend_dma(dmach_t channel)
++static void __exit nomadik_cpu_exit(void)
 +{
-+      dma_t *dma;
-+      volatile struct dmach_register *p_dmach_reg;
-+      unsigned long flags;
++      cpufreq_unregister_driver(&nomadik_driver);
++}
 +
-+      nmdk_dbg_ftrace();
-+      if (!(socdat->dma_chan)) goto inactive_dma;
-+      dma = socdat->dma_chan;
-+      if (DMA_ALL_MEM_CHANNELS == channel) {
-+              for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
-+                      if (!dma->lock) continue;
-+                      if (NMDK_DMA_SUSPENDED == dma->state) continue;
-+                      if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
-+                              == PERIPH_TO_PERIPH) continue;
-+                      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++MODULE_AUTHOR("Manish Rathi");
++MODULE_DESCRIPTION("cpufreq driver for ARM Nomadik CPUs");
++MODULE_LICENSE("GPL");
 +
-+                      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
-+                      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+                      flags = claim_dma_lock();
-+                      nmdk_dbg("Channel %d Suspended on pipe %p", channel, (void *)dmaconfig_pipeadr(dma));
-+                      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+                              p_dmach_reg->cfg |= NMDK_DMACH_HALT;
-+                      }
-+                      release_dma_lock(flags);
-+                      dma->state = NMDK_DMA_SUSPENDED;
++module_init(nomadik_cpu_init);
++module_exit(nomadik_cpu_exit);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/create_kconfig.pl
+@@ -0,0 +1,55 @@
++#! /usr/bin/perl
++#
++# gen_nomadik_kconfig.pl: Generates Kconfig in arch/arm/mach-nomadik/ considering all board specific Kconfig files.
 +
-+                      dma++;
-+              }
-+              return;
-+      }
-+      if (!(socdat->dma_chan)) goto inactive_dma;
-+      dma += channel;
-+      if (!dma->lock)
-+              goto free_dma;
++$VAR=@ARGV;
++if (@ARGV != 1)
++{
++      print "Usage: ./create_kconfig.pl <filepath>\n";
++      print "example: ./create_kconfig.pl arch/arm/mach-nomadik\n";
++      exit(1);
++}
 +
-+      if (NMDK_DMA_SUSPENDED == dma->state) return;
-+      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++$KPATH=@ARGV[0];
 +
-+      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
-+      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+      flags = claim_dma_lock();
-+      nmdk_dbg("Channel %d Suspended on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+              p_dmach_reg->cfg |= NMDK_DMACH_HALT;
-+      }
-+      release_dma_lock(flags);
-+      dma->state = NMDK_DMA_SUSPENDED;
-+      return;
++@temp=split(/mach-/, $KPATH);
++@temp1=split(/\//, @temp[1]);
++$mach=@temp1[0];
++$machuc=uc($mach);
 +
-+free_dma:
-+      printk(KERN_ERR "dma%d: trying to suspend free DMA\n", channel);
-+      BUG();
-+      return;
-+inactive_dma:
-+      printk(KERN_ERR "dma driver not active\n");
-+      BUG();
++if ( -e "$KPATH/Kconfig" ) {
++      exit(0);
 +}
-+EXPORT_SYMBOL(suspend_dma);
 +
++open (KCONFIG, "> $KPATH/Kconfig") || die "Can't open file: $!";
++$Kconfig_data="# Automatically generated Kconfig: don't edit\n# To add new board support create $KPATH/<board>_Kconfig file\n\nif ARCH_$machuc\n\nchoice\n\nprompt \"$mach target board\"\n\n";
++print KCONFIG $Kconfig_data;
 +
-+/**
-+ * nomadik_dma_residue - low level method for get_dma_residue API
-+ * @channel: DMA channel number 
-+ * @dma: DMA channel data structure pointer 
-+ *
-+ * Pause the channel, read the control register, resume the channel
-+ * May not be an accurate value
-+ * returns bytes remaining on a transfer
-+ */
-+static int nomadik_dma_residue(dmach_t channel, dma_t *dma)
-+{
-+      volatile unsigned int r = 0;
-+      volatile struct dmach_register *p_dmach_reg = 
-+              (struct dmach_register *)dmaconfig_pipeadr(dma);
++@filenames =qx(ls $KPATH/*_Kconfig);
++foreach $filename(@filenames)
++      {
++              @temp=split(/mach-$mach\//, $filename);
++              @temp1=split(/_Kconfig/, @temp[1]);
++              $filename=@temp1[0];
++              chomp($filename);
++              $filenameuc=uc($filename);
++              $usc="_";
++              print KCONFIG "config $machuc$usc$filenameuc\n\tbool \"$filename\"\n\thelp\n\t\tSupprots $filename target board for $mach platform\n\n";
++      };
 +
-+      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return -1;
-+      suspend_dma(channel);
-+      mb();
++print KCONFIG "endchoice\n\n";
 +
-+      /*get transfer bytes = src_width * transfer_size */
-+      r = p_dmach_reg->cr & 0x0fff;
-+      r *= ((p_dmach_reg->cr & 0x000c0000)>>17);
-+      mb();
-+      resume_dma(channel);
++@filenames =qx(ls $KPATH/*_Kconfig);
++foreach $filename(@filenames)
++      {
++              chomp($filename);
++              print KCONFIG "source \"$filename\"\n\n";
++      };
 +
-+      return r;
++if ( -e "$KPATH/Kconfig-$mach" ) {
++      print KCONFIG "source \"$KPATH/Kconfig-$mach\"\n";
 +}
 +
-+/**
-+ * resume_dma - Resume already suspended DMA transfer for this channel
-+ * @channel: DMA channel number 
++print KCONFIG "endif\n\n";
++close KCONFIG;
++
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/deep_sleep.S
+@@ -0,0 +1,655 @@
++/*
++ * arch/arm/mach-nomadik/deep_sleep.S
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
 + *
-+ * This API will resume current dma if it is suspended previously
-+ * also this API is used to resume all active and paused DMA channels involved
-+ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
 + */
-+void resume_dma(dmach_t channel)
-+{
-+      dma_t *dma;
-+      volatile struct dmach_register *p_dmach_reg;
-+      unsigned long flags;
 +
-+      nmdk_dbg_ftrace();
-+      if (!(socdat->dma_chan)) goto inactive_dma;
-+      dma = socdat->dma_chan;
-+      if (DMA_ALL_MEM_CHANNELS == channel) {
-+              for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
-+                      if (!dma->lock) continue;
-+                      if (NMDK_DMA_SUSPENDED != dma->state) continue;
-+                      if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
-+                              == PERIPH_TO_PERIPH) continue;
-+                      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++#include <asm/arch/hardware.h>
++#include <asm/arch/entry-macro.S>
 +
-+                      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
-+                      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+                      flags = claim_dma_lock();
-+                      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+                              p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
-+                      }
-+                      nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+                      release_dma_lock(flags);
-+                      dma->state = NMDK_DMA_RESUMED;
++.global nomadik_deep_sleep
++.extern L2dummyPointer
 +
-+              }
-+              return;
-+      }
-+      dma += channel;
-+      if (!dma->lock)
-+              goto free_dma;
++nomadik_deep_sleep:
++      /*Store all the general purpose registers along with the link register*/
++      stmfd sp!,{r0-r12,lr}
 +
-+      if (NMDK_DMA_SUSPENDED != dma->state) return;
-+      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++      /* save the first parameter passed to function nomadik_deep_sleep to r12*/
++      mov r12,r0
 +
-+      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
-+      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
-+      flags = claim_dma_lock();
-+      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
-+              p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
-+      }
-+      nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
-+      release_dma_lock(flags);
-+      dma->state = NMDK_DMA_RESUMED;
-+      return;
++      /* save the second parameter passed to function nomadik_deep_sleep to the variable addr - mpmc_base*/
++      ldr r11, =mpmc_base
++      str r1,[r11]
 +
-+free_dma:
-+      printk(KERN_ERR "dma%d: trying to resume free DMA\n", channel);
-+      BUG();
-+      return;
-+inactive_dma:
-+      printk(KERN_ERR "dma driver not active\n");
-+      BUG();
-+}
-+EXPORT_SYMBOL(resume_dma);
++      /* save the third parameter passed to function nomadik_deep_sleep to the variable addr - backup_ram_base  */
++      ldr r11, =backup_ram_base
++      str r2,[r11]
 +
-+/**
-+ * nomadik_dma_set_destadr - low level method for set_dma_speed API
-+ * @channel: DMA channel number 
-+ * @dma: DMA channel data structure pointer 
-+ * @cycle: sonsidered as destination DMA address 
-+ *
-+ * Since ther is no API to program destination DMA address.
-+ * set_dma_speed is used to fulfill this need.
-+ * the function returnes the cycle which finally programs dma->spped
-+ * with destination DMA address for nomadik platform
-+ */
-+static int nomadik_dma_set_destadr(dmach_t channel, dma_t *dma, int cycle)
-+{
-+      /*Speed is used to store destination address*/
-+      return (cycle);
-+}
 +
-+/**
-+ * nomadik_dma_interrupt - Interrupt handler for DMA controller
-+ * @irq: interrupt request number 
-+ * @desc: irq structure pointer 
-+ *
-+ * checks and find out the source DMA channel who generated interrupt
-+ * if interrupt generated is Terminal count then
-+ *    process the DMA chanel irq associated with a pipe
-+ * if interrupt generated is Bus_error then
-+ *    just acknowledge it.
-+ * free processed transfer lli and schedule the queue
-+ */
-+static void nomadik_dma_interrupt(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
-+{
-+      u32 mask;
-+      volatile struct dma_register *p_dma_reg = (struct dma_register *)desc->chip_data;
-+      volatile struct dmach_register *p_dmach_reg;
-+      struct dma_struct *di_dmachan;
-+      do {
-+              p_dmach_reg = &p_dma_reg->dmach[0];
-+              nmdk_dbg2("dhach addr = %p", p_dmach_reg);
-+              for (mask = 1; mask != 0x100; mask=mask<<1) {
-+                      if (p_dma_reg->mis & mask) {
-+                              /* To wait for the physical Channel to get disabled(otherwise it may
-+                                 cause Virtual/Spurious Interrupts) */
-+                              while (nomadik_dmach_is_active_n_enabled(p_dmach_reg->cfg)) ;
-+                              if (p_dma_reg->tcmis & mask) {
-+                                      p_dma_reg->tcicr |= mask;
-+                                      irq = nomadik_dma_channel_of_pipe((void *)p_dmach_reg);
-+                                      if (irq != 0) {
-+                                              desc = socdat->dirqdesc + irq;
-+                                              di_dmachan = socdat->dma_chan + DMACH_FOR_IRQNO(irq);
-+                                              /*handle dmachanel interrupt callback*/
-+                                              nmdk_dbg3("ch%d tc intr", DMACH_FOR_IRQNO(irq));
-+                                              /*flag upper layer to that requested dma is complete*/
-+                                              if (di_dmachan->active) di_dmachan->active = 0;
-+                                              desc_handle_irq(irq, desc);
-+                                              /*free lli of processed request and schedule if any request in queue*/
-+                                              nomadik_dma_free_procesed_pipe(p_dmach_reg);
-+                                      }
-+                              }
-+                              if (p_dma_reg->emis & mask) {
-+                                      p_dma_reg->eicr |= mask;
-+                                      nmdk_error("Intr buserr for pipe %08x", (u32)p_dmach_reg);
-+                                      nomadik_dma_free_procesed_pipe(p_dmach_reg);
-+                              }
-+                      }
-+                      p_dmach_reg++;
-+              }
-+      } while (p_dma_reg->mis != 0);
-+      nmdk_dbg2("intr exit");
-+}
 +
-+struct dma_ops nomadik_dma_ops = {
-+      .type           = "DMACH:",
-+      .request        = nomadik_dma_req,
-+      .free           = nomadik_dma_fr,
-+      .enable         = nomadik_dma_en,
-+      .disable        = nomadik_dma_dis,
-+      .setspeed       = nomadik_dma_set_destadr,
-+      .residue        = nomadik_dma_residue,
-+};
++      ldr r11, =backup_ram_store
++      mov r10,#0x250
++      add r10, r2, r10
++      str r10, [r11, #0x0]
 +
-+/**
-+ * nomadik_dma_probe - driver probe function
-+ *
-+ * checks platfom_data is programmed properly
-+ * ioremaps the DMAC register and updates pointer
-+ * sets DMAC irq handler
-+ * allocates memory for lli pool
-+ * configures DMA channels and DMA channel interrupts
-+ */
-+static int nomadik_dma_probe(struct amba_device *dev, void *data)
-+{
-+      int i, ret;
-+      uint8 dmac;
-+      struct irq_desc *dirq_desc;
-+      struct dma_struct *dmachan, *dmachan_temp;
-+      volatile struct dma_register *p_dma_reg;
-+      struct irqchip *p_dirqchip;
++#ifdef DEEP_SLEEP_DEBUG
++      /*Clean entire DCache using test and clean*/
++clean_dcache_start:
++      mrc p15,0,r15,c7,c14,3
++      bne clean_dcache_start
 +
-+      nmdk_dbg_ftrace();
++      /* Invalidate I cache and Dcache */
++      mov r0,#0
++      mcr p15,0,r0,c7,c7,0
 +
-+      /* findout dma controller number*/
-+      if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
-+      else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
-+      else {
-+              nmdk_error("invalid dma device");
-+              ret = -EINVAL;
-+              goto res_out;
-+      }
++      /*Drain Write Buffers*/
++      mov r0,#0
++      mcr p15,0,r0,c7,c10,4
++#endif
 +
-+      if (! dev->dev.platform_data) {
-+              nmdk_error("platform specific data no initialized for DMAC%d", dmac);
-+              ret = -ENOMEM;
-+              goto res_out;
-+      }
-+/*    ret = amba_request_regions(dev, NULL);
-+      if (ret)
-+              goto out;
-+ */
-+      p_dma_reg = (void __iomem *)
-+              ioremap((int)dev->res.start, SZ_4K);
-+      if (!p_dma_reg) {
-+              nmdk_error("ioremap failed for DMAC%d", dmac);
-+              ret = -ENOMEM;
-+              goto res_out;
-+      }
-+      nmdk_dbg("dma_erg prt = %p irq  %d", p_dma_reg,dev->irq[0] );
-+      socdat = (struct dma_soc_data *)dev->dev.platform_data;
-+      dmachan = (struct dma_struct *)socdat->dma_chan;
-+      dirq_desc = socdat->dirqdesc;
-+      p_dirqchip = socdat->dirqchip;
-+      dirq_desc[dev->irq[0]].chip_data = (void *)p_dma_reg;
++      /* Storing the enabled values of VIC */
++      ldr r0, =vic_base
++      ldr r0, [r0,#0x0]
 +
-+      memset((void *)p_dma_reg, 0, sizeof(struct dma_register));      /*init h/w register to zero*/
-+#ifdef __STN_8810
-+#if (__STN_8810 == 10)
-+      p_dma_reg->cr = 0x01;   /*enable DMa controller */
-+#endif
-+#endif
++      ldr r1, [r0,#0xC]       /* Interrupt sslection register */
++      ldr r2, [r0, #0x2C]
++      ldr r3, [r0, #0x10]     /* Interrupt Enable register */
++      ldr r4, [r0, #0x30]
++      ldr r5, [r0, #0x54]     /* Default VAR */
++      stmfd sp!, {r1-r5}
 +
-+      set_irq_chained_handler(dev->irq[0], (void *)nomadik_dma_interrupt);
 +
-+      if (!(dmac)) {
 +
-+              lli_ptr_log = (struct dmach_lli *)dma_alloc_coherent(NULL,
-+                       MAX_DMA_LLIS * (sizeof(struct dmach_lli)),
-+                       (dma_addr_t *) &lli_ptr_phy,
-+                       GFP_DMA | GFP_ATOMIC);
-+              if (lli_ptr_log <= 0) {
-+                      nmdk_error("unable to request mem for llis");
-+                      ret = -1;
-+                      goto bad_dev;
-+              }
-+              nmdk_info("chanel lli physical adr(%08x) logical adr(%08x)", (u32)lli_ptr_phy, (u32)lli_ptr_log);
-+              dmachan_temp = dmachan;
-+              /* dma chanel irq initialization */
-+              for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
-+                      /*set_irq_chip(i, &nomadik_dma_chip);*/
-+                      set_irq_handler(i, handle_simple_irq);
-+                      set_irq_flags(i, IRQF_VALID);
-+                      socdat->dirqdesc[i].chip_data= NULL; //&p_dma_reg->dmach[ret];
-+                      if (i < MAX_DMA_CHANNELS) p_lli_pipe[DMACH_FOR_IRQNO(i)] = NULL; 
-+                      /* dma chanel data structure initialization */
-+                      dmachan[DMACH_FOR_IRQNO(i)].d_ops = &nomadik_dma_ops;
-+                      dmachan[DMACH_FOR_IRQNO(i)].dma_irq = i;
++      ldr r1,[r0,#0x100]
++      ldr r2,[r0,#0x104]
++      ldr r3,[r0,#0x108]
++      ldr r4,[r0,#0x10C]
++      ldr r5,[r0,#0x110]
++      ldr r6,[r0,#0x114]
++      ldr r7,[r0,#0x118]
++      ldr r8,[r0,#0x11C]
++      ldr r9,[r0,#0x120]
++      ldr r10,[r0,#0x124]
++      ldr r11,[r0,#0x128]
++      stmfd sp!,{r1-r11}
 +
-+              }
-+      }
-+      nmdk_info("DMA%d Module initialized Ver("DMA_VER")",dmac);
-+      return (0);
++      ldr r1,[r0,#0x12C]
++      ldr r2,[r0,#0x130]
++      ldr r3,[r0,#0x134]
++      ldr r4,[r0,#0x138]
++      ldr r5,[r0,#0x13C]
++      ldr r6,[r0,#0x200]
++      ldr r7,[r0,#0x204]
++      ldr r8,[r0,#0x208]
++      ldr r9,[r0,#0x20C]
++      ldr r10,[r0,#0x210]
++      ldr r11,[r0,#0x214]
++      stmfd sp!,{r1-r11}
 +
-+bad_dev:
-+      iounmap(p_dma_reg);
-+res_out:
-+      return (ret);
-+}
 +
-+/**
-+ * nomadik_dma_remove - driver remove function
-+ *
-+ * resets DMA channels and DMA channel interrupts configureation
-+ * deallocates memory for lli pool
-+ * resets DMAC irq handler
-+ * frees ioremapped memory
-+ */
-+static int nomadik_dma_remove(struct amba_device *dev)
-+{
-+      uint8 dmac;
-+      int i;
-+      struct irq_desc *dirq_desc;
-+      struct dma_struct *dma_chan;
-+      volatile struct dma_register *p_dma_reg;
-+      struct irqchip *p_dirqchip;
++      ldr r1,[r0,#0x218]
++      ldr r2,[r0,#0x21C]
++      ldr r3,[r0,#0x220]
++      ldr r4,[r0,#0x224]
++      ldr r5,[r0,#0x228]
++      ldr r6,[r0,#0x22C]
++      ldr r7,[r0,#0x230]
++      ldr r8,[r0,#0x234]
++      ldr r9,[r0,#0x238]
++      ldr r10,[r0,#0x23C]
++      stmfd sp!,{r1-r10}
 +
-+      nmdk_dbg_ftrace();
 +
-+      /* findout dma controller number*/
-+      if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
-+      else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
-+      else {
-+              nmdk_error("invalide dma device");
-+              return(-EINVAL);
-+      }
-+      socdat = dev->dev.platform_data;
-+      dma_chan = (struct dma_struct *)socdat->dma_chan;
-+      dirq_desc = socdat->dirqdesc;
-+      p_dma_reg = dirq_desc[dev->irq[0]].chip_data;
 +
-+      p_dirqchip = socdat->dirqchip;
-+      if (!(dmac)) {
-+              for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
-+                      //set_irq_chip(i, 0x00);
-+                      set_irq_handler(i, handle_bad_irq); 
-+                      dma_chan[DMACH_FOR_IRQNO(i)].d_ops = NULL;
-+              }
-+      }
 +
-+      set_irq_handler(dev->irq[0], handle_bad_irq); 
 +
-+      dma_free_coherent(NULL,
-+                        ((MAX_DMA_CHANNELS*(sizeof(struct dmach_lli))*8)+256),
-+                        (void *)lli_ptr_log, (dma_addr_t)lli_ptr_phy ); 
-+      lli_ptr_phy = lli_ptr_log = NULL;
++      mrc p15,0, r0,c5,c0,0 /* FSR--Domain Fault */
++      mrc p15,0, r1,c5,c0,1  /* FSR--Instruction Fault */
 +
-+      iounmap(p_dma_reg);
-+      dirq_desc[dev->irq[0]].chip_data = 0x00;
-+      /*amba_release_regions(dev);*/
++      mrc p15,0, r2,c6,c0,0 /* FAR */
 +
-+      nmdk_info("Module removed");
-+      return 0;
-+}
++      mrc p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
++      mrc p15,0, r4,c9,c0,1 /* Read ICache Lockdown */
 +
-+static struct amba_id nomadik_dma_dev_ids[] __initdata = {
-+      {
-+       .id = DMA_PER_ID,
-+       .mask = DMA_PER_MASK,
-+       },
-+      {0, 0},
-+};
++      mrc p15,0, r5,c9,c1,0 /* Read Data TLB  */
++      mrc p15,0, r6,c9,c1,1 /* Read Instruction TCM region register */
 +
-+static struct amba_driver dma_driver = {
-+      .drv = {
-+              .name = "DMA",
-+              },
-+      .id_table = nomadik_dma_dev_ids,
-+      .probe = nomadik_dma_probe,
-+      .remove = nomadik_dma_remove
-+};
++      mrc p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
 +
-+static int __init nomadik_dma_init(void)
-+{
-+      return amba_driver_register(&dma_driver);
-+}
++      mrc p15,0, r8,c13,c0,0 /* FCSE--PID */
++      mrc p15,0, r9,c13,c0,1 /* Context-ID */
 +
-+static void __exit nomadik_dma_exit(void)
-+{
-+      amba_driver_unregister(&dma_driver);
-+}
++      /* Save all these registers onto the stack */
++      stmfd sp!, {r0-r9}
 +
-+module_init(nomadik_dma_init);
-+module_exit(nomadik_dma_exit);
++      /*Move sp to non banked register. sp is not shared in banked modes.*/
++      mov r6, sp
 +
-+/* Module parameters */
++      /* Store the two user mode registers*/
++      sub r6,r6,#0x8
++      stmia r6, {sp, lr}^
++      mov r0,r0
 +
-+MODULE_AUTHOR("ST Microelectronics");
-+MODULE_DESCRIPTION("Nomadik DMA Controllers (0 and 1)");
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/fsmc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/fsmc.c
---- linux-2.6.20/arch/arm/mach-nomadik/fsmc.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/fsmc.c   2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,113 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/fsmc.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
++      /* Save current mode with interrupts disabled*/
++      mrs r7, cpsr
++      stmfd r6!, {r7}
++      bic r7,r7,#0xf
 +
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <asm/io.h>
-+#include <asm/types.h>
-+#include <asm/hardware.h>
-+#include <asm/arch/fsmc.h>
++      /* move the first par from r12 to r3 */
++      mov r3,r12
 +
-+struct fsmc_nomadik_info {
-+      unsigned char __iomem *fsmc_reg;
-+};
++      /** Following are the registers that are used
++              R6:-  Stack Pointer
++              R7:-  CPSR Value [IRQ Disabled , FIQ Disabled, Mode bit Cleared]
++              R8:-  Virtual Address of Backup SRAM (0xA0010250)
++              R9:-  UART1 Base Register [Debug Device Base Register]
++              R10:- MPMC Base Register
++              R11:- SRC Base Register
++              R12:- PMU Base Register
++      */
 +
-+static int nomadik_fsmc_probe(struct platform_device *pdev)
-+{
-+      struct fsmc_platform_data *pdata = pdev->dev.platform_data;
-+      struct fsmc_nomadik_info *data = NULL;
-+      struct resource *res = NULL;
-+      if (!pdata->init) {
-+              printk("FSMC ::: platform init() function is not present\n");
-+              return (-1);
-+      }
++      ldr r8,=backup_ram_store
++      ldr r8, [r8,#0]
 +
-+      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      ldr r9,=uart1_base
++      ldr r9, [r9,#0]
 +
-+      data = kzalloc(sizeof(struct fsmc_nomadik_info), GFP_KERNEL);
-+      data->fsmc_reg = ioremap(res->start, res->end - res->start + 1);
-+      platform_set_drvdata(pdev, data);
++      ldr r10,=mpmc_base
++      ldr r10, [r10,#0]
 +
-+      /*do platform specific fsmc init */
-+      return (pdata->init());
-+}
++      ldr r11,=src_base
++      ldr r11, [r11,#0]
 +
-+/*
-+ * Clean up routine
-+ */
-+static int nomadik_fsmc_remove(struct platform_device *pdev)
-+{
-+      struct fsmc_nomadik_info *data = NULL;
++      ldr r12,=pmu_base
++      ldr r12, [r12,#0]
 +
-+      data = platform_get_drvdata(pdev);              
-+      if(data){
-+              iounmap(data->fsmc_reg);
-+              kfree(data);
-+      }
-+      return 0;
-+}
++      /*Store the jump back address at this location (physical Address) */
++      ldr r0, =backup_ram_base
++      ldr r0, [r0,#0]
 +
-+#ifdef CONFIG_PM
++      ldr r1, =after_deep_sleep
++      mov r2, #0xC0000000
++      sub     r1, r1, r2 /* Change from VA to PA */
 +
-+#define FSMC_REG_SIZE 0x78
-+static char vect_fsmc[FSMC_REG_SIZE];
-+int nomadik_fsmc_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+      struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
-+      printk("nomadik_fsmc_suspend: called......\n");
-+      memcpy(vect_fsmc, data->fsmc_reg, FSMC_REG_SIZE);
-+      return 0;
-+}
++      str r1, [r0]
 +
-+int nomadik_fsmc_resume(struct platform_device *pdev)
-+{
-+      struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
-+      printk("nomadik_fsmc_resume: called......\n");
-+      memcpy(data->fsmc_reg, vect_fsmc, FSMC_REG_SIZE);
++    /*Enter FIQ mode-Interrupt disabled and save the banked registers*/
++    orr r0,r7,#0x1
++    msr cpsr_cxsf,r0
 +
-+      return 0;
-+}
++    mrs r0,spsr
++    stmfd r6!, {r0,r8-r14}  /* store r8 to r14 and spsr */
 +
-+#else
-+#define nomadik_fsmc_suspend NULL
-+#define nomadik_fsmc_resume NULL
++    /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
++    orr r0,r7,#0x2
++    msr cpsr_cxsf,r0 /* enter IRQ mode with IRQ/FIQ disable */
 +
-+#endif
++    mrs r0,spsr
++    stmfd r6!, {r0,r13,r14}
 +
-+static struct platform_driver nomadik_fsmc_driver = {
-+      .probe = nomadik_fsmc_probe,
-+      .remove = nomadik_fsmc_remove,
-+      .driver = {
-+                 .owner = THIS_MODULE,
-+                 .name = "NOMADIK-FSMC",
-+                 },
-+      .suspend = nomadik_fsmc_suspend,
-+      .resume = nomadik_fsmc_resume,
-+};
 +
-+static int __init nomadik_fsmc_init(void)
-+{
-+      return platform_driver_register(&nomadik_fsmc_driver);
-+}
++    /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
++    orr r0,r7,#0x7
++    msr cpsr_cxsf,r0
 +
-+module_init(nomadik_fsmc_init);
-+static void __exit nomadik_fsmc_exit(void)
-+{
-+      platform_driver_unregister(&nomadik_fsmc_driver);
-+      return;
-+}
++    mrs r0,spsr
++    stmfd r6!, {r0,r13,r14}
 +
-+module_exit(nomadik_fsmc_exit);
 +
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
-+MODULE_DESCRIPTION("FSMC driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/gpio.c ../new/linux-2.6.20/arch/arm/mach-nomadik/gpio.c
---- linux-2.6.20/arch/arm/mach-nomadik/gpio.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/gpio.c   2008-09-16 23:41:14.000000000 +0530
-@@ -0,0 +1,916 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/gpio.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#define GPIO_VER      "2.1.0"
++    /*Enter Undef Mode-IRQ/FIQ disable. Save r13,r14 and spsr */
++    orr r0,r7,#0xB
++    msr cpsr_cxsf,r0
 +
-+#include <linux/kernel_stat.h>
-+#include <linux/smp.h>
-+#include <linux/spinlock.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/device.h>
-+#include <linux/signal.h>
-+#include <linux/amba/bus.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/interrupt.h>
-+#include <asm/hardware.h>
-+#include <asm/mach/irq.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/debug.h>
++    mrs r0,spsr
++    stmfd r6!, {r0,r13,r14}
 +
-+#define GPIO_NAME             "GPIO"
 +
-+#ifndef GPIO_DEBUG
-+#define GPIO_DEBUG 0
-+#endif
++      /*Store the top of stack [VA] in the Scratch-Pad Register*/
++      str r6,[r12,#0x14]
 +
-+#define NMDK_DEBUG    GPIO_DEBUG      /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  GPIO_NAME     /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++      /*Go back in SVC mode*/
++      orr r0,r7,#0x3
++      msr cpsr_cxsf,r0
 +
-+const char *gpio_block_name[4] = {
-+      "GPIO_Block0", "GPIO_Block1", "GPIO_Block2", "GPIO_Block3",
-+};
++      /* Store MMU registers */
++      /*Domain Register on Back-up RAM structure*/
++      mrc p15,0,r0,c3,c0,0
++      str r0,[r8]
 +
-+static spinlock_t altfun_lock = SPIN_LOCK_UNLOCKED;
-+static spinlock_t pinconf_lock = SPIN_LOCK_UNLOCKED;
-+static struct gpio_soc *socdat = NULL;        /*soc specific data ptr */
-+extern struct irq_desc irq_desc[];    /* maintain interrupt info */
++      /*TTB Register*/
++      mrc p15,0,r0,c2,c0,0
++      str r0,[r8,#0x4]
 +
-+#define CHK_VALID_CALL if (! socdat) { \
-+              nmdk_error("called %s before initilization", __FUNCTION__); \
-+              return(-EINVAL); \
-+              }
++      /*MMU Enable Register*/
++      mrc p15,0,r0,c1,c0,0
++      str r0,[r8,#0x8]
 +
-+#define CHK_VALID_PIN(pin) if (irq_desc[IRQNO_GPIO(pin)].action) {\
-+              nmdk_error("%s failed, gpio%d used by irq %d", __FUNCTION__, pin , IRQNO_GPIO(pin));\
-+              return -EINVAL;\
-+              }
++      /* Virtual Address of MMU Enable*/
++      adr r0,mmu_enabled
++      str r0,[r8,#0xC]
 +
-+static char *nomadik_gpio_owner(gpio_pin pin_id)
-+{
-+      if (irq_desc[IRQNO_GPIO(pin_id)].action) {
-+              return (char *)irq_desc[IRQNO_GPIO(pin_id)].action->name;
-+      }
-+      if (irq_desc[IRQNO_GPIO(pin_id)].chip_data) {
-+              return (char *)irq_desc[IRQNO_GPIO(pin_id)].chip_data;
-+      }
-+      return (0);
-+}
 +
-+/**
-+ * nomadik_gpio_chkwr_permission - checks pin permission for write operation
-+ */
-+static int nomadik_gpio_chkwr_permission(gpio_pin pin_id, char *dev_name)
-+{
-+      char *pin_owner = nomadik_gpio_owner(pin_id);
-+      if (!pin_owner) {
-+              nmdk_error("pin %d not configured", pin_id);
-+              return -1;
-+      }
-+      if (pin_owner != dev_name)
-+              if (!strcmp(pin_owner, dev_name)) {
-+                      nmdk_error("pin %d not owned by %s", pin_id, dev_name);
-+                      return -1;
-+      }
-+      if (irq_desc[IRQNO_GPIO(pin_id)].action) {
-+              nmdk_error("pin %d used as irq cannot be written", pin_id);
-+              return -1;
-+      }
-+      return 0;
-+}
++      /*Clear the Remap bit from SRC-Register*/
++      ldr r0,[r11]
++      bic r0,r0,#0x100
++      str r0,[r11]
 +
-+/*
-+ * Static Function declarations
-+ */
-+static gpio_error gpio_setpinconfig(gpio_pin pin_id, gpio_config * config)
-+{
-+      unsigned long flags;
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
-+      gpio_error gpio_error = GPIO_OK;
++      /*Enable the Mode Status Register*/
++      mov r0,#0
++      str r0,[r11,#0x8]
 +
-+      nmdk_dbg_ftrace();
-+      spin_lock_irqsave(&pinconf_lock, flags);
-+      if (config->dev_name)
-+              irq_desc[IRQNO_GPIO(pin_id)].chip_data = config->dev_name;
-+      else
-+              irq_desc[IRQNO_GPIO(pin_id)].chip_data = "unknown";
-+      spin_unlock_irqrestore(&pinconf_lock, flags);
++      /* Clear the PMU bit - for entering the deep sleep mode instead sleep*/
++      ldr r0,[r12]
++      bic r0,r0,#0x10
++      str r0,[r12]
 +
-+      switch (config->mode) {
-+      case GPIO_ALTF_A:
-+              p_gpio_register->gpio_afsa |= mask;
-+              p_gpio_register->gpio_afsb &= ~mask;
-+              break;
-+      case GPIO_ALTF_B:
-+              p_gpio_register->gpio_afsa &= ~mask;
-+              p_gpio_register->gpio_afsb |= mask;
-+              break;
-+      case GPIO_ALTF_C:
-+              p_gpio_register->gpio_afsa |= mask;
-+              p_gpio_register->gpio_afsb |= mask;
-+              break;
-+      case GPIO_MODE_SOFTWARE:
-+              p_gpio_register->gpio_afsa &= ~mask;
-+              p_gpio_register->gpio_afsb &= ~mask;
++      /*Store the value of Scratch-Pad Register*/
++      ldr r0,=backup_ram_base_phys
++      ldr r0,[r0,#0x0]
++      str r0,[r12,#0x10]
 +
-+              switch (config->direction) {
-+              case GPIO_DIR_INPUT:
-+                      p_gpio_register->gpio_dirc = mask;
-+                      break;
-+              case GPIO_DIR_OUTPUT:
-+                      p_gpio_register->gpio_dirs = mask;
-+                      break;
-+              case GPIO_DIR_LEAVE_UNCHANGED:
-+                      break;
-+              default:
-+                      return (GPIO_INVALID_PARAMETER);
-+              }
++      /*Program to wake-up in Normal mode*/
++      ldr r0,[r11,#0x4]
++      bic r0,r0,#0xf
++      orr r0,r0,#0x9
++      str r0,[r11,#0x4]
 +
-+              if (socdat->dbounce)
-+                      gpio_error =
-+                          socdat->dbounce(p_gpio_register, mask,
-+                                          config->debounce,
-+                                          config->debounce_time);
-+              break;
-+      case GPIO_MODE_LEAVE_UNCHANGED:
-+              break;
-+      default:
-+              return (GPIO_INVALID_PARAMETER);
-+      }
-+      return (gpio_error);
-+}
++      /*Clean entire DCache using test and clean*/
++clean_dcache:
++      mrc p15,0,r15,c7,c10,3
++      bne clean_dcache
 +
-+static gpio_error gpio_resetgpiopin(gpio_pin pin_id, char *dev_name)
-+{
-+      unsigned long flags;
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
-+      char *pin_dev_name;
-+      gpio_error gpio_error = GPIO_OK;
++      /*Drain Write Buffers*/
++      mov r0,#0
++      mcr p15,0,r0,c7,c10,4
 +
-+      nmdk_dbg_ftrace();
-+      pin_dev_name = nomadik_gpio_owner(pin_id);
-+      if (!pin_dev_name)
-+              return 0;
-+      if (strcmp(dev_name, pin_dev_name)) {
-+              nmdk_error("Unable to free pin%d Current Owner is %s", pin_id,
-+                         pin_dev_name);
-+              return (-1);
-+      }
-+      p_gpio_register->gpio_afsa &= ~mask;
-+      p_gpio_register->gpio_afsb &= ~mask;    /*software mode*/
-+      p_gpio_register->gpio_dirc = mask;      /*input dir*/
-+      if (socdat->dbounce)                    /*disalbe debounce*/
-+                      gpio_error =
-+                          socdat->dbounce(p_gpio_register, mask,
-+                                          GPIO_DEBOUNCE_DISABLE,
-+                                          (gpio_debounce_time)NULL);
-+      /* mark pin is freed */
++      ldr r0, =L2dummyPointer
++      ldr r0, [r0]
++      mov r1, #0
++      cmp r1, r0
++      stmneia r0!,{r1-r8}
 +
-+      spin_lock_irqsave(&pinconf_lock, flags);
-+      irq_desc[IRQNO_GPIO(pin_id)].chip_data = NULL;
-+      spin_unlock_irqrestore(&pinconf_lock, flags);
-+      if (irq_desc[IRQNO_GPIO(pin_id)].action)
-+              irq_desc[IRQNO_GPIO(pin_id)].action->name = NULL;
-+      return (gpio_error);
-+}
++#ifdef CONFIG_L2CACHE_ENABLE
++      v_l2_cache_clean_and_invalidate r0, r1
++      v_l2_cache_sync r0, r1
++      v_l2_cache_disable r0,r1
 +
-+gpio_config altfun_pinconfig;
-+static gpio_error gpio_altfunction(gpio_alt_function alt_func,
-+                                 int which_altfunc, char *dev_name)
-+{
-+      struct gpio_altfun_data *altfun_table = socdat->altfun_tbl;
-+      int max_altfun = socdat->sz_altfun_tbl;
-+      int i, j, start, end;
-+      unsigned long flags;
-+      u8 check_pins = 1;      /*first check availability of all gpio pins */
-+      gpio_error error = -1;
++#endif
 +
-+      nmdk_dbg_ftrace();
-+      spin_lock_irqsave(&altfun_lock, flags);
-+      for (i = 0; i < max_altfun; i++) {
-+              if (altfun_table[i].altfun != alt_func)
-+                      continue;
-+              start = altfun_table[i].start;
-+              end = altfun_table[i].end;
-+              if (start > end) {
-+                      j = start;
-+                      start = end;
-+                      end = j;
-+              }
-+              if (end > GPIO_TOTAL_PINS) {
-+                      nmdk_error("range upto pin%d not suported", end);
-+                      error = GPIO_INVALID_PARAMETER;
-+                      goto exit_altfunc;
-+              }
-+              for (j = start; j <= end; j++) {
-+                      if (check_pins) {
-+                              if (nomadik_gpio_owner(j) &&
-+                                  (which_altfunc != GPIO_ALTF_DISABLE)) {
-+                                      nmdk_error("pin%d not free", j);
-+                                      error = -1;
-+                                      goto exit_altfunc;
-+                              }
-+                              if (!nomadik_gpio_owner(j) &&
-+                                  (which_altfunc == GPIO_ALTF_DISABLE)) {
-+                                      nmdk_error
-+                                          ("Trying to disable free pin%d", j);
-+                                      error = -1;
-+                                      goto exit_altfunc;
-+                              }
-+                      } else {
-+                              if (which_altfunc == GPIO_ALTF_FIND) {
-+                                      altfun_pinconfig.mode =
-+                                          altfun_table[i].type;
-+                              } else {
-+                                      altfun_pinconfig.mode = which_altfunc;
-+                              }
-+                              altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
-+                              altfun_pinconfig.debounce =
-+                                  GPIO_DEBOUNCE_DISABLE;
-+                              altfun_pinconfig.dev_name = dev_name;
 +
-+                              if (which_altfunc != GPIO_ALTF_DISABLE) {
-+                                      error =
-+                                          gpio_setpinconfig(j,
-+                                                            &altfun_pinconfig);
-+                              } else {
-+                                      error = gpio_resetgpiopin(j, dev_name);
-+                              }
-+                              if (!error)
-+                                      continue;
-+                              nmdk_error
-+                                  ("GPIO %d configuration failure (nmdk_error:%d)",
-+                                   j, error);
-+                              error = GPIO_INVALID_PARAMETER;
-+                              goto exit_altfunc;
-+                      }
-+              }
-+              if (altfun_table[i].cont == 0) {
-+                      /*schedule to configure if check sucessfull */
-+                      if (check_pins) {
-+                              check_pins = 0;
-+                              i = -1;
-+                      } else {
-+                              error = 0;
-+                              goto exit_altfunc;
-+                      }
-+              }
-+      }
-+      exit_altfunc:
-+      spin_unlock_irqrestore(&altfun_lock, flags);
-+      return (error);
-+}
++      /* Prefetch certain instructions in the cache.  */
++    adr r4, cache_prefetch_start
++      adr r5, cache_prefetch_end
++      mvn r1,#0x1F
++      ands r4,r1,r4
++fetch_loop:
++      mcr p15, 0, r4, c7, c13,1
++      cmp r4,r5
++      addls r4, r4, #0x20
++      bls fetch_loop
 +
-+/**
-+ * exported functions for other drives
-+ */
 +
-+/*
-+ * Get gpio list for /proc/gpio
-+ */
-+int get_gpio_list(char *buf)
-+{
-+      struct gpio_register *p_gpio_register;
-+      uint32 mask;
-+      char *p = buf;
-+      char *gpiofunc;
-+      char *gpio_client;
-+      int i;
++cache_prefetch_start:
++      ldr r10, =mpmc_base
++      ldr r10,[r10,#0x0]
 +
-+      CHK_VALID_CALL;
-+      p += sprintf(p, "Pin: %s\t%s\n", "mode", "client");
-+      for (i = 0; i < GPIO_TOTAL_PINS; i++) {
-+              gpio_client = nomadik_gpio_owner(i);
-+              if (gpio_client) {
-+                      p_gpio_register = (struct gpio_register *)
-+                          get_irq_chip_data(GPIO_PIN2BLKIRQ(i));
-+                      mask = 1UL << (i % GPIO_PINS_PER_BLOCK);
-+                      if (irq_desc[IRQNO_GPIO(i)].action)
-+                              gpiofunc = "Irq";
-+                      else if ((p_gpio_register->gpio_afsa & mask)
-+                               && (p_gpio_register->gpio_afsb & mask))
-+                              gpiofunc = "AltFun_C";
-+                      else if ((p_gpio_register->gpio_afsa & mask)
-+                               && !(p_gpio_register->gpio_afsb & mask))
-+                              gpiofunc = "AltFun_A";
-+                      else if (!(p_gpio_register->gpio_afsa & mask)
-+                               && (p_gpio_register->gpio_afsb & mask))
-+                              gpiofunc = "AltFun_B";
-+                      else
-+                              gpiofunc = "I/O";
-+                      p += sprintf(p, "%3d: %s\t%s\n", i,
-+                                   gpiofunc, gpio_client);
-+              }
-+      }
-+      return p - buf;
-+}
++/* Check sdram is idle */
++poll_loop:
++      ldr r1,[r10, #0x4]
++      ands r1,r1,#0x1
++      cmp r1,#0
++      bne poll_loop
 +
-+int nomadik_gpio_resetpinconfig(gpio_pin pin_id, char *dev_name)
-+{
-+      int error = 0;
++      /*Put SDRAM in self-refresh mode*/
++      ldr r1,[r10, #0x20]
++      bic r1,r1,#0x1
++      orr r1,r1,#0x04
++      str r1,[r10, #0x20]
 +
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+      CHK_VALID_PIN(pin_id);
++      /*Wait for SDRAM to go in self-refresh*/
++wait:
++      ldr r1,[r10,#0x4]
++      and r1,r1,#0x4
++      cmp r1,#0x0
++      beq wait
 +
-+      if (0 != nomadik_gpio_owner(pin_id))
-+              error = gpio_resetgpiopin(pin_id, dev_name);
-+      return (error);
-+}
 +
-+int nomadik_gpio_setpinconfig(gpio_pin pin_id, gpio_config * pin_config)
-+{
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+      CHK_VALID_PIN(pin_id);
-+      if (!irq_desc[IRQNO_GPIO(pin_id)].action) {
-+              if (nomadik_gpio_owner(pin_id)) {
-+                      nmdk_error("pin%d not available.. aquired by %s client",
-+                                 pin_id, nomadik_gpio_owner(pin_id));
-+                      return -1;
-+              }
-+              return (gpio_setpinconfig(pin_id, pin_config));
-+      } else {
-+              nmdk_error("Cannot set gpio%d used by irq %d", pin_id,
-+                         IRQNO_GPIO(pin_id));
-+              return -1;
-+      }
-+      return 0;
-+}
 +
-+int nomadik_gpio_writepin(gpio_pin pin_id, gpio_data value, char *dev_name)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
 +
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+      CHK_VALID_PIN(pin_id);
-+      if (nomadik_gpio_chkwr_permission(pin_id, dev_name)) return -1;
-+      switch (value) {
-+      case GPIO_DATA_HIGH:
-+              p_gpio_register->gpio_dats = mask;
-+              break;
-+      case GPIO_DATA_LOW:
-+              p_gpio_register->gpio_datc = mask;
-+              break;
-+      default:
-+              nmdk_error("Invalid value passed in %s", __FUNCTION__);
-+              return GPIO_INVALID_PARAMETER;
-+      }
-+      return GPIO_OK;
-+}
++      /*Move system to sleep mode*/
++      ldr r1,[r11]
++      bic r1, r1, #0x7
++      str r1,[r11]
 +
-+int nomadik_gpio_readpin(gpio_pin pin_id, gpio_data * p_value)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++goto_sleep:
++      ldr r1,[r11]
++      and r1,r1,#0x78
++      cmp r1,#0x0
++      bne goto_sleep
 +
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+      if ((p_gpio_register->gpio_dat & mask) != GPIO_ALL_ZERO) {
-+              *p_value = GPIO_DATA_HIGH;
-+      } else {
-+              *p_value = GPIO_DATA_LOW;
-+      }
-+      return GPIO_OK;
-+}
 +
-+int nomadik_gpio_readblock(gpio_block_id block_id, uint32 * p_value,
-+                         uint32 mask)
-+{
-+      struct gpio_register *p_gpio_register;
++      nop
++      nop
++      nop
++      nop
 +
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+      if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
-+               return GPIO_INVALID_PARAMETER;
 +
-+      if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
-+              p_gpio_register =
-+                  (struct gpio_register *)get_irq_chip_data(block_id -
-+                                                           GPIO_BLOCK_32_BITS_0_TO_31
-+                                                           + IRQ_GPIO0);
-+              *p_value = p_gpio_register->gpio_dat & (mask & GPIO_32BIT_MASK);
 +
-+      } else {
-+              p_gpio_register = (struct gpio_register *)
-+                  get_irq_chip_data((block_id -
-+                                    GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
-+                                   IRQ_GPIO0);
-+              switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
-+              case 0:
-+                      *p_value =
-+                          (p_gpio_register->gpio_dat & (mask & 0x0000ffff));
-+                      break;
-+              case 1:
-+                      *p_value =
-+                          (p_gpio_register->
-+                           gpio_dat & (mask & 0x00ffff00)) >> GPIO_SHIFT8;
-+                      break;
-+              case 2:
-+                      *p_value =
-+                          (p_gpio_register->
-+                           gpio_dat & (mask & 0xffff0000)) >> GPIO_SHIFT16;
-+                      break;
-+              case 3:
-+                      *p_value =
-+                          (p_gpio_register->
-+                           gpio_dat & (mask & 0xff000000)) >> GPIO_SHIFT24;
-+                      p_gpio_register += SZ_4K;       /* point next bank */
-+                      *p_value |=
-+                          (p_gpio_register->
-+                           gpio_dat & (mask & 0x000000ff)) << GPIO_SHIFT8;
-+                      break;
-+              }
-+      }
-+      return (GPIO_OK);
-+}
 +
-+int nomadik_gpio_writeblock(gpio_block_id block_id, uint32 p_value, uint32 mask, char *dev_name)
-+{
-+      struct gpio_register *p_gpio_register;
-+      int i, bankno, testmask;
++/* For deepsleep this much pre-fetch is enough */
++cache_prefetch_end:
++      mov r0, r0
++      mov r0, r0
++      mov r0, r0
++      mov r0, r0
 +
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+      if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
-+              return GPIO_INVALID_PARAMETER;
 +
-+      if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
-+              bankno = block_id * GPIO_PINS_PER_BLOCK;
-+              testmask = 0x01;
-+              for (i = bankno; i < (bankno + GPIO_PINS_PER_BLOCK); i++) {
-+                      if ((mask & testmask) &&
-+                              (!nomadik_gpio_chkwr_permission(i, dev_name))){
-+                              return -1;
-+                      }
-+                      testmask = 1UL << i;
-+              }
++after_deep_sleep:
++/* Restore the MMU registers */
 +
-+              p_gpio_register =
-+                  (struct gpio_register *)get_irq_chip_data(block_id -
-+                                                           GPIO_BLOCK_32_BITS_0_TO_31
-+                                                           + IRQ_GPIO0);
-+              p_gpio_register->gpio_datc =
-+                  ~(p_value & (mask & GPIO_32BIT_MASK));
-+              p_gpio_register->gpio_dats = p_value & (mask & GPIO_32BIT_MASK);
 +
-+      } else {
-+              bankno = (block_id - GPIO_BLOCK_16_BITS_0_TO_15) * 8;
-+              testmask = 0x01;
-+              for (i = bankno; i < (bankno + (GPIO_PINS_PER_BLOCK / 2)); i++) {
-+                      if ((mask & testmask) &&
-+                              (!nomadik_gpio_chkwr_permission(i, dev_name))){
-+                              return -1;
-+                      }
-+                      testmask = 1UL << i;
-+              }
-+              p_gpio_register = (struct gpio_register *)
-+                  get_irq_chip_data((block_id -
-+                                    GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
-+                                   IRQ_GPIO0);
-+              switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
-+              case 0:
-+                      p_gpio_register->gpio_datc =
-+                          ~(p_value & (mask & 0x0000ffff));
-+                      p_gpio_register->gpio_dats =
-+                          p_value & (mask & 0x0000ffff);
-+                      break;
-+              case 1:
-+                      p_gpio_register->gpio_datc =
-+                          ~(((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
-+                      p_gpio_register->gpio_dats =
-+                          (((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
-+                      break;
-+              case 2:
-+                      p_gpio_register->gpio_datc =
-+                          ~(((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
-+                      p_gpio_register->gpio_dats =
-+                          (((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
-+                      break;
-+              case 3:
-+                      p_gpio_register->gpio_datc =
-+                          ~(((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
-+                      p_gpio_register->gpio_dats =
-+                          (((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
-+                      p_gpio_register += SZ_4K;       /* point next bank */
-+                      p_gpio_register->gpio_datc =
-+                          ~(p_value & (mask & 0x000000ff));
-+                      p_gpio_register->gpio_dats =
-+                          p_value & (mask & 0x000000ff);
-+                      break;
-+              }
-+      }
-+      return (GPIO_OK);
-+}
 +
-+int nomadik_gpio_altfuncenable(gpio_alt_function altfunc, char *dev_name)
-+{
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+          return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
-+}
++      ldr r8,=backup_ram_store_phys
++      mov r9, #0xC0000000
++      sub r8, r8, r9  /* Change from VA to PA */
++      ldr r8, [r8,#0]
 +
-+int nomadik_gpio_altfuncdisable(gpio_alt_function altfunc, char *dev_name)
-+{
-+      nmdk_dbg_ftrace();
-+      CHK_VALID_CALL;
-+          return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
-+}
 +
-+EXPORT_SYMBOL(nomadik_gpio_setpinconfig);
-+EXPORT_SYMBOL(nomadik_gpio_resetpinconfig);
-+EXPORT_SYMBOL(nomadik_gpio_writepin);
-+EXPORT_SYMBOL(nomadik_gpio_readpin);
-+EXPORT_SYMBOL(nomadik_gpio_readblock);
-+EXPORT_SYMBOL(nomadik_gpio_writeblock);
-+EXPORT_SYMBOL(nomadik_gpio_altfuncenable);
-+EXPORT_SYMBOL(nomadik_gpio_altfuncdisable);
 +
-+/**
-+ * Interrupt handling functions
-+ */
-+static void nomadik_gpio_intrenable(struct gpio_register *p_gpio_register,
-+                                  uint32 mask, uint32 type)
-+{
-+      if (socdat->irqen) {
-+              socdat->irqen(p_gpio_register, mask, type);
-+      } else {
-+              nmdk_error("irqen SOC specific function not configured");
-+      }
-+}
++out_of_sleep:
++ /*Domain Register*/
++      ldr r0,[r8, #0x0]
++      mcr p15,0,r0,c3,c0,0
 +
-+static void nomadik_gpio_intrdisable(struct gpio_register *p_gpio_register,
-+                                   uint32 mask)
-+{
-+      if (socdat->irqdis)
-+              socdat->irqdis(p_gpio_register, mask);
-+      else {
-+              nmdk_error("irqdis SOC specific function not configured");
-+      }
-+}
-+/**
-+   * @flag if 1 means enable, 0 means disable
-+ */
-+int nomadik_gpio_wakeupconfig(unsigned int irq, unsigned int flag)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
-+      if (flag)
-+      p_gpio_register->gpio_fwimsc |= mask;
-+      else
-+      p_gpio_register->gpio_fwimsc &= (~mask);
-+      return 0;
-+}
-+void nomadik_gpio_slpmreg_config(gpio_pin pin_id)
-+{
-+      struct gpio_register *p_gpio_register =
-+                  (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
-+      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
-+      p_gpio_register->gpio_slpm |= mask;
-+}
++      /*TTB Register*/
++      ldr r0,[r8,#0x4]
++      mcr p15,0,r0,c2,c0,0
 +
-+static void nomadik_gpio_mask(unsigned int irq)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
 +
-+      nmdk_dbg_ftrace();
-+      nomadik_gpio_intrdisable(p_gpio_register, mask);
-+}
++      /* Virtual Address of mmu_enabled*/
++      ldr r4, [r8, #0xC]
 +
-+static void nomadik_gpio_unmask(unsigned int irq)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
++      /*MMU Enable Register*/
++      ldr r1, [r8,#0x8]
++      mcr p15,0,r1,c1,c0,0
 +
-+      nmdk_dbg_ftrace();
-+      if (!irq_desc[irq].handler_data) {
-+              nmdk_info
-+                  ("for irq%d, configuruing default type as rising edge",
-+                   irq);
-+              irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
-+      }
-+      nomadik_gpio_intrenable(p_gpio_register, mask,
-+                              (uint32) irq_desc[irq].handler_data);
-+}
++      mov pc,r4
++      mov r0, r0
++      mov r0, r0
++      mov r0, r0
++      mov r0, r0
 +
-+static void nomadik_gpio_intrack(unsigned int irq)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
 +
-+      nmdk_dbg_ftrace();
-+      p_gpio_register->gpio_ic = mask;
-+}
 +
-+/*
-+ * callback function for gpio specific set_irq_type sys call
-+ * This function will be called in the context of request_irq also
-+ */
-+static int nomadik_gpio_intrsettype(unsigned int irq, unsigned int type)
-+{
-+      gpio_config settype_config;
-+      char *client_name = nomadik_gpio_owner(GPIO_PIN_FOR_IRQ(irq));
-+      int ret;
++mmu_enabled:
 +
-+      nmdk_dbg_ftrace();
-+      type&=SA_TRIGGER_MASK;
-+      /* mistake proofing for invalid entry incase if you try to configure
-+       * gpiopin interrupt for priority/fiq
-+       */
-+      if ( (type == SA_TRIGGER_MASK) ||
-+           (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_RISING)) ||
-+           (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_FALLING)) ||
-+           (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH))) {
-+              nmdk_error("Invalid IRQ type requested for irq%d", irq);
-+              return -1;
-+      }
-+      if (!irq_desc[irq].action) {
-+              nmdk_error("Trying to set type for unrequested irq%d", irq);
-+      }
-+      if (irq_desc[irq].handler_data) {
-+              nmdk_info("irq %d type already set by %s", irq,
-+                        client_name);
-+              return (0);
-+      }
-+      settype_config.mode = GPIO_MODE_SOFTWARE;
-+      settype_config.direction = GPIO_DIR_INPUT;
-+      settype_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      settype_config.dev_name = client_name;
-+      ret = gpio_setpinconfig(GPIO_PIN_FOR_IRQ(irq), &settype_config);
-+      if (ret < 0) {
-+              nmdk_error("Error in setting irq %d (err %d)", irq, ret);
-+              return (ret);
-+      }
-+      nmdk_dbg("set_irq_type =%d", type);
-+      if (type) {
-+              irq_desc[irq].handler_data = (void *)(type & SA_TRIGGER_MASK);
-+      } else {
-+              nmdk_info
-+                  ("%s Configuring default irq type to SA_TRIGGER_RISING",
-+                   __FUNCTION__);
-+              irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
-+      }
-+      if ((SA_TRIGGER_RISING == (int)irq_desc[irq].handler_data) ||
-+          (SA_TRIGGER_FALLING == (int)irq_desc[irq].handler_data))
-+              irq_desc[irq].handle_irq = handle_edge_irq;
-+      else if ((SA_TRIGGER_LOW == (int)irq_desc[irq].handler_data) ||
-+               (SA_TRIGGER_HIGH == (int)irq_desc[irq].handler_data))
-+              irq_desc[irq].handle_irq = handle_level_irq;
-+      /* Standard api call set_irq_handler() cannot be used from
-+         the contest of set_irq_type... deadlock occures */
++#ifdef DEEP_SLEEP_DEBUG
++      ldr r9, =uart1_base
++      ldr r9, [r9,#0]
++#endif
 +
-+      return (GPIO_OK);
-+}
++      ldr r11, =src_base
++      ldr r11, [r11,#0]
++      ldr r12, =pmu_base
++      ldr r12, [r12,#0]
++      ldr r10, =mpmc_base
++      ldr r10, [r10,#0]
 +
-+/**
-+ * callback function for enable_irq_wake and disable_irq_wake system calls
-+ *
-+ * @flag if 1 means enable, 0 means disable
-+ */
-+static int nomadik_gpio_intrwake(unsigned int irq, unsigned int flag)
-+{
-+      struct gpio_register *p_gpio_register =
-+          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
-+      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
-+      unsigned int type = (uint32) irq_desc[irq].handler_data;
 +
-+      if (socdat->irqwake) {
-+              if (!type)
-+                      type = SA_TRIGGER_RISING;
-+              if (!flag)
-+                      type = 0xff;    /* to disable wakeup irq */
-+              socdat->irqwake(p_gpio_register, mask, type);
-+      } else {
-+              nmdk_error("irqwake SOC specific function not configured");
-+              return (-1);
-+      }
-+      return (0);
-+}
 +
-+struct irq_chip nomadik_gpio_chip = {
-+      .ack = nomadik_gpio_intrack,
-+      .mask = nomadik_gpio_mask,
-+      .unmask = nomadik_gpio_unmask,
-+      .set_type = nomadik_gpio_intrsettype,
-+      .set_wake = nomadik_gpio_intrwake,
-+};
++      /* Move system to Normal Mode */
++      ldr r1,[r11]
++      orr r1,r1,#0x4
++      bic r1,r1,#0x3
++      str r1,[r11]
 +
-+static void nomadik_gpio_intr_handler(u32 irq, struct irq_desc *desc)
-+{
-+      struct gpio_register *p_gpio_reg =
-+          (struct gpio_register *)get_irq_chip_data(irq);
-+      unsigned long mis = p_gpio_reg->gpio_mis;
 +
-+      nmdk_dbg2("%d intr desc %p", (irq - IRQ_GPIO0), desc);
-+      irq = IRQNO_GPIO((irq - IRQ_GPIO0) * GPIO_PINS_PER_BLOCK);
-+      desc = irq_desc + irq;
-+      while (mis) {
-+              if (mis & 1) {
-+                      nmdk_dbg2("handling irq %d", irq);
-+                      desc->handle_irq(irq, desc);
-+              }
-+              irq++;
-+              desc++;
-+              mis >>= 1;
-+      }
-+}
++      /*Wait for the system to move in normal mode*/
++wait_norm1:
++      ldr r0,[r11, #0x0]
++      and r0,r0,#0x78
++      cmp r0, #0x20
++      bne wait_norm1
 +
-+static int nomadik_gpio_probe(struct amba_device *dev, void *id)
-+{
-+      int i, ret;
-+      struct gpio_register *p_gpio_register;
 +
-+      nmdk_dbg_ftrace();
++      /* Remove the chip from Interrupt mode */
++      ldr r0,[r11, #0x4]
++      bic r0,r0,#0x1
++        str r0,[r11, #0x4]
 +
-+      socdat = dev->dev.platform_data;
++      /* Clear the interrupt mode status bit*/
++      mov r0, #0x0
++      str r0, [r11, #0x8]
 +
-+      if (!socdat) {
-+              nmdk_error("platform_data struct for %s not initialized",
-+                         dev->dev.bus_id);
-+              ret = -1;
-+              goto out;
-+      }
-+      ret = amba_request_regions(dev, NULL);
-+      if (ret)
-+              goto out;
++      /* For CLCD Refresh issue */
++      ldr r1, =0x00000005     /* Loading the value with timeout so as to avoid flickering on CLCD */
++      str r1, [r10, #0x408]
 +
-+      for (i = 0; i < (dev->irq[1] - dev->irq[0]); i++) {
-+              set_irq_chip_data((i + dev->irq[0]),
-+                               (void *)ioremap((int)dev->res.start +
-+                                               (i * SZ_4K), SZ_4K));
 +
-+              p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
++      /* Stack Restoration Routine */
++      ldr r6,[r12,#0x14]
 +
-+              if (!p_gpio_register) {
-+                      ret = -ENOMEM;
-+                      goto res_out;
-+              }
++      /* Store the value of cpsr in r7*/
++      mrs r7,cpsr
++      orr r7,r7,#0xC0 /*Not Needed*/
++      bic r7,r7,#0xf
 +
-+              set_irq_chained_handler((i + dev->irq[0]),
-+                                      nomadik_gpio_intr_handler);
-+      }
++      /*Move to undef mode and restore everything*/
++    orr r0,r7,#0xB
++    msr cpsr_cxsf,r0
 +
-+      for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
-+              set_irq_chip(i, &nomadik_gpio_chip);
-+              set_irq_handler(i, handle_level_irq);
-+              set_irq_flags(i, IRQF_VALID);
-+              set_irq_chip_data(i, NULL);     /*clear gpio client name */
-+              irq_desc[i].handler_data = NULL;        /*clear gpio irq_type */
-+      }
++    ldmfd r6!, {r0,r13,r14}
++    msr spsr_cxsf,r0
 +
-+      nmdk_info("Module initialized Ver(" GPIO_VER ")");
-+      return 0;
++    /*Enter Abort mode-IRQ/FIQ disable. Save r13,r14 and spsr */
++    orr r0,r7,#0x7
++    msr cpsr_cxsf,r0
 +
-+      res_out:
-+      for (; 0 == i; i--) {
-+              p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
++    ldmfd r6!, {r0,r13,r14}
++    msr spsr_cxsf,r0
 +
-+              set_irq_handler((i + dev->irq[0]), handle_bad_irq);
-+              if (p_gpio_register)
-+                      iounmap((void __iomem *)p_gpio_register);
-+              set_irq_chip_data((i + dev->irq[0]), NULL);
++     /*Enter IRQ mode-Interrupt disabled Save: r13,r14 and spsr*/
++    orr r0,r7,#0x2
++    msr cpsr_cxsf,r0
 +
-+      }
-+      amba_release_regions(dev);
-+      out:
-+      return (ret);
-+}
++    ldmfd r6!, {r0,r13,r14}
++    msr spsr_cxsf,r0
 +
-+static int nomadik_gpio_remove(struct amba_device *dev)
-+{
-+      int i;
 +
-+      nmdk_dbg_ftrace();
-+      for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
-+              set_irq_chip(i, NULL);
-+              set_irq_chip_data(i, NULL);
-+      }
++    /*Enter FIQ mode-Interrupt disabled and save the banked registers. Save: r8-r14 and spsr*/
++    orr r0,r7,#0x1
++    msr cpsr_cxsf,r0
 +
-+      for (i = dev->irq[0]; i < dev->irq[1]; i++) {
-+              set_irq_handler(i, handle_bad_irq);
-+              iounmap((void __iomem *)get_irq_chip_data(i));
-+              set_irq_chip_data(i, NULL);
-+      }
-+      amba_release_regions(dev);
-+      socdat = NULL;
-+      nmdk_info("Module removed");
-+      return 0;
-+}
++    ldmfd r6!, {r0,r8-r14}
++    msr spsr_cxsf,r0
 +
-+#if (defined CONFIG_PM && defined __STN_8815)
-+static int nomadik_gpio_suspend(struct amba_device *dev, pm_message_t state)
-+{
-+      unsigned int i;
-+      struct gpio_register *p_gpio_register;
-+      struct gpio_pm_context *gpio_pm;;
++    /* Here we will restore our cpsr..IRQ/FIQ Disabled*/
++    ldr r0, [r6]
++    msr cpsr_cxsf, r0
++    add r6, r6,#4
 +
-+      nmdk_dbg_ftrace();
-+      dev->dev.driver_data =
-+          kmalloc(sizeof(struct gpio_pm_context) * GPIO_BLOCKS_COUNT,
-+                  GFP_KERNEL);
-+      gpio_pm = (struct gpio_pm_context *)dev->dev.driver_data;
-+      if (!gpio_pm) {
-+              nmdk_error("Unable to alocate memory %s failed...",
-+                         __FUNCTION__);
-+      }
-+      for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
-+              p_gpio_register =
-+                  (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
-+              gpio_pm[i].slpm = p_gpio_register->gpio_slpm;
-+              gpio_pm[i].rwimsc = p_gpio_register->gpio_rwimsc;
-+              gpio_pm[i].fwimsc = p_gpio_register->gpio_fwimsc;
-+              gpio_pm[i].rimsc = p_gpio_register->gpio_rimsc;
-+              gpio_pm[i].fimsc = p_gpio_register->gpio_fimsc;
-+      }
-+      return 0;
-+}
++    /*Now only two user-mode registers are left*/
++    ldmia r6,{sp, lr}^
++    mov r0,r0
++    add r6,r6,#8
 +
-+static int nomadik_gpio_resume(struct amba_device *dev)
-+{
-+      unsigned int i;
-+      struct gpio_register *p_gpio_register;
-+      struct gpio_pm_context *gpio_pm =
-+          (struct gpio_pm_context *)dev->dev.driver_data;
++    /*Restore sp*/
++    mov sp,r6
 +
-+      nmdk_dbg_ftrace();
-+      for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
-+              p_gpio_register =
-+                  (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
-+              p_gpio_register->gpio_slpm = gpio_pm[i].slpm;
-+              p_gpio_register->gpio_rwimsc = gpio_pm[i].rwimsc;
-+              p_gpio_register->gpio_fwimsc = gpio_pm[i].fwimsc;
-+              p_gpio_register->gpio_rimsc = gpio_pm[i].rimsc;
-+              p_gpio_register->gpio_fimsc = gpio_pm[i].fimsc;
-+      }
-+      kfree(gpio_pm);
-+      return 0;
-+}
-+#else
-+#define nomadik_gpio_suspend NULL
-+#define nomadik_gpio_resume NULL
-+#endif
 +
-+static struct amba_id nomadik_gpio_ids[] = {
-+      {
-+       .id = GPIO_PER_ID,
-+       .mask = GPIO_PER_MASK,
-+       },
-+      {0, 0},
-+};
++    /*ReStore the remaining items*/
++    ldmfd sp!, {r0-r9}
 +
-+static struct amba_driver gpio_driver = {
-+      .drv = {
-+              .owner = THIS_MODULE,
-+              .name = "gpio",
-+              },
-+      .probe = nomadik_gpio_probe,
-+      .remove = nomadik_gpio_remove,
-+      .suspend = nomadik_gpio_suspend,
-+      .resume = nomadik_gpio_resume,
-+      .id_table = nomadik_gpio_ids,
-+};
++    mcr p15,0, r0,c5,c0,0 /*FSR--Domain Fault */
++      mcr p15,0, r1,c5,c0,1 /*FSR--Instruction Fault */
 +
-+static int __init nomadik_gpio_init(void)
-+{
-+      return amba_driver_register(&gpio_driver);
-+}
++      mcr p15,0, r2,c6,c0,0 /* FAR */
 +
-+static void __exit nomadik_gpio_exit(void)
-+{
-+      amba_driver_unregister(&gpio_driver);
-+}
++      mcr p15,0, r3,c9,c0,0 /* Read Dcache Lockdown */
++      mcr p15,0, r4,c9,c0,1  /* Read ICache Lockdown */
 +
-+EXPORT_SYMBOL(nomadik_gpio_intrsettype);
-+EXPORT_SYMBOL(nomadik_gpio_mask);
-+EXPORT_SYMBOL(nomadik_gpio_unmask);
++      mcr p15,0, r5,c9,c1,0 /* Read Data TLB  */
++      mcr p15,0, r6,c9,c1,1 /* Read Instruction Lockdown */
 +
-+module_init(nomadik_gpio_init);
-+module_exit(nomadik_gpio_exit);
++      mcr p15,0, r7,c10,c0,0 /* Data TLB LockDown operation */
 +
-+MODULE_AUTHOR("Prafulla WADASKAR <prafulla.wadaskar@st.com>");
-+MODULE_DESCRIPTION("Nomadik GPIO Driver");
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/irq.c ../new/linux-2.6.20/arch/arm/mach-nomadik/irq.c
---- linux-2.6.20/arch/arm/mach-nomadik/irq.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/irq.c    2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,231 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/irq.c
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Author     : Prafulla WADASKAR <prafulla.wadaskar@st.com>
-+ * Reference  : Documentation/arm/STM-Nomadik/irq_usrguide.txt
-+ */
-+#include <linux/kernel_stat.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/list.h>
-+#include <linux/timer.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/mach/irq.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/debug.h>
++      mcr p15,0, r8,c13,c0,0 /* FCSE--PID */
++      mcr p15,0, r9,c13,c0,1  /* Context-ID */
 +
-+#define VIC_VER       "2.0.0"
-+#define VIC_NAME      "VIC"
 +
-+#ifndef VIC_DEBUG
-+#define VIC_DEBUG 0
-+#endif
 +
-+#define NMDK_DEBUG    VIC_DEBUG       /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  VIC_NAME      /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+struct vic_basic_registers {
-+      u32 irqsr;              /* IRQ Status*/
-+      u32 fiqsr;              /* FIQ Status*/
-+      u32 ris;                /* Raw Interrupt status*/
-+      u32 isel;               /* Interrupt select*/
-+      u32 iens;               /* Interrupt enable set*/
-+      u32 ienc;               /* Interrupt enable clear*/
-+      u32 swisr;              /* Software interrupt*/
-+      u32 swicr;              /* Software interrupt clear*/
-+};
 +
-+struct vic_register {
-+      struct vic_basic_registers bank[(MAXIRQNUM/32) +1];
-+      u32 per;                /* Protection enable*/
-+#if defined(__STN_8815)
-+      u32 reserved_1[(0x50 - 0x44) >> 2];     /* Reserved*/
-+      u32 isr_var;            /* ISR Vector address*/
-+      u32 isr_dvar;           /* ISR Default vector address*/
-+      u32 reserved_2[(0x100 - 0x58) >> 2];    /* Reserved*/
-+#elif defined(__STN_8810)
-+      u32 reserved_1[(0x30 - 0x24) >> 2];     /* Reserved*/
-+      u32 isr_var;            /* ISR Vector address*/
-+      u32 isr_dvar;           /* ISR Default vector address*/
-+      u32 reserved_2[(0x100 - 0x38) >> 2];    /* Reserved*/
-+#endif
-+      u32 var[VIC_VECTORED_IRQ_NUM];  /* Vector address 0-15*/
-+      u32 reserved_3[(0x200 - 0x140) >> 2];   /* Reserved*/
-+      u32 vcr[VIC_VECTORED_IRQ_NUM];  /* Vector control 0-15*/
-+      u32 reserved_4[(0x300 - 0x240) >> 2];   /* Reserved*/
-+      u32 itcr;               /* Test Control register*/
-+      u32 itip_1;             /* Test input nVICIRQIN/nVICFIQIN*/
-+      u32 itip_2;             /* Test input VICVECADDRIN*/
-+      u32 itop_1;             /* Test output nVICIRQ/nVICFIQ*/
-+      u32 itop_2;             /* Test output VICVECADDROUT*/
-+      u32 reserved_5[(0xFE0 - 0x314) >> 2];   /* Reserved*/
-+      u32 periph_id_0;        /* Peripheral id: bits 7:0*/
-+      u32 periph_id_1;        /* Peripheral id: bits 15:8*/
-+      u32 periph_id_2;        /* Peripheral id: bits 23:16*/
-+      u32 periph_id_3;        /* Peripheral id: bits 31:24*/
-+      u32 pcell_id_0;         /* PrimeCell id: bits 7:0*/
-+      u32 pcell_id_1;         /* PrimeCell id: bits 15:8*/
-+      u32 pcell_id_2;         /* PrimeCell id: bits 23:16*/
-+      u32 pcell_id_3;         /* PrimeCell id: bits 31:24*/
-+};
 +
-+extern struct irq_desc irq_desc[];    /* interrupt description table */
-+static volatile struct vic_register *p_vic_register =
-+                      (struct vic_register *)IO_ADDRESS(NOMADIK_IC_BASE);
++      /* ReStoring the enabled values of VIC */
++      ldr r0, =vic_base
++      ldr r0, [r0,#0]
 +
-+static int nomadik_vic_set_type(unsigned int irq, unsigned int type);
-+static DEFINE_SPINLOCK(vic_lock);
++      ldmfd sp!,{r1-r10}
++      str r1,[r0,#0x218]
++      str r2,[r0,#0x21C]
++      str r3,[r0,#0x220]
++      str r4,[r0,#0x224]
++      str r5,[r0,#0x228]
++      str r6,[r0,#0x22C]
++      str r7,[r0,#0x230]
++      str r8,[r0,#0x234]
++      str r9,[r0,#0x238]
++      str r10,[r0,#0x23C]
 +
-+static void nomadik_vic_priority_mask(unsigned int irq)
-+{
-+      u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
-+      u32 mask = 1UL<<irq%32;
-+      /*
-+       * Reading the VIC_VAR register updates the interrupt controllers
-+       * hardware priority register to mask lower priority interrupts.
-+       * reading is done in entry-macro.S
-+       */
-+      p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
-+      p_vic_register->bank[irq/32].ienc |= mask;
-+}
 +
-+static void nomadik_vic_priority_unmask(unsigned int irq)
-+{
-+      u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
-+      u32 mask = 1UL<<irq%32;
++      ldmfd sp!,{r1-r11}
++      str r1,[r0,#0x12C]
++      str r2,[r0,#0x130]
++      str r3,[r0,#0x134]
++      str r4,[r0,#0x138]
++      str r5,[r0,#0x13C]
++      str r6,[r0,#0x200]
++      str r7,[r0,#0x204]
++      str r8,[r0,#0x208]
++      str r9,[r0,#0x20C]
++      str r10,[r0,#0x210]
++      str r11,[r0,#0x214]
 +
-+      p_vic_register->vcr[priority_level] |= VIC_VECTORED_IRQ_EN;
-+      p_vic_register->bank[irq/32].iens |= mask;
-+      /*
-+       * Write to the VIC_VAR register.
-+       * This clears the respective interrupt in the internal interrupt
-+       * priority hardware.
-+       */
-+      p_vic_register->isr_var = (u32)NULL;
-+}
 +
-+static struct irq_chip nomadik_vic_priority_chip = {
-+      .ack = nomadik_vic_priority_mask,
-+      .mask = nomadik_vic_priority_mask,
-+      .unmask = nomadik_vic_priority_unmask,
-+      .set_type = nomadik_vic_set_type
-+};
 +
-+static void nomadik_vic_mask(unsigned int irq)
-+{
-+      u32 mask = 1UL<<irq%32;
-+      p_vic_register->bank[irq/32].ienc |= mask;
-+}
++      ldmfd sp!,{r1-r11}
++      str r1,[r0,#0x100]
++      str r2,[r0,#0x104]
++      str r3,[r0,#0x108]
++      str r4,[r0,#0x10C]
++      str r5,[r0,#0x110]
++      str r6,[r0,#0x114]
++      str r7,[r0,#0x118]
++      str r8,[r0,#0x11C]
++      str r9,[r0,#0x120]
++      str r10,[r0,#0x124]
++      str r11,[r0,#0x128]
 +
-+static void nomadik_vic_unmask(unsigned int irq)
-+{
-+      u32 mask = 1UL<<irq%32;
-+      p_vic_register->bank[irq/32].iens |= mask;
-+}
++      ldmfd sp!, {r1-r5}
++      str r1, [r0,#0xC]       /* Interrupt sslection register */
++      str r2, [r0, #0x2C]
++      str r3, [r0, #0x10]     /* Interrupt Enable register */
++      str r4, [r0, #0x30]
++      str r5, [r0, #0x54]     /* Default VAR */
 +
-+static struct irq_chip nomadik_vic_chip = {
-+      .ack = nomadik_vic_mask,
-+      .mask = nomadik_vic_mask,
-+      .unmask = nomadik_vic_unmask,
-+      .set_type = nomadik_vic_set_type
-+};
 +
-+/**
-+ * nomadik_vic_set_type - To enable/disable/change priority logic
-+ *
-+ * callback function for set_irq_type sys call 
-+ * This function will be called in the context of request_irq.
-+ * This function is used to configure the interrupt priotity requested
-+ * through request_irq sytem call
-+ *
-+ * This function can be invoked by set_irq_type sys call ,using which 
-+ * you can enable/disable/change preprogrammed priority 
-+ *
-+ * Note: this function will NOT be invoked if interrupt is requested as
-+ * shared irq (i.e. SA_SHIRQ is specifed during requerst_irq), 
-+ */
-+static int nomadik_vic_set_type(unsigned int irq, unsigned int type)
-+{
-+      struct irq_desc *desc;
-+      struct irq_chip *vic_chip;
-+      unsigned long flags;
 +
-+      u8 priority_level;
++      /*Clean entire DCache using test and clean*/
++clean_dcache_end:
++      mrc p15,0,r15,c7,c14,3
++      bne clean_dcache_end
 +
-+      nmdk_dbg_ftrace();
-+      if (!irq_desc[irq].action) return(-1); /*if irq not configured*/
-+      /*
-+       * Priority logic does not work for interrupt configured with
-+       * SA_TIMER flag, hence exit if SA_TIMER flag is set for irq
-+       */
-+      if (irq_desc[irq].action->flags & IRQF_TIMER) return(-1);
-+      if ((type & SA_NMDK_PRIORITYIRQ) != SA_NMDK_PRIORITYIRQ) return(-1);    
-+      /*
-+       * if this function is invoked by set_irq_type call
-+       * then store input type as flags
-+       */
-+      if (type > SA_TRIGGER_MASK) irq_desc[irq].action->flags = type;
-+      /*process irq priority configuration*/
-+      priority_level = (u8)(((irq_desc[irq].action->flags)>>24) & 0x0f);
-+      if (p_vic_register->vcr[priority_level] & VIC_VECTORED_IRQ_EN) {
-+              nmdk_info("priority change for active irq%d", irq);
-+      }
-+      /*configure vic for vectored priority interrupt request*/
-+      p_vic_register->var[priority_level] = irq;
-+      p_vic_register->vcr[priority_level] = irq;
-+      /* configure appropriate chip pointer*/
-+      desc = irq_desc + irq;
-+      if (!priority_level) {
-+              p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
-+              vic_chip = &nomadik_vic_chip;
-+      } else 
-+              vic_chip = &nomadik_vic_priority_chip;
-+      spin_lock_irqsave(&vic_lock, flags);
-+      desc->chip = vic_chip;
-+      spin_unlock_irqrestore(&vic_lock, flags);
 +
-+      nmdk_info("Configured PL%2d for irq%d", priority_level, irq);
-+      return (0);
-+}
++      /* Invalidate I cache and Dcache */
++      mov r0,#0
++      mcr p15,0,r0,c7,c7,0
 +
-+static void nomadik_vic_configure(unsigned int irq)
-+{
-+      u32 mask = 1UL<<irq%32;
++      /*Drain Write Buffers*/
++      mov r0,#0
++      mcr p15,0,r0,c7,c10,4
 +
-+      nmdk_dbg("%s for irq %d", __FUNCTION__, irq);
-+      /* Select interrupt line as Irq (no FIQ used currently)*/
-+      p_vic_register->bank[irq/32].isel &= ~mask;
-+}
++      mov r0,#0
++      mcr     p15, 0, r0, c8, c7, 0           @ invalidate I & D TLBs
 +
-+void __init nomadik_vic_init(void)
-+{
-+      unsigned int i;
++      mov r0,#0
++      mov r0,#0
++      mov r0,#0
++      mov r0,#0
 +
-+      nmdk_dbg_ftrace();
-+      /*force default isr value to zero*/
-+      p_vic_register->isr_dvar = (u32)NULL;
-+      for (i = 0; i < MAX_CHIP_IRQ; i++) {
-+              if (1ULL<<i & IRQ_CONF) {
-+                      nomadik_vic_configure(i);
-+                      set_irq_chip(i, &nomadik_vic_chip);
-+                      set_irq_handler(i, handle_level_irq);
-+                      set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-+              }
-+              if (i < VIC_VECTORED_IRQ_NUM) {
-+                      /*Disable all vectored interrupts */
-+                      p_vic_register->vcr[i] = (u32)NULL;     
-+                      p_vic_register->var[i] = (u32)NULL;     
-+              }
-+      }
-+      nmdk_info("Module initialized Ver("VIC_VER")");
-+}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik ../new/linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik
---- linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Kconfig-nomadik  2008-07-17 16:42:38.000000000 +0530
-@@ -0,0 +1,267 @@
-+if ARCH_NOMADIK
 +
-+# The GPIO_PIN_23 is shared between MMC and MSP0.
-+# by default this pin is used for MMC for NOMADIK_NDK15_REV2_B_03 target
-+# to use this pin for MSP it should be configured 'n'
-+config NOMADIK_NDK15_REV2_MMC
-+      bool
-+      default y if NOMADIK_NDK15_REV2_B_03
++#ifdef DEEP_SLEEP_DEBUG
++      ldr r0, =uart1_base
++      ldr r0, [r0,#0x0]
++      mov r1, #0x65
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++      mov r1, #0x66
++      str r1, [r0]
++#endif
 +
-+config NOMADIK_NDK10_CUTA
-+      bool
-+      default y if NOMADIK_NDK10_CUT_A1
 +
-+config NOMADIK_NDK10_CUTB
-+      bool
-+      default y if (NOMADIK_NDK10_CUT_B0 || NOMADIK_NDK10_CUT_B06)
++/*Try to go back also...FIQ Disabled...IRQ Disabled*/
++    ldmfd sp!,{r0-r12,pc}
 +
-+config NOMADIK_GPIO
-+      bool 
-+      default y
 +
-+config NOMADIK_ENABLE_L2CACHE
-+      bool "Enable L2 Cache controller"
-+      depends on (NOMADIK_NDK15 || NOMADIK_NHK15)
-+      default y if NOMADIK_STN8815CAS22H11
-+      select L2CACHE_ENABLE
-+      help
-+              Nomadik Chip version for this platfrom supports L2 Cache
-+              by default it is enabled, if you want to check system
-+              performanence without L2 Cache, then say no here
++uart1_phys:
++      .word 0x101FB000
++src_phys:
++      .word 0x101E0000
++backup_ram_store_phys:
++      .word 0x80010250
++mtu0_base:
++      .word 0xf01E2000
 +
-+config GPIO_PROC
-+      bool
-+      default y
-+      depends on NOMADIK_GPIO
++uart1_base:
++      .word 0xf01FB000
++src_base:
++      .word 0xf01E0000
++pmu_base:
++      .word 0xf01E9000
++fsmc_base:
++      .word 0xf0100000
++backup_ram_base_phys:
++      .word 0x80010000
++vic_base:
++      .word 0xf0140000
++mpmc_base:
++      .word 0xf0110000
++backup_ram_store:
++      .word 0x80010250
++backup_ram_base:
++      .word 0x80010000
++.end
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/dfs.S
+@@ -0,0 +1,355 @@
++/*
++ * arch/arm/mach-nomadik/sleep.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ *
++ * Low-level Nomadik DFS support
++ */
 +
-+config NOMADIK_DMA
-+      tristate "NOMADIK DMA SUPPORT"
-+      depends on ISA_DMA_API
-+      default y
-+      help
-+              Nomadik DMA low level driver for standrd DMA interface
++.align 5
++.globl dfs
 +
-+config NOMADIK_SSP
-+      tristate "NOMADIK SSP SUPPORT"
-+      depends on (NOMADIK_DMA && NOMADIK_SPI)
-+      default m
-+      help
-+              Depends on Nomadik DMA driver and SPI driver
 +
-+config NOMADIK_MSP
-+      tristate "NOMADIK MSP SUPPORT"
-+      depends on (NOMADIK_DMA && NOMADIK_SPI)
-+      default m
-+      help
-+              Depends on Nomadik DMA driver and SPI driver
-+      
-+config NOMADIK_MTU 
-+      tristate "NOMADIK MTU SUPPORT"
-+      default m
-+      help
-+              The driver offers 8 MTU units tobe used. 
-+              In case of module only MTU1 unit will be 
-+              available with 4 timers:
-+                      MTU1_T0, MTU1_T1, MTU1_T2 & MTU1_T3
-+              
-+config NOMADIK_MTU_SYSTEM_TICK
-+      bool "NOMADIK MTU SYSTEM TICK SUPPORT"
-+      depends on NOMADIK_MTU
-+      help 
-+              This will prevent the system tick to be used through MTU.
-+      default y
++dfs:
++      stmfd sp!,{r4-r12,lr}
 +
-+config NOMADIK_RTC 
-+      bool "NOMADIK RTC/RTT SUPPORT"
-+      default y
-+      help
-+              The driver offers RTC and RTT support.
-+              The RTC can be used through /dev/rtc interface for real
-+              time calculations, alarms, long delays if required
-+              If unsure say Y here. 
++      str r3,  bkup_adr_base
++      add r4, r3, #8
++      str r4,  bkup_adr
++      add r4, r3, #0x1c8
++      str r4,  bkup_data
++      add r4, r3, #0x388
++      str r4,  bkup_action
++      add r4, r3, #0x3f8
++      str r4,  bkup_size
 +
-+config NOMADIK_PM
-+      bool "NOMADIK POWER MANAGEMENT SUPPORT"
-+      depends on ( (NOMADIK_NHK15 || NOMADIK_NDK15) && NOMADIK_RTC )
-+      default y
-+      select  PM if NOMADIK_PM
-+      help
-+              Nomadik Power Management Driver
++      ldr r9, bkup_size
++      ldr r9,[r9]
++      ldr r10,bkup_adr
++      ldr r11,bkup_data
++      ldr r12,bkup_action
 +
-+config NOMADIK_SVA_INIT_MEM
-+      bool "NOMADIK SVA MEMORY at initialisation"
-+      default n
-+      help
-+              The driver uses physically contiguous memory allocated 
-+              at kernel initialisation time.
-+              If unsure say N here. 
++      mrc p15, 0, r3, c10, c0, 0      /* read the lockdown register */
++      orr r3, r3, #1                  /* set the preserved bit */
++      mcr p15, 0, r3, c10, c0, 0      /* write to the lockdown register */
 +
-+config FORCE_MAX_ZONEORDER
-+      int "Maximum zone order"
-+      default "13"
-+      help
-+        For use cases having large memory requirements choosing a 
-+        larger memory size is advised.
 +
-+config NOMADIK_SVA_MEM_SIZE
-+      int "SVA initial memory size" if NOMADIK_SVA_INIT_MEM
-+      default "4"
-+      help
-+        For use cases having large memory requirements choosing a 
-+        larger memory size is advised.
 +
-+config NOMADIK_SVA_VPIP
-+    bool "NOMADIK SVA VPIP support"
-+    default y
-+    help
-+        This enables the support for VPIP in SVA driver. This allows to 
-+        create IRP services in SVA to grab the images from sensor CCP0.
-+        Warning: This disables Ethernet & MTD devices.
-+        
-+config NOMADIK_SAA_INIT_MEM
-+      bool "NOMADIK SAA MEMORY at initialisation"
-+      default n
-+      help
-+              The SAA driver uses physically contiguous memory allocated 
-+              at kernel initialisation time.
-+              If unsure say N here. 
 +
-+#Configuration for default display setup
-+choice
-+      prompt "Default Display Type"
-+      depends on FB
-+      default FB_NOMADIK_QVGA_PORTRAIT
++      ldr r4, mpmc_base
++      mcr p15, 0, r4, c8, c7, 1
++      ldr r4, [r4]
++      mrc p15, 0, r3, c10, c0, 0
 +
-+config FB_NOMADIK_VGA
-+      bool "CLCD VGA"
 +
-+config FB_NOMADIK_CRT
-+      bool "CRT VGA"
++      ldr r4, src_base
++      mcr p15, 0, r4, c8, c7, 1
++      ldr r4, [r4]
++      mrc p15, 0, r3, c10, c0, 0
 +
-+config FB_NOMADIK_QVGA_PORTRAIT
-+      bool "CLCD QVGA Portrait"
++      ldr r4, bkup_adr_base
++      mcr p15, 0, r4, c8, c7, 1
++      ldr r4, [r4]
++      mrc p15, 0, r3, c10, c0, 0
 +
-+config FB_NOMADIK_QVGA_LANDSCAPE
-+      bool "CLCD QVGA Landscape"
 +
-+config FB_NOMADIK_WVGA
-+        bool "CLCD WVGA"
-+endchoice
++      bic r3, r3, #1                          /* clear preserve bit */
++      mcr p15, 0, r3, c10, c0, 0      /* write to the lockdown register */
 +
-+choice
-+        prompt "Default Display BPP"
-+        depends on FB
-+        default FB_NOMADIK_PANEL_24BPP_PACKED 
++      ldr r7,mpmc_base
++      ldr r8,src_base
 +
-+config FB_NOMADIK_PANEL_8BPP
-+        bool "8 BPP"
++/*
++      mov r7, #0xf0
++      lsl r7, #8
++      orr r7, r7, #0x11
++      lsl r7, #16
 +
-+config FB_NOMADIK_PANEL_16BPP
-+        bool "16 BPP"
++      mov r8, #0xf0
++      lsl r8, #8
++      orr r8, r8, #0x1e
++      lsl r8, #16
++*/
 +
-+config FB_NOMADIK_PANEL_24BPP
-+        bool "24 BPP"
 +
-+config FB_NOMADIK_PANEL_24BPP_PACKED
-+        bool "24 BPP Packed"
++      /* Prefetch certain instructions in the cache.  */
++    adr r4, cache_prefetch_start1
++      adr r5, cache_prefetch_end1
++      mvn r3,#0x1F
++      ands r4,r3,r4
++fetch_loop:
++      mcr p15, 0, r4, c7, c13,1
++      cmp r4,r5
++      addls r4, r4, #0x20
++      bls fetch_loop
 +
-+endchoice
++mov r0,r0
++mov r0,r0
++mov r0,r0
++mov r0,r0
 +
-+config FB_NOMADIK_ACCLN
-+      bool "Nomadik Graphics Acceleration"
-+      tristate
-+      depends on FB
-+      default y
-+      help
-+        enable hw accln for graphics on nomadik
 +
-+config FB_NOMADIK_PANEL_BPP
-+      int
-+      default 16 if !FB
-+      default 8 if FB_NOMADIK_PANEL_8BPP
-+      default 16 if FB_NOMADIK_PANEL_16BPP
-+      default 24 if FB_NOMADIK_PANEL_24BPP_PACKED
-+      default 32 if FB_NOMADIK_PANEL_24BPP
++cache_prefetch_start1:
 +
-+config FB_NOMADIK_PANEL_NAME
-+      string
-+      default "VGA" if !FB
-+      default "VGA" if FB_NOMADIK_VGA
-+      default "CRT" if FB_NOMADIK_CRT
-+      default "QVGA_Portrait" if FB_NOMADIK_QVGA_PORTRAIT
-+      default "QVGA_Landscape" if FB_NOMADIK_QVGA_LANDSCAPE
-+      default "WVGA" if FB_NOMADIK_WVGA
++      /**
++       *Put SDRAM in self-refresh mode
++       */
++      ldr r3,[r7, #0x20]
++      orr r3,r3,#0x04
++      str r3,[r7, #0x20]
 +
-+config FB_NOMADIK_PANEL_XRES
-+      int
-+      default 800 if FB_NOMADIK_WVGA
-+      default 640 if !FB
-+      default 640 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT)
-+      default 240 if FB_NOMADIK_QVGA_PORTRAIT
-+      default 320 if FB_NOMADIK_QVGA_LANDSCAPE
 +
-+config FB_NOMADIK_PANEL_YRES
-+      int
-+      default 480 if !FB
-+      default 480 if ( FB_NOMADIK_VGA || FB_NOMADIK_CRT || FB_NOMADIK_WVGA)
-+      default 320 if FB_NOMADIK_QVGA_PORTRAIT
-+      default 240 if FB_NOMADIK_QVGA_LANDSCAPE
++      /**
++       *Wait for SDRAM to go in self-refresh
++       */
++wait_till_selfrefresh :
++      ldr r3,[r7,#0x4]
++      and r3,r3,#0x4
++      cmp r3,#0x0
++      beq wait_till_selfrefresh
 +
-+config FB_NOMADIK_PANEL_LFMARGIN
-+      hex
-+      default 0xD6 if FB_NOMADIK_WVGA
-+      default 0x21 if !FB
-+      default 0x21 if FB_NOMADIK_VGA
-+      default 0x29 if FB_NOMADIK_CRT
-+      default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
 +
-+config FB_NOMADIK_PANEL_RTMARGIN
-+      hex
-+      default 0x27 if FB_NOMADIK_WVGA
-+      default 0x40 if !FB
-+      default 0x40 if FB_NOMADIK_VGA
-+      default 0x09 if FB_NOMADIK_CRT
-+      default 0x2f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++      /**
++       * Stop the DLL, leave SDMC on
++       */
++      ldr r3,[r7]
++      bic r3,r3,#0x2
++      str r3,[r7]
 +
-+config FB_NOMADIK_PANEL_UPRMARGIN
-+      hex
-+      default 0x22 if FB_NOMADIK_WVGA
-+      default 0x07 if !FB
-+      default 0x07 if FB_NOMADIK_VGA
-+      default 0x19 if FB_NOMADIK_CRT
-+      default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++      /**
++       *Move the system in Slow mode
++       */
++      ldr r3,[r8]
++      bic r3,r3,#0x7
++      orr r3,r3,#0x2
++      str r3,[r8]
 +
-+config FB_NOMADIK_PANEL_LWRMARGIN
-+      hex
-+      default 0xA if FB_NOMADIK_WVGA
-+      default 0x24 if !FB
-+      default 0x24 if FB_NOMADIK_VGA
-+      default 0x02 if FB_NOMADIK_CRT
-+      default 0x0f if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++wait_till_slow_mode:
++      ldr r3,[r8]
++      and r3,r3,#0x78
++      cmp r3,#0x10
++      bne wait_till_slow_mode
 +
-+config FB_NOMADIK_PANEL_HSLEN
-+      hex
-+      default 0x1 if FB_NOMADIK_WVGA
-+      default 0x40 if !FB
-+      default 0x40 if FB_NOMADIK_VGA
-+      default 0x61 if FB_NOMADIK_CRT
-+      default 0x13 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++      ldr r3,[r8]
++      bic r3,r3,#0x6000
++      orr r3,r3,r2,LSL #13
++      str r3,[r8]
 +
-+config FB_NOMADIK_PANEL_VSLEN
-+      hex
-+      default 0x1 if FB_NOMADIK_WVGA
-+      default 0x19 if !FB
-+      default 0x19 if FB_NOMADIK_VGA
-+      default 0x02 if FB_NOMADIK_CRT
-+      default 0x04 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
++      ldr r3,[r8,#0x14]
++      bic r3,r3,#0x3F00
++      bic r3,r3,#0x7
++      orr r3,r3,r0
++      orr r3,r3,r1,LSL #8
++      str r3,[r8,#0x14]
 +
-+config FB_NOMADIK_PANEL_TIM2VAL
-+      hex
-+      default 0x031f1822 if FB_NOMADIK_WVGA
-+      default 0x027f1800 if !FB
-+      default 0x027f1800 if (FB_NOMADIK_VGA)
-+      default 0x027f3800 if (FB_NOMADIK_CRT)
-+      default 0x00ef1804 if (FB_NOMADIK_QVGA_PORTRAIT || FB_NOMADIK_QVGA_LANDSCAPE)
-+#Configuration for default display setup ends here
++      /**
++       *Move the system in Normal mode
++       */
++      ldr r0,[r8, #0x0]
++      ldr r1, =0xfffffff8
++      and r0,r0,r1
++      orr r0,r0,#0x4
++      str r0,[r8, #0x0]
 +
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/l2cc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/l2cc.c
---- linux-2.6.20/arch/arm/mach-nomadik/l2cc.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/l2cc.c   2008-07-04 23:45:55.000000000 +0530
-@@ -0,0 +1,152 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/stn8815_devices.c
-+ *
-+ *  Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2, as
-+ * published by the Free Software Foundation.
-+ *
-+ *  SOC specifc drivers whcih are used as amba devices
-+ */
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/smp.h>
-+#include <linux/amba/bus.h>
-+#include <linux/amba/kmi.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/spi/spi.h>
-+#include <linux/delay.h>
-+#include <linux/amba/clcd.h>
++wait_till_normal_mode:
++      ldr r0,[r8, #0x0]
++      and r0,r0,#0x78
++      cmp r0, #0x20
++      bne wait_till_normal_mode
 +
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/dma.h>
-+#include <asm/setup.h>
-+#include <asm/param.h>
-+#include <asm/system.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/flash.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/time.h>
-+#include <asm/arch/timex.h>
-+#include <asm/arch/debug.h>
 +
++#define ACTION_WRITE  0x01
++#define ACTION_WRITE_AND      0x02
++#define ACTION_WRITE_OR       0x03
++#define ACTION_READ   0x04
++#define ACTION_POLL   0x05
++#define ACTION_POLL_AND       0x06
++#define ACTION_POLL_OR        0x07
++#define ACTION_WAIT   0x08
 +
-+#define L210_CACHE_SYNC                       0x730
-+#define L210_INV_LINE_PA              0x770
-+#define L210_INV_WAY                  0x77C
-+#define L210_CLEAN_LINE_PA            0x7B0
-+#define L210_CLEAN_LINE_IDX           0x7B8
-+#define L210_CLEAN_WAY                        0x7BC
-+#define L210_CLEAN_INV_LINE_PA                0x7F0
-+#define L210_CLEAN_INV_LINE_IDX               0x7F8
-+#define L210_CLEAN_INV_WAY            0x7FC
++/*
++      ldr r12,bkup_size
++      ldr r9,[r12]
 +
-+static void __iomem *l210_base = (void __iomem *)IO_ADDRESS(NOMADIK_L2CC_BASE);
-+static unsigned long way_size = 0x4000;
++      ldr r10,bkup_adr
++      ldr r11,bkup_data
++      ldr r12,bkup_action
++*/
 +
-+static inline void sync_writel(unsigned long val, unsigned long reg,
-+                             unsigned long complete_mask)
-+{
-+      writel(val, l210_base + reg);
-+      /* wait for the operation to complete not required for l210 controller */
-+      //while (readl(l210_base + reg) & complete_mask);
-+}
 +
-+static inline void cache_sync(void)
-+{
-+      sync_writel(0, L210_CACHE_SYNC, 1);
-+}
++      mov r8,#0x0
++loop1:
++      cmp r8,r9
++      beq end1
 +
-+static inline void cacheline_index_op(unsigned long addr, unsigned long reg)
-+{
-+      unsigned long way, index;
++      ldr r7,[r10]
++      ldr r6,[r11]
++      ldr r5,[r12]
 +
-+      for (way = 0; way < 8; way++)
-+              for (index = 0; index < way_size; index += PAGE_SIZE) {
-+                      unsigned long val = (way << 29) | index | (addr & (PAGE_SIZE - 1));
-+                      sync_writel(val, reg, 1);
-+              }
-+}
++      mov r2,r8
++      and r2,r2,#0x3
++      mov r2,r2,LSL #0x3
++      mov r5,r5,LSR r2
++      and r5,r5,#0xFF
 +
-+inline void l210_inv_all(void)
-+{
-+      /* invalidate all ways */
-+      sync_writel(0xff, L210_INV_WAY, 0xff);
-+      cache_sync();
-+}
-+EXPORT_SYMBOL(l210_inv_all);
 +
-+inline void l210_clean_all(void)
-+{
-+      /* clean all ways */
-+      sync_writel(0xff, L210_CLEAN_WAY, 0xff);
-+      cache_sync();
-+}
-+EXPORT_SYMBOL(l210_clean_all);
++      /**
++        Decide action to be taken
++       */
++      ldr r4,=ACTION_WRITE
++      cmp r5,r4
++      beq action_write
++      ldr r4,=ACTION_WRITE_AND
++      cmp r5,r4
++      beq action_write_and
++      ldr r4,=ACTION_WRITE_OR
++      cmp r5,r4
++      beq action_write_or
++      ldr r4,=ACTION_READ
++      cmp r5,r4
++      beq action_read
++      ldr r4,=ACTION_POLL
++      cmp r5,r4
++      beq action_poll
++      ldr r4,=ACTION_POLL_AND
++      cmp r5,r4
++      beq action_poll_and
++      ldr r4,=ACTION_POLL_OR
++      cmp r5,r4
++      beq action_poll_or
++      ldr r4,=ACTION_WAIT
++      cmp r5,r4
++      beq action_wait
++      b action_end
++action_write:
++#if 0
++      mov r4, #0xf0
++      lsl r4, #8
++      orr r4, #0x1f
++      lsl r4, #8
++      orr r4, #0xb0
++      lsl r4, #8
 +
-+inline void l210_flush_all(void)
-+{
-+      /* clean and invalidate all ways */
-+      sync_writel(0xff, L210_CLEAN_INV_WAY, 0xff);
-+      cache_sync();
-+}
-+EXPORT_SYMBOL(l210_flush_all);
++      mov r3, #0x73
++      str r3, [r4]
++#endif
++      str r6,[r7]
++      b action_end
++action_write_and:
 +
-+void l210_inv_range(unsigned long start, unsigned long end)
-+{
-+      l210_inv_all();
-+}
-+EXPORT_SYMBOL(l210_inv_range);
++      b action_end
++action_write_or:
++      ldr r3,[r7]
++      orr r3,r3,r6
++      str r3,[r7]
++      b action_end
++action_read:
++      ldr r3,[r7]
++      b action_end
++action_poll:
++      b action_end
++action_poll_and:
++      b action_end
++action_poll_or:
++      b action_end
++action_wait:
++      cmp r6,#0x0
++      beq action_end
++      sub r6,r6,#0x1
++      b action_wait
++action_end:
 +
-+void l210_clean_range(unsigned long start, unsigned long end)
-+{
-+      unsigned long size = end - start;
-+      unsigned long addr;
++      add r10,r10,#0x4
++      add r11,r11,#0x4
++      /**
++       * Determine if r8 is multiple of 4 and r12 must be increased
++       */
++      mov r2,r8
++      and r2,r2,#0x3
++      cmp r2,#0x3
++      bne incr8
++      add r12,r12,#0x4
++incr8:
++      add r8,r8,#0x01
++      b loop1
++end1:
 +
-+      if (size >= PAGE_SIZE) {
-+              l210_clean_all();
-+              return;
-+      }
++      mov r10, #0xf0
++      lsl r10, #8
++      orr r10, r10, #0x11
++      lsl r10, #16
 +
-+      /* no physical address information, flush by index/way */
-+      for (addr = start & ~(32 - 1); addr < end; addr += 32)
-+              cacheline_index_op(addr, L210_CLEAN_LINE_IDX);
-+      cache_sync();
-+}
-+EXPORT_SYMBOL(l210_clean_range);
 +
 +
-+void l210_flush_range(unsigned long start, unsigned long end)
-+{
-+      unsigned long addr,way,val;
 +
-+      //printk("\nl2 flushing hit\n");
-+      /* no physical address information, flush by index/way */
-+      for (addr = start & ~(32 - 1); addr < end; addr += 32)
-+              cacheline_index_op(addr, L210_CLEAN_INV_LINE_IDX);
++      ldr r1,[r10]
++      orr r1,r1,#0x2
++      str r1,[r10]
 +
-+      /*for (addr = start; addr < end; addr += 32) {
-+              for (way = 0; way < 8; way++) {
-+                      //val = (way << 29) |  ((addr & 0x1ff) << 5);
-+                      val = (way << 29) |  (addr << 5);
-+                      sync_writel(val, L220_CLEAN_INV_LINE_IDX, 1);
-+              }
-+      }*/
-+      cache_sync();
-+}
-+EXPORT_SYMBOL(l210_flush_range);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Makefile ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile
---- linux-2.6.20/arch/arm/mach-nomadik/Makefile        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile 2008-07-04 23:45:06.000000000 +0530
-@@ -0,0 +1,166 @@
-+#
-+# Makefile for the linux kernel.
-+#
++      /* Wait for the DLL to lock */
++waitlock:
++      ldr r1,[r10,#0x4]
++      and r1,r1,#0x8
++      cmp r1,#0x0
++      beq waitlock
 +
-+ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
-+include $(TOPDIR)/.config
-+endif
++      /* Exit DDR-SDRAM from self-refresh mode */
++      ldr r1,[r10, #0x20]
++      bic r1,r1,#0x04
++      str r1,[r10, #0x20]
 +
-+# Object file lists.
++      /* Wait for DDR-SDRAM to exit from self-refresh */
++loop_refresh:
++      ldr r1,[r10,#0x4]
++      and r1,r1,#0x4
++      cmp r1,#0x4
++      beq loop_refresh
 +
-+TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
-+SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
-+PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
-+NMDK_EXTRA_CFLAGS = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
 +
-+EXTRA_CFLAGS-y                        := $(NMDK_EXTRA_CFLAGS)
-+EXTRA_CFLAGS-$(CONFIG_NOMADIK_MTU)    += -DCONFIG_MTU0 
-+CFLAGS += $(EXTRA_CFLAGS-y)
++    ldmfd sp!,{r4-r12,pc}
 +
-+# NMDKDBG_FLAGS maintainence for all Nomadik debuging strategy
-+# Add new entry for new component to be supported here 
-+NMDKDBG_FLAGS := 
++mov r0,r0
++mov r0,r0
++mov r0,r0
++mov r0,r0
 +
-+ifdef VIC_DEBUG
-+NMDKDBG_FLAGS += -DVIC_DEBUG=$(VIC_DEBUG)
-+endif
++cache_prefetch_end1 :  /* This is the end of the code to be copied into eSRAM */
++mov r0,r0
++mov r0,r0
++mov r0,r0
++mov r0,r0
 +
-+ifdef RTC_DEBUG
-+NMDKDBG_FLAGS += -DRTC_DEBUG=$(RTC_DEBUG)
-+endif
++bkup_adr_base :
++      .word 0x80010000
++bkup_adr :
++      .word 0x80010008
++bkup_data :
++      .word 0x800101C8
++bkup_action :
++      .word 0x80010388
++bkup_size :
++      .word 0x800103F8
++src_base :
++      .word 0xf01E0000
++mpmc_base :
++      .word 0xf0110000
++uart1_base :
++      .word 0xf01fb000
 +
-+ifdef GPIO_DEBUG
-+NMDKDBG_FLAGS += -DGPIO_DEBUG=$(GPIO_DEBUG)
-+endif
 +
-+ifdef DMA_DEBUG
-+NMDKDBG_FLAGS += -DDMA_DEBUG=$(DMA_DEBUG)
-+endif
 +
-+ifdef EPIO_DEBUG
-+NMDKDBG_FLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG)
-+endif
 +
-+ifdef SPI_DEBUG
-+NMDKDBG_FLAGS += -DSPI_DEBUG=$(SPI_DEBUG)
-+endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/dma.c
+@@ -0,0 +1,1337 @@
++/*
++ * arch/arm/mach-nomadik/dma.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ *
++ * Nomadik DMA driver to support standard APIs.
++ * the API details can be found at ./Documentation/arm/STM-Nomadik/dma_user_guide.txt
++ *
++ * Author : Prafulla WADASKAR <prafulla.wadaskar@st.com>
++ */
++#define DMA_VER "2.1.0"
 +
-+ifdef SSP_DEBUG
-+NMDKDBG_FLAGS += -DSSP_DEBUG=$(SSP_DEBUG)
-+endif
++#include <linux/module.h>     /* module functions */
++#include <linux/slab.h>
++#include <linux/mman.h>
++#include <linux/init.h>
++#include <linux/wait.h>               /* For wait queues */
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/spinlock.h>   /* spinlocks */
++#include <linux/errno.h>      /* err nos */
++#include <linux/sched.h>      /* wait macros */
++#include <linux/mm.h>         /* GFP flags */
++#include <linux/amba/bus.h>   /* Amba device register */
++#include <linux/cpufreq.h>
++#include <asm/page.h>
++#include <asm/dma.h>
++#include <asm/fiq.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>               /* for cli etc */
++#include <asm/hardware.h>
++#include <asm/hardware/iomd.h>
++#include <asm/mach/dma.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/defs.h>
++#include <asm/arch/memory.h>
++#include <asm/arch/debug.h>
 +
-+ifdef MSP_DEBUG
-+NMDKDBG_FLAGS += -DMSP_DEBUG=$(MSP_DEBUG)
-+endif
++#define DMA_NAME              "DMA"
 +
-+ifdef KEYPAD_DEBUG
-+NMDKDBG_FLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG)
-+endif
++#ifndef DMA_DEBUG
++#define DMA_DEBUG 0
++#endif
 +
-+ifdef TOUCHP_DEBUG
-+NMDKDBG_FLAGS += -DTOUCHP_DEBUG=$(TOUCHP_DEBUG)
-+endif
++#define NMDK_DEBUG    DMA_DEBUG       /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  DMA_NAME      /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+ifdef POWER_DEBUG
-+NMDKDBG_FLAGS += -DPOWER_DEBUG=$(POWER_DEBUG)
-+endif
++/* Macros used to identify standard dma structure elements for Nomadik implimentation*/
++#define dmaconfig_pipeadr(x)  ((x)->dma_base)
 +
-+ifdef PM_DEBUG
-+NMDKDBG_FLAGS += -DPM_DEBUG=$(PM_DEBUG)
-+endif
++#define dmaconfig_defconfig(x)        ((x)->buf.page)
++#define dmaconfig_config(x)   ((x)->buf.offset)
++#define dmaconfig_usrconfig(x)        ((x)->buf.dma_address)
++#define dmaconfig_mode(x)     ((x)->buf.length)
 +
-+ifdef CPUFREQ_DEBUG
-+NMDKDBG_FLAGS += -DCPUFREQ_DEBUG=$(CPUFREQ_DEBUG)
-+endif
++#define dmaconfig_srcadr(x)   ((x)->cur_sg.dma_address)
++#define dmaconfig_destadr(x)  ((x)->cur_sg.length)
 +
-+ifdef SLEEP_DEBUG
-+NMDKDBG_FLAGS += -DSLEEP_DEBUG=$(SLEEP_DEBUG)
-+endif
-+
-+ifdef SVA_DEBUG
-+NMDKDBG_FLAGS += -DSVA_DEBUG=$(SVA_DEBUG)
-+endif
-+#export the nomadik debug flags for driver/* build
-+CFLAGS += $(NMDKDBG_FLAGS)
-+
-+obj-y := gpio.o clock.o timer.o irq.o fsmc.o
-+
-+obj-y += $(SOC_NAME)_devices.o  
-+obj-y += $(PLATFORM_NAME)_devices.o  
-+
-+# Soc Specific modules
-+
-+obj-$(CONFIG_NOMADIK_PM)      += sleep.o deep_sleep.o soft_sleep.o  normal.o slow.o pm.o  
-+
-+ifeq ($(CONFIG_NOMADIK_PM),y)
-+obj-y += power.o
-+endif
-+
-+ifeq ($(CONFIG_L2CACHE_ENABLE),y)
-+obj-y += l2cc.o
-+endif
-+ifeq ($(CONFIG_CPU_FREQ_NOMADIK),y)
-+obj-y += power.o slow.o
-+endif
-+
-+obj-$(CONFIG_CPU_FREQ_NOMADIK)        += cpu.o dfs.o 
-+obj-$(CONFIG_NOMADIK_DMA)       += nmdkmod_DMA.o
-+obj-$(CONFIG_NOMADIK_SSP)       += nmdkmod_ssp.o
-+obj-$(CONFIG_NOMADIK_MSP)     += nmdkmod_msp.o
-+obj-$(CONFIG_NOMADIK_MTU)     += nmdkmod_mtu.o
-+obj-$(CONFIG_NOMADIK_RTC)     += nmdkmod_rtc.o
-+
-+nmdkmod_gpio-objs             := gpio.o
-+nmdkmod_DMA-objs      := dma.o 
-+nmdkmod_ssp-objs              := ssp.o 
-+nmdkmod_msp-objs      := msp.o 
-+nmdkmod_mtu-objs      := mtu.o
-+nmdkmod_rtc-objs      := rtc.o
-+
-+# Auto board configuration/dependency resolution
-+#include $(TOPDIR)/.config
-+
-+SOC_HEADER  = include/asm-arm/arch-nomadik/soc_devices.h
-+PDEV_HEADER = include/asm-arm/arch-nomadik/board_devices.h
-+
-+$(TOPDIR)/.platform:
-+      $(Q)echo "Generating $@"
-+      $(Q)echo $(CONFIG_NOMADIK_PLATFORM) > $@
-+
-+$(TOPDIR)/.soc:
-+      $(Q)echo "Generating $@"
-+      $(Q)echo $(CONFIG_NOMADIK_SOC) > $@
-+
-+$(TOPDIR)/.target:
-+      $(Q)echo "Generating $@"
-+      $(Q)echo $(CONFIG_NOMADIK_TARGET) > $@
-+
-+$(TOPDIR)/$(PDEV_HEADER):
-+      $(Q)echo "Generating SYMLINK $(PDEV_HEADER) -> $(PLATFORM_NAME)_devices.h"
-+      $(Q)rm -rf $@
-+      $(Q)ln -s $(PLATFORM_NAME)_devices.h $@
-+
-+$(TOPDIR)/$(SOC_HEADER):
-+      $(Q)echo "Generating SYMLINK $(SOC_HEADER) -> $(SOC_NAME)_devices.h"
-+      $(Q)rm -rf $@
-+      $(Q)ln -s $(SOC_NAME)_devices.h $@
-+
-+# machprepare kjhsdk dfsdf
-+machprepare: $(TOPDIR)/.platform $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/$(SOC_HEADER)
-+
-+# machprepare kjhsdk j
-+machclean:
-+      $(Q)rm -rf *mod.o *.mod.c *.o *.ko  
-+
-+machmrproper:
-+      $(Q)rm -rf $(TOPDIR)/$(SOC_HEADER) $(TOPDIR)/$(PDEV_HEADER) $(TOPDIR)/arch/arm/mach-nomadik/Kconfig $(TOPDIR)/.soc $(TOPDIR)/.target $(TOPDIR)/.platform
-+
-+#This will resolve any machin specific dependency for configuration
-+#This will generate Kconfig file if not present
-+machconfig:
-+ifneq ($(wildcard $(TOPDIR)/arch/arm/mach-nomadik/Kconfig), $(TOPDIR)/arch/arm/mach-nomadik/Kconfig)
-+      @echo "Generating $(TOPDIR)/arch/arm/mach-nomadik/Kconfig"
-+      @./create_kconfig.pl $(TOPDIR)/arch/arm/mach-nomadik
-+endif 
-+
-+# end of Auto board configuration/dependency resolution
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot
---- linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/Makefile.boot    2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,4 @@
-+   zreladdr-y := 0x00008000
-+params_phys-y := 0x00000100
-+initrd_phys-y := 0x00800000
-+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/msp.c ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.c
---- linux-2.6.20/arch/arm/mach-nomadik/msp.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.c    2008-11-19 16:47:02.000000000 +0530
-@@ -0,0 +1,2062 @@
 +/*
-+ *  Driver for Nomadik STN8810/STN8815 MSP device.
-+ *
-+ *  Copyright 2006 STMicroelectronics Pvt. Ltd.
-+ *
-+ *  This program is free sofstware; 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.
-+ *
++ * Constants used for DMA channel priority processing
 + */
++#define QUEUE_ID 0x80
++#define POLICY_CHECK_END 0xff
++const u8 policy_mem2mem[10] ={15,14,13,12,
++                      QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
++                      POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_undefined[34] ={11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,
++                      QUEUE_ID+11,QUEUE_ID+10,QUEUE_ID+9,QUEUE_ID+8,
++                      QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
++                      QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
++                      QUEUE_ID+15,QUEUE_ID+14,QUEUE_ID+13,QUEUE_ID+12,
++                      POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_high[34] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
++                      QUEUE_ID+0,QUEUE_ID+1,QUEUE_ID+2,QUEUE_ID+3,
++                      QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
++                      QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
++                      QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
++                      POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_normal[34] ={4,5,6,7,8,9,10,11,3,2,1,0,12,13,14,15,
++                      QUEUE_ID+4,QUEUE_ID+5,QUEUE_ID+6,QUEUE_ID+7,
++                      QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
++                      QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
++                      QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
++                      POLICY_CHECK_END, POLICY_CHECK_END};
++const u8 policy_low[34] ={8,9,10,11,7,6,5,4,3,2,1,0,12,13,14,15,
++                      QUEUE_ID+8,QUEUE_ID+9,QUEUE_ID+10,QUEUE_ID+11,
++                      QUEUE_ID+7,QUEUE_ID+6,QUEUE_ID+5,QUEUE_ID+4,
++                      QUEUE_ID+3,QUEUE_ID+2,QUEUE_ID+1,QUEUE_ID+0,
++                      QUEUE_ID+12,QUEUE_ID+13,QUEUE_ID+14,QUEUE_ID+15,
++                      POLICY_CHECK_END, POLICY_CHECK_END};
 +
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+#include <linux/wait.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/amba/bus.h>
-+#include <linux/delay.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/delay.h>
-+#include <asm/irq.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/defs.h>
-+#include <asm/arch/debug.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/arch/gpio.h>
-+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+#include <asm/arch/spi.h>
-+#include <asm/arch/msp-spi.h>
-+#endif
-+
-+#include <asm/arch/msp.h>
-+
-+#include "msp.h"
-+
-+#ifndef MSP_DEBUG
-+#define MSP_DEBUG 0
-+#endif
-+
-+#define NMDK_MSP_NAME         "NOMADIK_MSP"
-+
-+#define NMDK_DEBUG    MSP_DEBUG       /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  NMDK_MSP_NAME /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
-+
-+char MSP_NAME[] = "msp";
-+
-+static volatile struct msp_register *registers[MSP_COUNT] = {
-+      (struct msp_register *)IO_ADDRESS(NOMADIK_MSP0_BASE),
-+#if MSP_COUNT > 1
-+      (struct msp_register *)IO_ADDRESS(NOMADIK_MSP1_BASE),
-+#endif
-+#if MSP_COUNT > 2
-+      (struct msp_register *)IO_ADDRESS(NOMADIK_MSP2_BASE),
-+#endif
-+};
-+
-+static int altfunc[MSP_COUNT] = {
-+      GPIO_ALT_MSP_0,
-+#if MSP_COUNT > 1
-+      GPIO_ALT_MSP_1,
-+#endif
-+#if MSP_COUNT > 2
-+      GPIO_ALT_MSP_2,
-+#endif
-+};
-+static int msp_irq = IRQ_MSP0;
-+
-+static wait_queue_head_t wait[MSP_COUNT];
-+static volatile int msp_io_error[MSP_COUNT];
 +
-+static struct msp_context msp_context[MSP_COUNT];
++static char dmach_name[MAX_DMA_CHANNELS * MAX_DMA_CHNAME_SIZE];
++static struct dma_soc_data *socdat;
++static struct dmach_lli *p_lli_pipe[MAX_DMA_HWCHANNELS];
++struct dmach_lli *lli_ptr_log = NULL;
++struct dmach_lli *lli_ptr_phy = NULL;
++#define nomadik_dma_lli_phy_to_logical(x)     ((struct dmach_lli *)((u32)(x + (lli_ptr_log - lli_ptr_phy)) & ~0x01))
 +
-+static struct msp_mode_status tx_status[MSP_COUNT];
-+static struct msp_mode_status rx_status[MSP_COUNT];
++#define nomadik_dmach_is_active_n_enabled(x) (x & 0x00020001)
++#define nomadik_dma_is_pipe_busy(pipe)                (p_lli_pipe[pipe])
++#define nomadik_dma_mark_pipe_busy(pipe)      (p_lli_pipe[pipe] = (void *)0xffffffff)
 +
-+static u32 input_clock[MSP_COUNT];
-+static u32 spi_clock_mode[MSP_COUNT];
-+static u32 spi_burst_mode[MSP_COUNT];
++/**
++ * nomadik_dma_channel_of_pipe - To get dma channel irq for provided pipe address
++ * @pipeadr: pipe address w.r.to which channel irq needs for foundout
++ *
++ * finds the pipe number assoicated with channel
++ * if any transfer is already scheduled on a pipe, returns the channel irq of scheduled DMA
++ * if pipe is free, returns null
++ */
++static int nomadik_dma_channel_of_pipe(struct dmach_register *pipeadr)
++{
++      u32 pipe;
++      struct dma_struct * dma;
 +
-+/*Usage Flag for MSPs*/
-+msp_flag *flag_msp0, *flag_msp1, *flag_msp2;
++      pipe= (((u32)pipeadr & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
++      if ((u32 *)pipeadr > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
++      if (p_lli_pipe[pipe]) {
++              if (p_lli_pipe[pipe]->mem2.dma) {
++                      dma = p_lli_pipe[pipe]->mem2.dma;
++                      return dma->dma_irq;
++              } else return 0;
++      }
++      return 0;
++}
 +
-+static const struct msp_protocol_desc protocol_desc_tab[] =   /* Protocol desciptors */
++/**
++ * nomadik_dma_allocate_llis - Allocates requested number of LLIs
++ * @count: No of LLI buffers requested
++ *
++ * reserves the requested number of llis from internal lli poolf
++ * link them with DMAble LLI addresses so that can be used directly by DMA h/w
++ * return the point of first lli
++ */
++static struct dmach_lli *nomadik_dma_allocate_llis(u32 count)
 +{
-+      I2S_PROTOCOL_DESC,
-+      /*  PCM_PROTOCOL_DESC */
-+      {
-+       MSP_SINGLE_PHASE,
-+       MSP_FRAME_LENGTH_1,
-+       MSP_FRAME_LENGTH_1,
-+       MSP_ELEM_LENGTH_16,
-+       MSP_ELEM_LENGTH_16,
-+       /*below three settings are platform specific */
-+       MSP_DATA_DELAY,
-+       MSP_TX_CLOCK_EDGE,
-+       MSP_RX_CLOCK_EDGE},
-+      PCM_COMPAND_PROTOCOL_DESC,
-+      AC97_PROTOCOL_DESC,
-+      SPI_MASTER_PROTOCOL_DESC,
-+      SPI_SLAVE_PROTOCOL_DESC
-+};
-+/* local functions */
-+static irqreturn_t handle_irq(int irq, void *dev_id);
-+static int transmit_data(int msp, void *data, size_t bytes);
-+static int receive_data(int msp, void *data, size_t bytes);
-+static int transmit_receive_data(int msp, int work_mode,
-+                               void *txdata, size_t txbytes, void *rxdata,
-+                               size_t rxbytes);
-+static int configure_clock(int msp, int protocol, u32 input_clock,
-+                         u32 frame_freq, int frame_size);
-+static int configure_protocol(int msp, int protocol, int direction,
-+                            enum msp_data_size data_size);
++      struct dmach_lli *p_lli = lli_ptr_log;
++      struct dmach_lli *p_lli_phy = lli_ptr_phy;
++      struct dmach_lli *p_lli_phylast = (struct dmach_lli *)0x01;
++      unsigned long flags;
 +
++      nmdk_dbg_ftrace();
++      if (!(p_lli) || !(count)) return (struct dmach_lli *)NULL;
++      if (count > MAX_DMA_LLIS) return (struct dmach_lli *)NULL;
++      flags = claim_dma_lock();
++      do {
++              if (p_lli == (lli_ptr_log + MAX_DMA_LLIS-2)) {
++                      nmdk_error("unable to find free lli.. rechecking...");
++                      p_lli = lli_ptr_log;
++                      p_lli_phy = lli_ptr_phy;
++              }
++              p_lli++; p_lli_phy++;
++              if (!(p_lli->mem3.next)) {
++                      p_lli->mem3.next = p_lli_phylast;
++                      count--;
++                      p_lli_phylast = (struct dmach_lli *)((u32)p_lli_phy + 0x01);
++              }
++      } while (count);
++      release_dma_lock(flags);
++      return p_lli;
++}
 +
 +/**
-+ * nomadik_msp_configure - configures the MSP controller
-+ * @msp - specifies the msp controller to configure.
-+ * @config - specifies the configuration parameters.
++ * nomadik_dma_deallocate_llis - deallocates/frees the provided lli list
++ * @p_lli: pointer to the first lli
++ *
++ * frees all llis in the provided lli list
 + */
-+int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user)
++static void nomadik_dma_deallocate_llis(struct dmach_lli *p_lli)
 +{
-+      u32 old_reg;
-+      u32 new_reg;
-+      u32 mask;
-+      int status = 0;
-+
-+      if (msp < 0 || msp > MSP_COUNT) {
-+              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+              return -EINVAL;
-+      }
-+      nmdk_dbg("In nomadik_msp_configure, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
-+      nmdk_dbg("In nomadik_msp_configure, flag_msp1 is %d\n", flag_msp1->user);
-+      nmdk_dbg("In nomadik_msp_configure, flag_msp2 is %d\n", flag_msp2->user);
++      struct dmach_lli *p_lli_bkup;
 +
-+      switch(msp) {
-+              case 0: if((flag_msp0->user != MSP_NO_USER) && (flag_msp0->user != user)){
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP0 already in use in %d mode", flag_msp0->user);
-+                      }
-+                      else {
-+                              down(&flag_msp0->lock);
-+                              flag_msp0->user = user;
-+                              up(&flag_msp0->lock);
-+                      }
-+                      break;
-+              case 1: if((flag_msp1->user != MSP_NO_USER) && (flag_msp1->user != user)){
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP1 already in use in %d mode", flag_msp1->user);
-+                      }
-+                      else {
-+                              down(&flag_msp1->lock);
-+                              flag_msp1->user = user;
-+                              up(&flag_msp1->lock);
-+                      }
-+                      break;
-+              case 2: if((flag_msp2->user != MSP_NO_USER) && (flag_msp2->user != user)){
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP2 already in use in %d mode", flag_msp2->user);
-+                      }
-+                      else
-+                              down(&flag_msp2->lock);
-+                              flag_msp2->user = user;
-+                              up(&flag_msp2->lock);
++      nmdk_dbg_ftrace();
++      while (p_lli) {
++              if (!(p_lli)) break;
++              if (!(p_lli->mem3.next)) break;
++              if ((u32)p_lli->mem3.next == 0x01) {
++                      p_lli->mem3.next = (struct dmach_lli *)NULL;
 +                      break;
++              }
++              p_lli_bkup = nomadik_dma_lli_phy_to_logical(p_lli->mem3.next);
++              p_lli->mem3.next = (struct dmach_lli *)NULL;
++              p_lli = p_lli_bkup;
 +      }
-+      if(status) {
-+              printk(KERN_ERR "Error in setting flag bit for MSP\n");
-+              return status;
-+      }
-+
-+      /* First do the global config register */
-+      mask =
-+          RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FRAME_SYNC_MASK |
-+          TX_FRAME_SYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
-+          RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK;
-+
-+      new_reg =
-+          (config->tx_clock_sel | config->rx_clock_sel | config->
-+           rx_frame_sync_pol | config->tx_frame_sync_pol | config->
-+           rx_frame_sync_sel | config->tx_frame_sync_sel | config->
-+           rx_fifo_config | config->tx_fifo_config | config->srg_clock_sel);
-+
-+      old_reg = (registers[msp]->global_ctrl);
-+      old_reg &= ~mask;
-+      old_reg |= new_reg;
-+      (registers[msp]->global_ctrl) = old_reg;
-+
-+      /* Now do the tx_config and rx_config registers */
-+      old_reg = registers[msp]->rx_config;
-+      mask = MSP_NON_MODE_BIT_MASK;
-+      new_reg = config->rx_endianess | config->rx_unexpect_frame_sync;
-+      old_reg &= ~mask;
-+      old_reg |= new_reg;
-+      (registers[msp]->rx_config) = old_reg;
-+      old_reg = registers[msp]->tx_config;
-+      new_reg = config->tx_endianess | config->tx_unexpect_frame_sync;
-+      old_reg &= ~mask;
-+      old_reg |= new_reg;
-+      (registers[msp]->tx_config) = old_reg;
-+
-+      /* Set global input clock and spi clock mode, needed by other config ops */
-+
-+      input_clock[msp] = config->input_clock_freq;
-+      spi_clock_mode[msp] = config->spi_clk_mode;
-+      spi_burst_mode[msp] = config->spi_burst_mode;
-+      return 0;
 +}
 +
 +/**
-+ * nomadik_msp_enable - Enable the msp controller with given configuration
-+ * @msp - specifies the msp controller
-+ * @direction - specifies the transmit/receive direction
-+ * @work_mode - specifies DMA/Interrupt/Polling mode
-+ * @protocol - Either PCM/I2S
-+ * @frame_freq - specifies the frequency.
-+ * @frame_size - specifies frame size
-+ * @data_size -  specifies element size
++ * nomadik_dma_schedule_xfer_on_pipe - Schedules DMA transfer lli on a pipe
++ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
++ * @p_lli: pointer to the lli to be scheduled
++ *
++ * finds out the pipe no associated with a pipe
++ * checkes whether pipe is free or busy
++ * if free then
++ *    Configures the pipe with LLI data
++ *    clears any pending interrupt on a pipe
++ *    marks pipe as busy
++ *    Enables DMA to strat transfer
++ * if pipe is busy then
++ *    queues the lli on the pipe
 + */
-+int nomadik_msp_enable(int msp, int direction, int work_mode, int protocol,
-+                     int frame_freq, int frame_size,
-+                     enum msp_data_size data_size, t_msp_user user)
++static void nomadik_dma_schedule_xfer_on_pipe(volatile struct dmach_register *p_pipe, struct dmach_lli *p_lli)
 +{
-+      int status = 0;
-+      int skip_irq;
-+      if (msp < 0 || msp > MSP_COUNT) {
-+              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+              return -EINVAL;
-+      }
-+
-+      nmdk_dbg("In nomadik_msp_enable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
-+      switch(msp) {
-+              case 0: if(flag_msp0->user != user) {
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP0 not usable in Non SPI mode\n");
-+                      }
-+                      break;
-+              case 1: if(flag_msp1->user != user) {
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP1 not usable in Non SPI mode\n");
-+                      }
-+                      break;
-+              case 2: if(flag_msp2->user != user) {
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP2 not usable in Non SPI mode\n");
-+                      }
-+                      break;
-+      }
-+      if(status) {
-+              printk(KERN_ERR "Error in setting flag bit for MSP, status is %d\n", status);
-+              return status;
-+      }
++      u32 pipe, i;
++      struct dmach_lli *p_lli_hw, *p_lli_curr;
++      volatile struct dma_register *p_dma_reg;
 +
-+      skip_irq = (registers[msp]->global_ctrl) & (TX_ENABLE | RX_ENABLE);
++      nmdk_dbg_ftrace();
++      i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
++      pipe = i*2;
++      if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
 +
-+      if(!skip_irq) {
-+              switch (msp) {
-+                      case 0:
-+                              status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_0");
-+                              break;
-+                      case 1:
-+                              status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_1");
-+                              break;
-+                      case 2:
-+                              status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_2");
-+                              break;
-+              }
-+              if (status) {
-+                      printk(KERN_ERR "Error in nomadik_gpio_altfuncenable, status is %d\n", status);
-+                      return status;
++      p_lli->mem1.p_lli_qh = (struct dmach_lli *)NULL; /*Marked this lli as last in queue*/
++      p_lli_curr = p_lli_pipe[pipe];
++      mb();
++      if ((p_lli_curr != (void*)0xffffffff) && (p_lli_curr != NULL) ) {
++              while (p_lli_curr->mem1.p_lli_qh) {
++                      nmdk_dbg2("currlli(%p) next_lli (%p)", p_lli_curr, p_lli_curr->mem1.p_lli_qh);
++                      p_lli_curr = p_lli_curr->mem1.p_lli_qh; /*go thr lli headers to point last lli head */
 +              }
++              p_lli_curr->mem1.p_lli_qh = p_lli;
++              nmdk_dbg2("lli(%p) is queued on PIPE %d at %p", p_lli, pipe, p_lli_curr);
++      } else {
++              /* clear any pending interrupt on this pipe if any */
++              p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
++              p_dma_reg->tcicr |= 1UL<<i;
++              p_dma_reg->eicr |= 1UL<<i;
++              nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
++
++              /* program pipe for a transfer*/
++              p_lli_pipe[pipe] = p_lli;
++              p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
++              p_pipe->sadr = p_lli_hw->mem1.sadr;
++              p_pipe->dadr = p_lli_hw->mem2.dadr;
++              p_pipe->lli = p_lli_hw->mem3.next;
++              p_pipe->cr = p_lli_hw->mem4.cr;
++              nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
++                      (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
++              mb();
++              p_pipe->cfg = p_lli->mem4.cfg;
 +      }
++}
 +
-+      /* Store context data for power management */
-+      msp_context[msp].direction = direction;
-+      msp_context[msp].mode = work_mode;
-+      msp_context[msp].protocol = protocol;
-+      msp_context[msp].frame_freq = frame_freq;
-+      msp_context[msp].frame_size = frame_size;
-+      msp_context[msp].requested_data_size = data_size;
++/**
++ * nomadik_dma_free_procesed_pipe - Frees processed LLI on a pipe
++ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
++ *
++ * finds out the pipe no associated with a pipe
++ * checkes whether pipe is free or busy, if free then just returns
++ * frees the allocated llis for a pipe
++ * checks whether any transfer is queued on a pipe
++ * if the queue is not empty then
++ *    Configures queues lli as current lli
++ *    Configures the pipe with LLI data
++ *    clears any pending interrupt on a pipe
++ *    marks pipe as busy
++ *    Enables DMA to strat transfer
++ * if the queue is empty then
++ *    marks the pipe as free if not reserved by requesting DMA Channel
++ *    otherwise marks the pipe as free
++ */
++static void nomadik_dma_free_procesed_pipe(volatile struct dmach_register *p_pipe)
++{
++      u32 pipe;
++      struct dmach_lli *p_lli;
++      dma_t *dma;
++      struct dmach_lli *p_lli_hw;
++      volatile struct dma_register *p_dma_reg;
++      u32 i;
 +
-+      /* Configure msp with protocol dependent settings */
-+      configure_protocol(msp, protocol, direction, data_size);
++      nmdk_dbg_ftrace();
++      i= (((u32)p_pipe & 0x0fff) - 0x0100)/sizeof(struct dmach_register);
++      pipe = i*2;
++      if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
 +
-+      configure_clock(msp, protocol, input_clock[msp], frame_freq,
-+                      frame_size);
++      /* free lli of processed pipe*/
++      if ((p_lli_pipe[pipe] != (void *)0xffffffff) && (p_lli_pipe[pipe] != NULL) ) {
++              dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
++              p_lli = p_lli_pipe[pipe]->mem1.p_lli_qh;
++              nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
++              mb();
++              if (p_lli) {
++                      /* clear any pending interrupt on this pipe if any */
++                      p_dma_reg = (void *)((u32)p_pipe & 0xffff0000);
++                      /*p_dma_reg->tcicr |= 1UL<<i;*/
++                      p_dma_reg->eicr |= 1UL<<i;
++                      nmdk_dbg2("previous interrupt cleaned(%p) intno %d", p_dma_reg, i);
 +
-+      switch (direction) {
-+      case MSP_TRANSMIT_MODE:
-+              registers[msp]->irq_mask |= TRANSMIT_UNDERRUN_ERR_INT;
-+              if (work_mode == MSP_DMA_MODE) {
-+                      registers[msp]->dma_ctrl |= TX_DMA_ENABLE;
-+              }
++                      /* program pipe for a transfer*/
++                      p_lli_pipe[pipe] = p_lli;
++                      p_lli_hw = nomadik_dma_lli_phy_to_logical(p_lli->mem3.p_lli_hw);
++                      p_pipe->sadr = p_lli_hw->mem1.sadr;
++                      p_pipe->dadr = p_lli_hw->mem2.dadr;
++                      p_pipe->lli = p_lli_hw->mem3.next;
++                      p_pipe->cr = p_lli_hw->mem4.cr;
++                      nmdk_dbg2("lli (%p) dmach(%p) sadr(%08x) dadr(%08x) lli(%p) cr(%08x)", p_lli, p_pipe,
++                              (u32)p_pipe->sadr, (u32)p_pipe->dadr, p_pipe->lli, (u32)p_lli_hw->mem4.cr);
++                      mb();
++                      p_pipe->cfg = p_lli->mem4.cfg;
 +
-+              tx_status[msp].work_mode = work_mode;
-+              if (protocol == MSP_I2S_PROTOCOL) {
-+                      tx_status[msp].stereo_mode = MSP_STEREO;
++                      nmdk_dbg2("Scheduling queued transfer on pipe %d (lli(%p))", pipe,
++                              p_lli_pipe[pipe]);
 +              } else {
-+                      tx_status[msp].stereo_mode = MSP_MONO;
-+              }
-+
-+              (registers[msp]->global_ctrl) &= ~RX_ENABLE;
-+              (registers[msp]->global_ctrl) |= TX_ENABLE;
-+              break;
-+      case MSP_RECEIVE_MODE:
-+              registers[msp]->irq_mask |= RECEIVE_OVERRUN_ERROR_INT;
-+              if (work_mode == MSP_DMA_MODE) {
-+                      registers[msp]->dma_ctrl |= RX_DMA_ENABLE;
++                      if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
++                              p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
++                      else {
++                              p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
++                              dmaconfig_pipeadr(dma) = (u32)0;
++                      }
 +              }
++      }
++}
 +
-+              rx_status[msp].work_mode = work_mode;
-+              if (protocol == MSP_I2S_PROTOCOL) {
-+                      rx_status[msp].stereo_mode = MSP_STEREO;
-+              } else {
-+                      rx_status[msp].stereo_mode = MSP_MONO;
-+              }
++/* removes all allocated requests on the pipe */
++/**
++ * nomadik_dma_flush_pipe - Removes all scheduled and queued transfers on a pipe
++ * @p_pipe: pointer to a pipe on which DMA transfer to be scheduled
++ *
++ * finds out the pipe no associated with a pipe
++ * stops current transfer
++ * traverse through lli heads and flush all queued llis including scheduled one
++ * marks the pipe as free
++ */
++static void nomadik_dma_flush_pipe(volatile struct dmach_register *p_pipe)
++{
++      u32 pipe;
++      struct dmach_lli *p_lli_qh = (struct dmach_lli *)NULL;
++      dma_t *dma;
 +
-+              (registers[msp]->global_ctrl) |= RX_ENABLE;
-+              (registers[msp]->global_ctrl) &= ~TX_ENABLE;
-+              break;
-+      case MSP_BOTH_T_R_MODE:
-+              registers[msp]->irq_mask |=
-+                  TRANSMIT_UNDERRUN_ERR_INT | RECEIVE_OVERRUN_ERROR_INT;
-+              if (work_mode == MSP_DMA_MODE) {
-+                      registers[msp]->dma_ctrl |=
-+                          TX_DMA_ENABLE | RX_DMA_ENABLE;
-+              }
++      nmdk_dbg_ftrace();
++      pipe= (((u32)p_pipe & 0x0fff) - 0x0100)*2/sizeof(struct dmach_register);
++      if ((u32 *)p_pipe > (u32 *)socdat->dirqdesc[IRQ_DMA1].chip_data) pipe++;
 +
-+              tx_status[msp].work_mode = work_mode;
-+              rx_status[msp].work_mode = work_mode;
-+              if (protocol == MSP_I2S_PROTOCOL) {
-+                      tx_status[msp].stereo_mode = MSP_STEREO;
-+                      rx_status[msp].stereo_mode = MSP_STEREO;
-+              } else {
-+                      tx_status[msp].stereo_mode = MSP_MONO;
-+                      rx_status[msp].stereo_mode = MSP_MONO;
-+              }
++      if ((u32)p_lli_pipe[pipe] == 0xffffffff) goto nextt;
++      while (p_lli_pipe[pipe] != 0) {
++              dma = (dma_t *)p_lli_pipe[pipe]->mem2.dma;
++              p_lli_qh = p_lli_pipe[pipe]->mem1.p_lli_qh;
++              nomadik_dma_deallocate_llis(p_lli_pipe[pipe]);
++              p_lli_pipe[pipe] = p_lli_qh;
++              nmdk_dbg2("Flushed lli (%p) for pipe %d", p_lli_pipe[pipe], pipe);
++      };
++      nextt:
++//    if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED)
++//            p_lli_pipe[pipe] = (struct dmach_lli *)0xffffffff;
++//    else
++              p_lli_pipe[pipe] = (struct dmach_lli *)NULL;
++}
 +
-+              (registers[msp]->global_ctrl) |= RX_ENABLE;
-+              (registers[msp]->global_ctrl) |= TX_ENABLE;
-+              break;
-+      default:
-+              printk(KERN_ERR "Invalid direction parameter\n");
-+              return -EINVAL;
++/**
++ * nomadik_dma_check_update_userconfig - updates config as per user configs
++ * @dma: DMA channel structure pointer
++ *
++ * checks the user configuration
++ * if some use configuration is provided by clinet driver during
++ * configuration then abstracts it and updates Channel configuration
++ * data accordingly
++ */
++static void nomadik_dma_check_update_userconfig(dma_t *dma)
++{
++      nmdk_dbg_ftrace();
++      if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_BSIZE_CONFIGURED) {
++              dmaconfig_config(dma) &= ~(DMA_BSIZE_256);
++              dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_BSIZE_256);
 +      }
-+
-+      /* enable frame generation logic */
-+      (registers[msp]->global_ctrl) |= FRAME_GEN_ENABLE;
-+      msp_context[msp].msp_disable = 0;
-+      if (!skip_irq) {
-+              status = request_irq(msp_irq, handle_irq,
-+                                   SA_INTERRUPT | SA_SHIRQ, MSP_NAME,
-+                                   (void *)registers[msp]);
-+      if(status)
-+              printk(KERN_ERR "Error while request_irq, err is %d\n", status);
++      if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_BSIZE_CONFIGURED) {
++              dmaconfig_config(dma) &= ~(DMA_BSIZE_256<<3);
++              dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_BSIZE_256<<3);
 +      }
-+      return status;
++      if ((u32)dmaconfig_usrconfig(dma) & DMA_SRC_WIDTH_CONFIGURED) {
++              dmaconfig_config(dma) &= ~(DMA_WIDTH_NA);
++              dmaconfig_config(dma) |= ((u32)dmaconfig_usrconfig(dma) & DMA_WIDTH_NA);
++      }
++      if ((u32)dmaconfig_usrconfig(dma) & DMA_DEST_WIDTH_CONFIGURED) {
++              dmaconfig_config(dma) &= ~(DMA_WIDTH_NA<<3);
++              dmaconfig_config(dma) |= (u32)dmaconfig_usrconfig(dma) & (DMA_WIDTH_NA<<3);
++      }
++      nmdk_dbg("usrconfig =%08x, config = %08x", (u32)dmaconfig_usrconfig(dma), (u32)dmaconfig_config(dma));
 +}
 +
-+void nomadik_msp_flush_input(int msp)
++/**
++ * nomadik_dma_usrdevconfig - updates user configuration as per type
++ * @config: user configuration information
++ * @type: src or destincation peripharal indicator (0= means src)
++ *
++ * checks provided configuration and returns configuration converting
++ * it for soruce or destination peripharal. this API is provided to
++ * facilitate and mistake proffing the configuration by client driver
++ */
++u32 __nomadik_dma_usrdevconfig(u32 config, int type)
 +{
-+      u32 dummy;
-+      while (!(registers[msp]->status & RX_FIFO_EMPTY)) {
-+              dummy = registers[msp]->fifo;
++      u32 val =0;
++      if (type == 0) { /*src*/
++              if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
++                      val |= DMA_SRC_BSIZE_CONFIGURED;
++                      val |= (config & DMA_BSIZE_256);
++              }
++              if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
++                      val |= DMA_SRC_WIDTH_CONFIGURED;
++                      val |= (config & DMA_WIDTH_NA);
++              }
++      } else { /*dest*/
++              if (config & DMA_DEV_BSIZE_CONFIGURABLE) {
++                      val |= DMA_DEST_BSIZE_CONFIGURED;
++                      val |= (config & DMA_BSIZE_256)<<3;
++              }
++              if (config & DMA_DEV_WIDTH_CONFIGURABLE) {
++                      val |= DMA_DEST_WIDTH_CONFIGURED;
++                      val |= (config & DMA_WIDTH_NA)<<3;
++              }
 +      }
++      return (val);
 +}
++EXPORT_SYMBOL(__nomadik_dma_usrdevconfig);
 +
-+int nomadik_msp_send_data(int msp, void *data, size_t bytes)
++/**
++ * nomadik_dmach_configure - configures DMA Channel processing default and user configuration
++ * @srcdmadev: name of srouce DMAble device IP
++ * @destdmadev: name of dest DMAble device IP
++ * @dma: DMA channel data structure pointer
++ *
++ * finds out the defult configuration for src and dest devices scanning the config_tbl
++ * prepares DMA configuration from default config of src and dest dmadevices and user
++ * configuration
++ * return 0 on cusess, negative value on failure
++ */
++static int nomadik_dmach_configure(char *src_dmadev, char *dest_dmadev, dma_t *dma)
 +{
-+      int status;
-+
-+      if (msp < 0 || msp > MSP_COUNT) {
-+              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+              return -EINVAL;
-+      }
++      int i;
++      uint8 flag =0;
 +
-+      if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
-+              printk(KERN_ERR
-+                     "Trying to transmit with transmit not enabled\n");
-+              return -EPERM;
-+      }
++      nmdk_dbg_ftrace();
++      dmaconfig_config(dma) = 0;
 +
-+      switch (tx_status[msp].work_mode) {
-+      case MSP_DMA_MODE:
-+              printk(KERN_WARNING "Function not authorized in DMA mode\n");
-+              return -ENOSYS;
-+              break;
-+      case MSP_POLLING_MODE:
-+      case MSP_INTERRUPT_MODE:
-+              status = transmit_data(msp, data, bytes);
-+              break;
-+      default:
-+              printk(KERN_ERR "tx work mode invalid: %d\n",
-+                     tx_status[msp].work_mode);
-+              return -EINVAL;
-+              break;
++      for (i=0; i < socdat->config_tbl_size; i++) {
++              if (!(strcmp (src_dmadev, (socdat->config_tbl[i].id)))) {
++                      dmaconfig_config(dma) |= (u32) (socdat->config_tbl[i].config &
++                              (DMA_AHB_M1 | DMA_DEV_BOTH_DMACS_CANBE_USED | DMA_ADR_INC |
++                               DMA_WIDTH_NA | DMA_BSIZE_256 |
++                               DMA_REQUEST_LINE(31)));
++                      flag |=0x01;
++              }
++              if (!(strcmp(dest_dmadev,(socdat->config_tbl[i].id)))) {
++                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config
++                                                       & DMA_DEV_BOTH_DMACS_CANBE_USED)<<2));
++                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_AHB_M1)<<1));
++                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_ADR_INC)<<1)); /*DI bit*/
++                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_WIDTH_NA)<<3));
++                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_BSIZE_256)<<3));
++                      dmaconfig_config(dma) |= (u32)(((socdat->config_tbl[i].config & DMA_REQUEST_LINE(31))<<5));
++                      flag |=0x02;
++              }
++              if ((flag & 0x03) == 0x03) {
++                      nomadik_dma_check_update_userconfig(dma);
++                      nmdk_dbg("conf(%08x), mode=%08x", dmaconfig_config(dma), dmaconfig_mode(dma));
++                      return(0);
++              }
 +      }
-+
-+      return status;
++      nmdk_error("unable to configure dmachanel");
++      return(-1);
 +}
 +
-+int nomadik_msp_receive_data(int msp, void *data, size_t bytes)
++/**
++ * nomadik_dma_find_dmahwpipe - Finds and returns free and compatible DMA pipe
++ * @dma: DMA channel data structure pointer
++ *
++ * searches a free pipe as per channel priority policy manager
++ * (refer ./Documentation//arm/STM-Nomadik/dma_user_guide.txt)
++ * checks the configuration for the pipe suitability for transfer
++ * selects the pipe and mark it as busy
++ * returns pipe address if selected
++ * returns NULL in case of unavailability of pipe
++ */
++static struct dmach_register *nomadik_dma_find_dmahwpipe(dma_t *dma)
 +{
-+      int status;
++      int i;
++      u8 *p_pipe;
++      volatile struct dmach_register *p_dmach_reg;
++      volatile struct dma_register *p_dma_reg;
++      unsigned long flags;
 +
-+      if (msp < 0 || msp > MSP_COUNT) {
-+              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+              return -EINVAL;
-+      }
++      nmdk_dbg_ftrace();
 +
-+      if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
-+              printk(KERN_ERR "Trying to receive with receive not enabled\n");
-+              return -EPERM;
++      flags = claim_dma_lock();
++      /* channel priority setup */
++      if ( MEM_TO_MEM == (u32)dmaconfig_mode(dma)) {
++              p_pipe = (void *)policy_mem2mem;
 +      }
-+
-+      switch (rx_status[msp].work_mode) {
-+      case MSP_DMA_MODE:
-+              printk(KERN_WARNING "Function not authorized in DMA mode\n");
-+              return -ENOSYS;
-+              break;
-+      case MSP_POLLING_MODE:
-+      case MSP_INTERRUPT_MODE:
-+              status = receive_data(msp, data, bytes);
-+              break;
-+      default:
-+              printk(KERN_ERR "rx work mode invalid: %d\n",
-+                     rx_status[msp].work_mode);
-+              return -EINVAL;
-+              break;
++      else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_HIGH) {
++              p_pipe = (void *)policy_high;
 +      }
-+
-+      return status;
++      else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_NORMAL) {
++              p_pipe = (void *)policy_normal;
++      }
++      else if ( (u32)dmaconfig_mode(dma) & DMA_EXCH_PRIORITY_LOW) {
++              p_pipe = (void *)policy_low;
++      }
++      else { /* DMA_EXCH_PRIORITY_UNDEFINED) */
++              p_pipe = (void *)policy_undefined;
++      }
++      do {
++              i = *p_pipe & ~QUEUE_ID;
++              /** Advanced Pipe selection strategy, under development */
++              /* skip if pipe is busy and not requested on queued pipe */
++              if (nomadik_dma_is_pipe_busy(i) && (!(*p_pipe & QUEUE_ID))) continue;
++              /* skip if pipe is busy with infinite dma xfer */
++              if (nomadik_dma_is_pipe_busy(i) &&
++                   ((dmaconfig_config((dma_t *)p_lli_pipe[i]->mem2.dma)) & DMA_INFINITE_XFER)) continue;
++              if (i & 0x01) {
++                      if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)))
++                               != (DMA_DEV_DMAC1_CANBE_USED | (DMA_DEV_DMAC1_CANBE_USED<<2)) ) continue;
++                      p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA1].chip_data;
++              } else {
++                      if (((u32)dmaconfig_config(dma) & (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)))
++                               != (DMA_DEV_DMAC0_CANBE_USED | (DMA_DEV_DMAC0_CANBE_USED<<2)) ) continue;
++                      p_dma_reg = (struct dma_register *)socdat->dirqdesc[IRQ_DMA0].chip_data;
++              }
++              p_dmach_reg = (struct dmach_register *)&p_dma_reg->dmach[i/2];
++              nomadik_dma_mark_pipe_busy(*p_pipe & ~QUEUE_ID);
++              nmdk_dbg("DMAHW PIPE%d assigned for Dma Channel %d",i, DMACH_FOR_IRQNO(dma->dma_irq));
++              release_dma_lock(flags);
++              return (void *)p_dmach_reg;
++      } while ((*(++p_pipe)) != POLICY_CHECK_END);
++      release_dma_lock(flags);
++      nmdk_error("All HW DMA Chanels busy...");
++      return NULL;
 +}
 +
-+int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
-+                              void *rxdata, size_t rxbytes)
++/**
++ * nomadik_dma_req - low level method for request_dma API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Check for configuration is passed by client
++ * prepares basic channel configuration from dma info provided by client
++ * generate dmach id string from src and dest dmadevtypes
++ * find and reserved a pipe in case of reserved mode requested by client
++ * returns NULL in case of sucess, negative value in case for failure
++ */
++static int nomadik_dma_req(dmach_t channel, dma_t *dma)
 +{
-+      int status;
++      struct nmdk_dma_info *dma_info =
++              (struct nmdk_dma_info *)dma->device_id;
++      int error;
 +
-+      if (msp < 0 || msp > MSP_COUNT) {
-+              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+              return -EINVAL;
-+      }
++      nmdk_dbg_ftrace();
 +
-+      if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
-+              printk(KERN_ERR "Trying to receive with receive not enabled\n");
-+              return -EPERM;
++      if (! dma->device_id) {
++              nmdk_error("nmdk_dma_info structptr not passed");
++              return (-DMA_CONFIG_INFO_NOT_PASSED);
 +      }
 +
-+      if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
-+              printk(KERN_ERR
-+                     "Trying to transmit with transmit not enabled\n");
-+              return -EPERM;
-+      }
++      dmaconfig_mode(dma) = (u32)dma_info->mode;
++      dmaconfig_usrconfig(dma) = (u32)dma_info->config;
 +
-+      if (tx_status[msp].work_mode != rx_status[msp].work_mode) {
-+              printk(KERN_ERR "Inconsistent transmit/reveive modes\n");
-+              return -EINVAL;
++      /* Prepare dmach configuration form dma_info*/
++      switch((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
++              case MEM_TO_MEM:
++                      dma_info->srcdevtype = "mem";
++                      dma_info->destdevtype = "mem";
++                      break;
++              case FLOW_CNTRL_PERIPH(MEM_TO_PERIPH):
++              case MEM_TO_PERIPH:
++                      dma_info->srcdevtype = "mem";
++                      break;
++              case FLOW_CNTRL_PERIPH(PERIPH_TO_MEM):
++              case PERIPH_TO_MEM:
++                      dma_info->destdevtype = "mem";
++                      break;
++              case FLOW_CNTRL_SRC_PERIPH(PERIPH_TO_PERIPH):
++              case FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH):
++              case PERIPH_TO_PERIPH:
++                      break;
++              default:
++                      nmdk_error("Invalid DMA mode");
++                      error =-1;
++                      goto err_exit;
 +      }
 +
-+      switch (tx_status[msp].work_mode) {
-+      case MSP_DMA_MODE:
-+              printk(KERN_WARNING "Function not authorized in DMA mode\n");
-+              return -ENOSYS;
-+              break;
-+      case MSP_POLLING_MODE:
-+      case MSP_INTERRUPT_MODE:
-+              status = transmit_receive_data(msp, tx_status[msp].work_mode,
-+                                             txdata, txbytes,
-+                                             rxdata, rxbytes);
-+              break;
-+      default:
-+              printk(KERN_ERR "work mode invalid: %d\n",
-+                     tx_status[msp].work_mode);
-+              return -EINVAL;
-+              break;
++      if (! dma_info->srcdevtype) {
++              nmdk_error("srcdevtype not specified");
++              error =-DMA_SRC_DEVICE_NOT_CONFIGURED;
++              goto err_exit;
++      }
++      if (! dma_info->destdevtype) {
++              nmdk_error("destdevtype not specified");
++              error =-DMA_DEST_DEVICE_NOT_CONFIGURED;
++              goto err_exit;
 +      }
++      error = nomadik_dmach_configure(dma_info->srcdevtype, dma_info->destdevtype, dma);
++      if (error) goto err_exit;
 +
-+      return status;
-+}
++      /* generate dmach id string from src and dest dmadevtypes */
++      sprintf(dmach_name + (channel * MAX_DMA_CHNAME_SIZE ),
++              "dmaclbk-%s->%s", dma_info->srcdevtype, dma_info->destdevtype);
++      dma->device_id = dmach_name + (channel * MAX_DMA_CHNAME_SIZE) + 8;
 +
-+static int nomadik_msp_wait_for_tx_complete(int msp)
-+{
-+      while (!(registers[msp]->status & TX_FIFO_EMPTY));
-+      return 0;
++      if ((u32)dmaconfig_mode(dma) & DMA_PIPE_RESERVED) {
++              dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
++              if ((u32)dmaconfig_pipeadr(dma)) {
++                      nmdk_dbg("pipe (%p) reserved for channel %d",
++                      (void *)dmaconfig_pipeadr(dma), channel);
++              } else {
++                      nmdk_error("could not reserve dmach hw pipe");
++                      error =-1;
++                      goto err_exit;
++              }
++      } else  dmaconfig_pipeadr(dma) = (u32)NULL;
++      dma->state = NMDK_DMA_CONFIGURED;
++      return(0);
++
++  err_exit:
++      return(error);
 +}
 +
 +/**
-+ * nomadik_msp_disable - disable the given msp controller
-+ * @msp - specifies the msp contoller
-+ * @direction - specifies the transmit/receive direction
++ * nomadik_dma_en - low level method for enable_dma API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Checks for channel configured properly
++ * allocates llis for transfer
++ * programm llis for transfer data
++ * checks if the pipe is already available with channel
++ * if not the find and allocates a free pipe for a transfer
++ * program dmach irqname if not set by client
++ * schedules a transfer on a pipe
 + */
-+int nomadik_msp_disable(int msp, int direction, t_msp_user user)
++static void nomadik_dma_en(dmach_t channel, dma_t *dma)
 +{
-+      int status = 0;
-+      if (msp < 0 || msp > MSP_COUNT) {
-+              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
-+              return -EINVAL;
++      struct dmach_lli *p_lli_start = (struct dmach_lli *)NULL;
++      struct dmach_lli *p_lli_curr;
++      struct dmach_lli *p_lli_next;
++
++      unsigned long flags;
++      u32 dmacnt, dmacnt_chkval, tmpcnt;
++
++      nmdk_dbg_ftrace();
++
++/*    if (dma->invalid) {
++              if (dma->mode) {
++                      if (((u32)dmaconfig_mode(dma) & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH) ==
++                          (dma->mode & FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH)) {
++                              dmaconfig_mode(dma) = (u32)dma->mode;
++                      }
++              }
++      } else {
++        exit_invl_parms:
++              nmdk_error("enable request without parameters");
++              goto exit_en
 +      }
++      if (dma->addr) dmaconfig_srcadr(x) = dma->addr;
++      if (dma->speed) dmaconfig_destadr(x) = (u32)dma->speed;
++*/
 +
-+      nmdk_dbg("In nomadik_msp_disable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
-+      /*Set global flag to free state*/
-+      switch(msp) {
-+              case 0: if(flag_msp0->user == user) {
-+                                              down(&flag_msp0->lock);
-+                                              flag_msp0->user = MSP_NO_USER;
-+                                              up(&flag_msp0->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP0\n");
-+                                      }
-+                                      else {
-+                                              nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp0->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+              case 1: if(flag_msp1->user == user) {
-+                                              down(&flag_msp1->lock);
-+                                              flag_msp1->user = MSP_NO_USER;
-+                                              up(&flag_msp1->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP1\n");
-+                                      }
-+                                      else {
-+                                              nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp1->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+              case 2: if(flag_msp2->user == user) {
-+                                              down(&flag_msp2->lock);
-+                                              flag_msp2->user = MSP_NO_USER;
-+                                              up(&flag_msp2->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP2\n");
-+                                      }
-+                                      else {
-+                                              nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp2->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
++      if (!(dma->sg)) {
++              if (!(dma->addr)) {
++                      nmdk_error("srcadr not set");
++                      goto exit_en;
++              }
++              if (!(dma->speed)) {
++                      nmdk_error("destadr not set");
++                      goto exit_en;
++              }
 +      }
-+      if(status)
-+              return status;
 +
-+      if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
-+              goto disable_alt;
-+      }
++      /*set transfer size = count/src_width */
++      dmacnt = dma->count/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
++      nmdk_dbg("total count = %d, dma count =%d",(u32)dma->count, dmacnt);
++      tmpcnt = 0;
++      dmacnt_chkval = 0x0ff0;
 +
-+      if (direction != MSP_RECEIVE_MODE) {
-+              int status = nomadik_msp_wait_for_tx_complete(msp);
-+              if (status) {
-+                  goto disable_alt;
++      if (dma->sg) {
++              /*Scatter gather list implimentation */
++              if (dma->sgcount == 0) {
++                      nmdk_error("Empty scatter gather list");
++                      goto exit_en;
 +              }
-+      }
-+      switch (direction) {
-+      case MSP_RECEIVE_MODE:
-+              registers[msp]->global_ctrl &= ~RX_ENABLE;
-+              registers[msp]->dma_ctrl &= ~RX_DMA_ENABLE;
-+              registers[msp]->irq_mask &= ~(RECEIVE_SERVICE_INT |
-+                                            RECEIVE_OVERRUN_ERROR_INT);
-+              rx_status[msp].flow_error_count = 0;
-+              break;
-+      case MSP_TRANSMIT_MODE:
-+              registers[msp]->global_ctrl &= ~TX_ENABLE;
-+              registers[msp]->dma_ctrl &= ~TX_DMA_ENABLE;
-+              registers[msp]->irq_mask &= ~(TRANSMIT_SERVICE_INT |
-+                                            TRANSMIT_UNDERRUN_ERR_INT);
-+              tx_status[msp].flow_error_count = 0;
-+              break;
-+      case MSP_BOTH_T_R_MODE:
-+              registers[msp]->global_ctrl &= ~(TX_ENABLE | RX_ENABLE);
-+              registers[msp]->dma_ctrl &= ~(TX_DMA_ENABLE | RX_DMA_ENABLE);
-+              registers[msp]->irq_mask &= ~ALL_INT;
-+              tx_status[msp].flow_error_count = 0;
-+              rx_status[msp].flow_error_count = 0;
-+              break;
-+      default:
-+              printk(KERN_ERR "Invalid direction param\n");
-+              status = -EINVAL;
-+              goto disable_alt;
-+      }
++              if ((((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_MEM ) ||
++                       (((u32)dmaconfig_mode(dma) & 0x03) == PERIPH_TO_PERIPH )) {
++                      nmdk_error("Unsupported mode for scatter gather");
++                      goto exit_en;
++              }
++              p_lli_start = nomadik_dma_allocate_llis(dma->sgcount +1);
++              p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
++#ifdef SCATERGATHER_MMC_DEBUG
++              if (dma->sgcount > 1) {
++                      dmaconfig_config(dma) |= 0x0f0007fe;
++                      nmdk_dbg("sc_count=%d , config=%08x", dma->sgcount, dmaconfig_config(dma));
++                      if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
++                              printk("===%p", dma_alloc_coherent( NULL , 4096, &dma->speed, GFP_DMA | GFP_KERNEL ));
 +
-+      msp_context[msp].msp_disable = 1;
++                      } else {
++                              printk("==%p",dma_alloc_coherent( NULL , 4096, &dma->addr, GFP_DMA | GFP_KERNEL ));
++                      }
++                      dmaconfig_mode(dma) = 0;
++              }
++#endif
++              tmpcnt = dma->count;
++              while (dma->sgcount) {
++                      nmdk_dbg("tmpcnt %d, sg_len %d", tmpcnt, dma->sg->length);
++                      p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
++                      if (!(dma->sg->dma_address)) {
++                              nmdk_error("sg list not dma mapped");
++                              goto exit_en;
++                      }
++                      if (((u32)dmaconfig_mode(dma) & 0x03) == MEM_TO_PERIPH ) {
++                              p_lli_curr->mem1.sadr = dma->sg->dma_address;
++                              if (!(dma->speed)) {
++                                      nmdk_error("destadr not set");
++                                      goto exit_en;
++                              }
++                              p_lli_curr->mem2.dadr = (dma_addr_t)dma->speed;
++                      } else {
++                              if (!(dma->addr)) {
++                                      nmdk_error("srcadr not set");
++                                      goto exit_en;
++                              }
++                              p_lli_curr->mem1.sadr = (dma_addr_t)dma->addr;
++                              p_lli_curr->mem2.dadr = dma->sg->dma_address;
++                      }
++                      if (tmpcnt > dma->sg->length) {
++                              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++                                        (dma->sg->length/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
++                      } else {
++                              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++                                        (tmpcnt/(((u32)dmaconfig_config(dma) & 0x000c0000)>>17)));
++                      }
++                      tmpcnt -= dma->sg->length;
++                      dma->sgcount--; dma->sg++;
++                      if (dma->sgcount == 0) p_lli_curr->mem4.cr |= (1<<31);
++                      p_lli_curr = p_lli_next;
++              }
++      } else if ((u32)dmaconfig_mode(dma) & DMA_DOUBLE_BUFFERED ) {
++              p_lli_start = nomadik_dma_allocate_llis(3);
++              p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
++              p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
 +
-+      if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
-+              /* disable sample rate and frame generators */
-+              registers[msp]->global_ctrl &= ~(FRAME_GEN_ENABLE | SRG_ENABLE);
++              dmacnt /= 2;
++              dmacnt_chkval = dmacnt;
++              /*fill next lli structure */
++              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) | dmacnt_chkval);
++              p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
++              p_lli_curr->mem2.dadr = dma->speed;
++              p_lli_next->mem4.cr = p_lli_curr->mem4.cr;
++              p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
++              p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
++              if (p_lli_next->mem4.cr & DMA_ADR_INC) p_lli_next->mem1.sadr += dma->count/2;
++              if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1)) p_lli_next->mem2.dadr += dma->count/2;
 +
-+              free_irq(msp_irq, (void *)registers[msp]);
-+      }
++              if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
++                      p_lli_next->mem3.next = p_lli_start->mem3.p_lli_hw;
++              } else {
++                      p_lli_next->mem4.cr |= (1<<31);
++              }
++      } /*mode & DMA_DOUBLE_BUFFERED*/
++      else {
++              tmpcnt = dmacnt/dmacnt_chkval;
++              p_lli_start = nomadik_dma_allocate_llis(tmpcnt + 2);
++              p_lli_curr = nomadik_dma_lli_phy_to_logical(p_lli_start->mem3.p_lli_hw);
++              p_lli_next = p_lli_curr;
 +
++              p_lli_curr->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++                               ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
++              dmacnt -= dmacnt_chkval;
++              p_lli_curr->mem1.sadr = (unsigned int)dma->addr;
++              p_lli_curr->mem2.dadr = dma->speed;
++              while(tmpcnt) {
++                      p_lli_next = nomadik_dma_lli_phy_to_logical(p_lli_curr->mem3.next);
++                      /*fill next lli structure */
++                      p_lli_next->mem4.cr = (((u32)dmaconfig_config(dma) & 0x0ffff000) |
++                                       ((dmacnt < dmacnt_chkval)?dmacnt:dmacnt_chkval));
++                      p_lli_next->mem1.sadr = p_lli_curr->mem1.sadr;
++                      p_lli_next->mem2.dadr = p_lli_curr->mem2.dadr;
++                      if (p_lli_next->mem4.cr & DMA_ADR_INC)
++                              p_lli_next->mem1.sadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
++                      if (p_lli_next->mem4.cr & (DMA_ADR_INC<<1))
++                              p_lli_next->mem2.dadr += dmacnt_chkval *(((u32)dmaconfig_config(dma) & 0x000c0000)>>17);
 +
-+disable_alt:
-+              switch (msp) {
-+                      case 0:
-+                              nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_0");
-+                              break;
-+                      case 1:
-+                              nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_1");
-+                              break;
-+                      case 2:
-+                              nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_2");
-+                              break;
++                      p_lli_curr = p_lli_next;
++                      dmacnt -= dmacnt_chkval;
++                      tmpcnt--;
++              }
++              p_lli_curr->mem4.cr |= (1<<31);
++              if ((u32)dmaconfig_mode(dma) & DMA_INFINITE_XFER) {
++                      p_lli_curr->mem3.next = p_lli_start->mem3.p_lli_hw;
++              } else {
++                      p_lli_curr->mem4.cr |= (1<<31);
 +              }
++      }
++      nmdk_dbg("lli_start(%p)", p_lli_start);
++      p_lli_start->mem2.dma = (void *)dma;                                    /*dma associated with this lii*/
++      p_lli_start->mem4.cfg = (((u32)dmaconfig_config(dma) & 0x000007fe) | /* set src/dest dma periph request line numbers */
++                         ((u32)dmaconfig_mode(dma)<<11 & (7<<11)) |   /* set flow control and xter type*/
++                         (0x0000c001));                       /*enable interrupts and start xfer*/
 +
-+      return status;
++      /* if channel is reserved use predefined hwpipe else find free
++       * h/w pipe to schedule dma
++       * if h/w pipe is not available the que the request
++       */
++      if (!((u32)dmaconfig_pipeadr(dma))) {
++              dmaconfig_pipeadr(dma) = (u32)nomadik_dma_find_dmahwpipe(dma);
++              if (dmaconfig_pipeadr(dma)) {
++                      nmdk_dbg("channel %d allocated pipe p_dmach_reg(%p) ",channel, (void *)dmaconfig_pipeadr(dma));
++              } else {
++                      nmdk_error("enable requested aborted...No pipe available...");
++                      goto exit_en;
++              }
++      }
++      /* program dmach irqname if not set by client */
++      if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
++              if (!(socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name))
++                      socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->name =
++                              (dmach_name + (channel * MAX_DMA_CHNAME_SIZE));
++
++      mb();
++      flags = claim_dma_lock();
++      nomadik_dma_schedule_xfer_on_pipe((void *)dmaconfig_pipeadr(dma), p_lli_start);
++      release_dma_lock(flags);
++      dma->state = NMDK_DMA_ENABLED;
++      if ((u32)dmaconfig_mode(dma) & DMA_QUEUE_ENABLED) dma->active = 0;
++      return;
++
++exit_en:
++      if (p_lli_start) nomadik_dma_deallocate_llis(p_lli_start);
++      return;
 +}
 +
-+static int configure_protocol(int msp, int protocol, int direction,
-+                            enum msp_data_size data_size)
++/**
++ * nomadik_dma_dis - low level method for disable_dma API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * disables a transfer on a pipe if associated with a requested channel
++ */
++static void nomadik_dma_dis(dmach_t channel, dma_t *dma)
 +{
-+      u32 temp_reg;
++      struct dmach_register *p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++      unsigned long flags;
 +
-+      if ((protocol < 0) || (protocol >= MSP_INVALID_PROTOCOL)) {
-+              printk(KERN_ERR
-+                     "invalid protocol requested in configure_protocol()\n");
-+              return -EINVAL;
-+      }
++      nmdk_dbg_ftrace();
 +
-+      if (data_size < MSP_DATA_SIZE_DEFAULT
-+          || data_size > MSP_DATA_SIZE_32BIT) {
-+              printk(KERN_ERR
-+                     "invalid data size requested in configure_protocol()\n");
-+              return -EINVAL;
-+      }
++      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
++      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++      flags = claim_dma_lock();
++      nmdk_dbg("Channel %d disabled on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++      p_dmach_reg->cfg &= ~0x0000c001;
++      release_dma_lock(flags);
++      dma->state = NMDK_DMA_DISABLED;
++}
 +
-+      switch (direction) {
-+      case MSP_TRANSMIT_MODE:
-+              tx_status[msp].phase_mode =
-+                  protocol_desc_tab[protocol].phase_mode;
++static void nomadik_dma_fr(dmach_t channel, dma_t *dma)
++{
++      nmdk_dbg_ftrace();
++      nomadik_dma_dis(channel, dma);
++      if (socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action)
++              free_irq(IRQNO_FOR_DMACH(channel), socdat->dirqdesc[IRQNO_FOR_DMACH(channel)].action->dev_id);
++      if (dmaconfig_pipeadr(dma)) nomadik_dma_flush_pipe((void *)dmaconfig_pipeadr(dma));
++}
 +
-+              /* Use a temp for setup. Clear everything except the two non-mode
-+               * dependent bits, then add back the bits for the selected protocol
-+               */
-+              temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
++/* find the available dma chanel and requests the same */
++/**
++ * request_available_dma - Wrapper over request_dma API
++ * @dmach_config_info: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Wrapper over request_dma API for free and available DMA channel search
++ * returns DMA Channel number , negative error value in case of failure
++ */
++int request_available_dma(struct nmdk_dma_info * dmach_config_info)
++{
++      dmach_t channel;
++      int error;
 +
-+              temp_reg |=
-+                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+              temp_reg |=
-+                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_1);
-+              temp_reg |=
-+                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_2);
-+              if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+                      temp_reg |=
-+                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_1);
-+                      temp_reg |=
-+                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_2);
-+                      if (protocol_desc_tab[protocol].element_len_1 ==
-+                          protocol_desc_tab[protocol].element_len_2) {
-+                              msp_context[msp].actual_data_size =
-+                                  protocol_desc_tab[protocol].element_len_1;
-+                      } else {
-+                              msp_context[msp].actual_data_size = data_size;
-+                      }
++      /*removed locks as detected by spinlock debugging on*/
++      for (channel = 0; channel < (MAX_DMA_CHANNELS - 1); channel++) {
++              error = request_dma(channel, (char *)dmach_config_info);
++              if (-EBUSY == error) continue;
++              if (error < 0) {
++                      nmdk_error("Request DMA error");
++                      return error;
 +              } else {
-+                      temp_reg |= msp_p1_elem_len_bits(data_size);
-+                      temp_reg |= msp_p2_elem_len_bits(data_size);
-+                      msp_context[msp].actual_data_size = data_size;
++                      nmdk_dbg("Dma Chanel %d is available and allocated", channel);
++                      return channel;
 +              }
-+              temp_reg |=
-+                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
-+
-+              (registers[msp]->tx_config) = temp_reg;
-+
-+              /* The tx_config register is done, now set the clock mode (rising
-+               * or falling edge). We first clear the bit using the ~RISING value.
-+               */
-+              temp_reg = (registers[msp]->global_ctrl) & ~TX_CLK_POL_RISING;
-+              temp_reg |=
-+                  msp_tx_clkpol_bit(protocol_desc_tab[protocol].
-+                                    tx_clock_edge);
-+              temp_reg |= TX_EXTRA_DELAY_ENABLE;
-+              temp_reg |= msp_data_delay_bits(MSP_DELAY_1);
++      }
++      nmdk_error("All DMA Channels occupied....");
++      return -DMA_ALLCHANELS_OCCUPIED;
++}
++EXPORT_SYMBOL(request_available_dma);
 +
-+              (registers[msp]->global_ctrl) = temp_reg;
-+              break;
-+      case MSP_RECEIVE_MODE:
-+              rx_status[msp].phase_mode =
-+                  protocol_desc_tab[protocol].phase_mode;
++/**
++ * suspend_dma - Pauses DMA transfer for this channel
++ * @channel: DMA channel number
++ *
++ * This API will pause current dma if it is ongoing
++ * also this API is used to pause all active on going DMA channels involved
++ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
++ */
++void suspend_dma(dmach_t channel)
++{
++      dma_t *dma;
++      volatile struct dmach_register *p_dmach_reg;
++      unsigned long flags;
 +
-+              /* Use a temp for setup. Clear everything except the two non-mode
-+               * dependent bits, then add back the bits for the selected protocol
-+               */
-+              temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
++      nmdk_dbg_ftrace();
++      if (!(socdat->dma_chan)) goto inactive_dma;
++      dma = socdat->dma_chan;
++      if (DMA_ALL_MEM_CHANNELS == channel) {
++              for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
++                      if (!dma->lock) continue;
++                      if (NMDK_DMA_SUSPENDED == dma->state) continue;
++                      if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
++                              == PERIPH_TO_PERIPH) continue;
++                      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
 +
-+              temp_reg |=
-+                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+              temp_reg |=
-+                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_1);
-+              temp_reg |=
-+                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_2);
-+              if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+                      temp_reg |=
-+                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_1);
-+                      temp_reg |=
-+                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_2);
-+                      if (protocol_desc_tab[protocol].element_len_1 ==
-+                          protocol_desc_tab[protocol].element_len_2) {
-+                              msp_context[msp].actual_data_size =
-+                                  protocol_desc_tab[protocol].element_len_1;
-+                      } else {
-+                              msp_context[msp].actual_data_size = data_size;
++                      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
++                      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++                      flags = claim_dma_lock();
++                      nmdk_dbg("Channel %d Suspended on pipe %p", channel, (void *)dmaconfig_pipeadr(dma));
++                      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++                              p_dmach_reg->cfg |= NMDK_DMACH_HALT;
 +                      }
-+              } else {
-+                      temp_reg |= msp_p1_elem_len_bits(data_size);
-+                      temp_reg |= msp_p2_elem_len_bits(data_size);
-+                      msp_context[msp].actual_data_size = data_size;
++                      release_dma_lock(flags);
++                      dma->state = NMDK_DMA_SUSPENDED;
++
++                      dma++;
 +              }
-+              temp_reg |=
-+                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
++              return;
++      }
++      if (!(socdat->dma_chan)) goto inactive_dma;
++      dma += channel;
++      if (!dma->lock)
++              goto free_dma;
 +
-+              (registers[msp]->rx_config) = temp_reg;
++      if (NMDK_DMA_SUSPENDED == dma->state) return;
++      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
 +
-+              /* The rx_config register is done, now set the clock mode (rising
-+               * or falling edge). We first clear the bit using the ~RISING value.
-+               */
-+              temp_reg = (registers[msp]->global_ctrl) & ~RX_CLK_POL_RISING;
-+              temp_reg |=
-+                  msp_rx_clkpol_bit(protocol_desc_tab[protocol].
-+                                    rx_clock_edge);
++      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
++      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++      flags = claim_dma_lock();
++      nmdk_dbg("Channel %d Suspended on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++              p_dmach_reg->cfg |= NMDK_DMACH_HALT;
++      }
++      release_dma_lock(flags);
++      dma->state = NMDK_DMA_SUSPENDED;
++      return;
 +
-+              (registers[msp]->global_ctrl) = temp_reg;
-+              break;
-+      case MSP_BOTH_T_R_MODE:
-+              rx_status[msp].phase_mode =
-+                  protocol_desc_tab[protocol].phase_mode;
-+              tx_status[msp].phase_mode =
-+                  protocol_desc_tab[protocol].phase_mode;
++free_dma:
++      printk(KERN_ERR "dma%d: trying to suspend free DMA\n", channel);
++      BUG();
++      return;
++inactive_dma:
++      printk(KERN_ERR "dma driver not active\n");
++      BUG();
++}
++EXPORT_SYMBOL(suspend_dma);
 +
-+              /* Use a temp for setup. Clear everything except the two non-mode
-+               * dependent bits, then add back the bits for the selected protocol
-+               * do rx_config first
-+               */
-+              temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
 +
-+              temp_reg |=
-+                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+              temp_reg |=
-+                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_1);
-+              temp_reg |=
-+                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_2);
-+              if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+                      temp_reg |=
-+                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_1);
-+                      temp_reg |=
-+                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_2);
-+                      if (protocol_desc_tab[protocol].element_len_1 ==
-+                          protocol_desc_tab[protocol].element_len_2) {
-+                              msp_context[msp].actual_data_size =
-+                                  protocol_desc_tab[protocol].element_len_1;
-+                      } else {
-+                              msp_context[msp].actual_data_size = data_size;
-+                      }
-+              } else {
-+                      temp_reg |= msp_p1_elem_len_bits(data_size);
-+                      temp_reg |= msp_p2_elem_len_bits(data_size);
-+                      msp_context[msp].actual_data_size = data_size;
-+              }
-+              temp_reg |=
-+                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
++/**
++ * nomadik_dma_residue - low level method for get_dma_residue API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ *
++ * Pause the channel, read the control register, resume the channel
++ * May not be an accurate value
++ * returns bytes remaining on a transfer
++ */
++static int nomadik_dma_residue(dmach_t channel, dma_t *dma)
++{
++      volatile unsigned int r = 0;
++      volatile struct dmach_register *p_dmach_reg =
++              (struct dmach_register *)dmaconfig_pipeadr(dma);
 +
-+              (registers[msp]->rx_config) = temp_reg;
++      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return -1;
++      suspend_dma(channel);
++      mb();
 +
-+              /* Now tx_config */
-+              temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
++      /*get transfer bytes = src_width * transfer_size */
++      r = p_dmach_reg->cr & 0x0fff;
++      r *= ((p_dmach_reg->cr & 0x000c0000)>>17);
++      mb();
++      resume_dma(channel);
++
++      return r;
++}
++
++/**
++ * resume_dma - Resume already suspended DMA transfer for this channel
++ * @channel: DMA channel number
++ *
++ * This API will resume current dma if it is suspended previously
++ * also this API is used to resume all active and paused DMA channels involved
++ * with memory transfer by passing DMA_ALL_MEM_CHANNELS as an argument
++ */
++void resume_dma(dmach_t channel)
++{
++      dma_t *dma;
++      volatile struct dmach_register *p_dmach_reg;
++      unsigned long flags;
++
++      nmdk_dbg_ftrace();
++      if (!(socdat->dma_chan)) goto inactive_dma;
++      dma = socdat->dma_chan;
++      if (DMA_ALL_MEM_CHANNELS == channel) {
++              for (channel=0; channel< MAX_DMA_CHANNELS; channel++) {
++                      if (!dma->lock) continue;
++                      if (NMDK_DMA_SUSPENDED != dma->state) continue;
++                      if (((u32)dmaconfig_mode(dma)&PERIPH_TO_PERIPH)
++                              == PERIPH_TO_PERIPH) continue;
++                      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
++
++                      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) continue;
++                      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++                      flags = claim_dma_lock();
++                      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++                              p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
++                      }
++                      nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++                      release_dma_lock(flags);
++                      dma->state = NMDK_DMA_RESUMED;
 +
-+              temp_reg |=
-+                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
-+              temp_reg |=
-+                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_1);
-+              temp_reg |=
-+                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
-+                                        frame_len_2);
-+              if (data_size == MSP_DATA_SIZE_DEFAULT) {
-+                      temp_reg |=
-+                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_1);
-+                      temp_reg |=
-+                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
-+                                               element_len_2);
-+              } else {
-+                      temp_reg |= msp_p1_elem_len_bits(data_size);
-+                      temp_reg |= msp_p2_elem_len_bits(data_size);
 +              }
-+              temp_reg |=
-+                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
++              return;
++      }
++      dma += channel;
++      if (!dma->lock)
++              goto free_dma;
 +
-+              (registers[msp]->tx_config) = temp_reg;
-+              /* The [rt]x_config register is done, now set the clock mode (rising
-+               * or falling edge). We first clear the bit using the ~RISING value.
-+               */
-+              temp_reg =
-+                  (registers[msp]->
-+                   global_ctrl) & ~(TX_CLK_POL_RISING | RX_CLK_POL_RISING);
-+              temp_reg |=
-+                  msp_rx_clkpol_bit(protocol_desc_tab[protocol].
-+                                    rx_clock_edge);
-+              temp_reg |=
-+                  msp_tx_clkpol_bit(protocol_desc_tab[protocol].
-+                                    tx_clock_edge);
++      if (NMDK_DMA_SUSPENDED != dma->state) return;
++      p_dmach_reg = (struct dmach_register *)dmaconfig_pipeadr(dma);
 +
-+              (registers[msp]->global_ctrl) = temp_reg;
-+              break;
-+      default:
-+              printk(KERN_ERR "Invalid direction given\n");
-+              return -EINVAL;
++      if ((p_dmach_reg == NULL) || p_dmach_reg == (void *)0xffffffff) return;
++      /*Reset E (Chanel Enablne) bit of DMAC_CxCFG reg*/
++      flags = claim_dma_lock();
++      if (p_dmach_reg->cfg & NMDK_DMACH_ENABLE) {
++              p_dmach_reg->cfg &= (u32)~(NMDK_DMACH_HALT);
 +      }
++      nmdk_dbg("Channel %d Resumed on pipe %08x", channel, (u32)dmaconfig_pipeadr(dma));
++      release_dma_lock(flags);
++      dma->state = NMDK_DMA_RESUMED;
++      return;
 +
-+      return 0;
++free_dma:
++      printk(KERN_ERR "dma%d: trying to resume free DMA\n", channel);
++      BUG();
++      return;
++inactive_dma:
++      printk(KERN_ERR "dma driver not active\n");
++      BUG();
 +}
++EXPORT_SYMBOL(resume_dma);
 +
-+static int configure_clock(int msp, int protocol, u32 input_clock,
-+                         u32 frame_freq, int frame_size)
++/**
++ * nomadik_dma_set_destadr - low level method for set_dma_speed API
++ * @channel: DMA channel number
++ * @dma: DMA channel data structure pointer
++ * @cycle: sonsidered as destination DMA address
++ *
++ * Since ther is no API to program destination DMA address.
++ * set_dma_speed is used to fulfill this need.
++ * the function returnes the cycle which finally programs dma->spped
++ * with destination DMA address for nomadik platform
++ */
++static int nomadik_dma_set_destadr(dmach_t channel, dma_t *dma, int cycle)
 +{
-+      u32 dummy;
-+      u32 frame_per = 0;
-+      u32 sck_div = 0;
-+      u32 frame_width = 0;
-+      u32 temp_reg = 0;
-+      u32 data_size;
-+
-+      (registers[msp]->global_ctrl) &= ~SRG_ENABLE;
-+
-+      switch (msp_context[msp].actual_data_size) {
-+      case MSP_DATA_SIZE_8BIT:
-+              data_size = 8;
-+              break;
-+      case MSP_DATA_SIZE_10BIT:
-+              data_size = 10;
-+              break;
-+      case MSP_DATA_SIZE_12BIT:
-+              data_size = 12;
-+              break;
-+      case MSP_DATA_SIZE_14BIT:
-+              data_size = 14;
-+              break;
-+      case MSP_DATA_SIZE_16BIT:
-+              data_size = 16;
-+              break;
-+      case MSP_DATA_SIZE_20BIT:
-+              data_size = 20;
-+              break;
-+      case MSP_DATA_SIZE_24BIT:
-+              data_size = 24;
-+              break;
-+      case MSP_DATA_SIZE_32BIT:
-+              data_size = 32;
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "Unable to determine data size in configure_clock\n");
-+              return -EINVAL;
-+      }
++      /*Speed is used to store destination address*/
++      return (cycle);
++}
 +
-+      switch (protocol) {
-+      case MSP_PCM_PROTOCOL:
-+      case MSP_PCM_COMPAND_PROTOCOL:
-+      case MSP_MASTER_SPI_PROTOCOL:
-+              if (frame_size < 0) {
-+                      frame_per = data_size;
-+                      if (protocol == MSP_MASTER_SPI_PROTOCOL) {
-+                              /* Need 1 clock between start of frame and start
-+                               * of data, and 1 clock to indicate end of frame
-+                               */
-+                              frame_per += 2;
++/**
++ * nomadik_dma_interrupt - Interrupt handler for DMA controller
++ * @irq: interrupt request number
++ * @desc: irq structure pointer
++ *
++ * checks and find out the source DMA channel who generated interrupt
++ * if interrupt generated is Terminal count then
++ *    process the DMA chanel irq associated with a pipe
++ * if interrupt generated is Bus_error then
++ *    just acknowledge it.
++ * free processed transfer lli and schedule the queue
++ */
++static void nomadik_dma_interrupt(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
++{
++      u32 mask;
++      volatile struct dma_register *p_dma_reg = (struct dma_register *)desc->chip_data;
++      volatile struct dmach_register *p_dmach_reg;
++      struct dma_struct *di_dmachan;
++      do {
++              p_dmach_reg = &p_dma_reg->dmach[0];
++              nmdk_dbg2("dhach addr = %p", p_dmach_reg);
++              for (mask = 1; mask != 0x100; mask=mask<<1) {
++                      if (p_dma_reg->mis & mask) {
++                              /* To wait for the physical Channel to get disabled(otherwise it may
++                                 cause Virtual/Spurious Interrupts) */
++                              while (nomadik_dmach_is_active_n_enabled(p_dmach_reg->cfg)) ;
++                              if (p_dma_reg->tcmis & mask) {
++                                      p_dma_reg->tcicr |= mask;
++                                      irq = nomadik_dma_channel_of_pipe((void *)p_dmach_reg);
++                                      if (irq != 0) {
++                                              desc = socdat->dirqdesc + irq;
++                                              di_dmachan = socdat->dma_chan + DMACH_FOR_IRQNO(irq);
++                                              /*handle dmachanel interrupt callback*/
++                                              nmdk_dbg3("ch%d tc intr", DMACH_FOR_IRQNO(irq));
++                                              /*flag upper layer to that requested dma is complete*/
++                                              if (di_dmachan->active) di_dmachan->active = 0;
++                                              desc_handle_irq(irq, desc);
++                                              /*free lli of processed request and schedule if any request in queue*/
++                                              nomadik_dma_free_procesed_pipe(p_dmach_reg);
++                                      }
++                              }
++                              if (p_dma_reg->emis & mask) {
++                                      p_dma_reg->eicr |= mask;
++                                      nmdk_error("Intr buserr for pipe %08x", (u32)p_dmach_reg);
++                                      nomadik_dma_free_procesed_pipe(p_dmach_reg);
++                              }
 +                      }
-+              } else {
-+                      frame_per = data_size;
-+              }
-+              if (frame_per < data_size) {
-+                      printk(KERN_ERR
-+                             "Frame size too small in configure_clock\n");
-+                      return -EINVAL;
++                      p_dmach_reg++;
 +              }
-+              frame_width = 1;
++      } while (p_dma_reg->mis != 0);
++      nmdk_dbg2("intr exit");
++}
 +
-+              sck_div = input_clock / (frame_freq << 8);
-+              frame_per = MSP_FRAME_PERIOD_IN_MONO_MODE;
++struct dma_ops nomadik_dma_ops = {
++      .type           = "DMACH:",
++      .request        = nomadik_dma_req,
++      .free           = nomadik_dma_fr,
++      .enable         = nomadik_dma_en,
++      .disable        = nomadik_dma_dis,
++      .setspeed       = nomadik_dma_set_destadr,
++      .residue        = nomadik_dma_residue,
++};
 +
-+              break;
-+      case MSP_I2S_PROTOCOL:
-+              sck_div = input_clock / (frame_freq << 5);
-+              frame_per = MSP_FRAME_PERIOD_IN_STEREO_MODE;
-+              frame_width = MSP_FRAME_WIDTH_IN_STEREO_MODE;
++/**
++ * nomadik_dma_probe - driver probe function
++ *
++ * checks platfom_data is programmed properly
++ * ioremaps the DMAC register and updates pointer
++ * sets DMAC irq handler
++ * allocates memory for lli pool
++ * configures DMA channels and DMA channel interrupts
++ */
++static int nomadik_dma_probe(struct amba_device *dev, void *data)
++{
++      int i, ret;
++      uint8 dmac;
++      struct irq_desc *dirq_desc;
++      struct dma_struct *dmachan, *dmachan_temp;
++      volatile struct dma_register *p_dma_reg;
++      struct irqchip *p_dirqchip;
 +
-+              break;
-+      case MSP_AC97_PROTOCOL:
-+              /* Not supported */
-+              printk(KERN_WARNING "AC97 protocol not supported\n");
-+              return -ENOSYS;
-+      case MSP_SLAVE_SPI_PROTOCOL:
-+              sck_div = 1;
-+              break;
-+      default:
-+              printk(KERN_ERR "Invalid mode attempted for setting clocks\n");
-+              return -EINVAL;
++      nmdk_dbg_ftrace();
++
++      /* findout dma controller number*/
++      if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
++      else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
++      else {
++              nmdk_error("invalid dma device");
++              ret = -EINVAL;
++              goto res_out;
 +      }
 +
-+      temp_reg = (sck_div - 1) & SCK_DIV_MASK;
-+      temp_reg |= frame_width_bits(frame_width - 1);
-+      temp_reg |= frame_period_bits(frame_per - 1);
-+      registers[msp]->srg_ctrl = temp_reg;
++      if (! dev->dev.platform_data) {
++              nmdk_error("platform specific data no initialized for DMAC%d", dmac);
++              ret = -ENOMEM;
++              goto res_out;
++      }
++/*    ret = amba_request_regions(dev, NULL);
++      if (ret)
++              goto out;
++ */
++      p_dma_reg = (void __iomem *)
++              ioremap((int)dev->res.start, SZ_4K);
++      if (!p_dma_reg) {
++              nmdk_error("ioremap failed for DMAC%d", dmac);
++              ret = -ENOMEM;
++              goto res_out;
++      }
++      nmdk_dbg("dma_erg prt = %p irq  %d", p_dma_reg,dev->irq[0] );
++      socdat = (struct dma_soc_data *)dev->dev.platform_data;
++      dmachan = (struct dma_struct *)socdat->dma_chan;
++      dirq_desc = socdat->dirqdesc;
++      p_dirqchip = socdat->dirqchip;
++      dirq_desc[dev->irq[0]].chip_data = (void *)p_dma_reg;
 +
-+      /* Wait a bit */
-+      dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
++      memset((void *)p_dma_reg, 0, sizeof(struct dma_register));      /*init h/w register to zero*/
++#ifdef __STN_8810
++#if (__STN_8810 == 10)
++      p_dma_reg->cr = 0x01;   /*enable DMa controller */
++#endif
++#endif
 +
-+      /* Enable clock */
-+      registers[msp]->global_ctrl |= SRG_ENABLE;
++      set_irq_chained_handler(dev->irq[0], (void *)nomadik_dma_interrupt);
 +
-+      /* Another wait */
-+      dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
-+      /* reconfigure spi clock mode */
-+      temp_reg = registers[msp]->global_ctrl;
-+      temp_reg &= ~SPI_CLK_MODE_MASK;
-+      temp_reg |= spi_clock_mode[msp];
-+      temp_reg &= ~SPI_BURST_MODE_MASK;
-+      temp_reg |= spi_burst_mode[msp];
++      if (!(dmac)) {
 +
-+      registers[msp]->global_ctrl = temp_reg;
-+      return 0;
++              lli_ptr_log = (struct dmach_lli *)dma_alloc_coherent(NULL,
++                       MAX_DMA_LLIS * (sizeof(struct dmach_lli)),
++                       (dma_addr_t *) &lli_ptr_phy,
++                       GFP_DMA | GFP_ATOMIC);
++              if (lli_ptr_log <= 0) {
++                      nmdk_error("unable to request mem for llis");
++                      ret = -1;
++                      goto bad_dev;
++              }
++              nmdk_info("chanel lli physical adr(%08x) logical adr(%08x)", (u32)lli_ptr_phy, (u32)lli_ptr_log);
++              dmachan_temp = dmachan;
++              /* dma chanel irq initialization */
++              for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
++                      /*set_irq_chip(i, &nomadik_dma_chip);*/
++                      set_irq_handler(i, handle_simple_irq);
++                      set_irq_flags(i, IRQF_VALID);
++                      socdat->dirqdesc[i].chip_data= NULL; //&p_dma_reg->dmach[ret];
++                      if (i < MAX_DMA_CHANNELS) p_lli_pipe[DMACH_FOR_IRQNO(i)] = NULL;
++                      /* dma chanel data structure initialization */
++                      dmachan[DMACH_FOR_IRQNO(i)].d_ops = &nomadik_dma_ops;
++                      dmachan[DMACH_FOR_IRQNO(i)].dma_irq = i;
++
++              }
++      }
++      nmdk_info("DMA%d Module initialized Ver("DMA_VER")",dmac);
++      return (0);
++
++bad_dev:
++      iounmap(p_dma_reg);
++res_out:
++      return (ret);
 +}
 +
-+static irqreturn_t handle_irq(int irq, void *dev_id)
++/**
++ * nomadik_dma_remove - driver remove function
++ *
++ * resets DMA channels and DMA channel interrupts configureation
++ * deallocates memory for lli pool
++ * resets DMAC irq handler
++ * frees ioremapped memory
++ */
++static int nomadik_dma_remove(struct amba_device *dev)
 +{
-+      int msp;
-+      u32 irq_status;
++      uint8 dmac;
++      int i;
++      struct irq_desc *dirq_desc;
++      struct dma_struct *dma_chan;
++      volatile struct dma_register *p_dma_reg;
++      struct irqchip *p_dirqchip;
 +
-+      /* dev_id should be the register base address, find out which MSP
-+       * we are dealing with. */
-+      for (msp = 0; msp < MSP_COUNT; msp++) {
-+              if (dev_id == registers[msp]) {
-+                      break;
-+              }
++      nmdk_dbg_ftrace();
++
++      /* findout dma controller number*/
++      if (IRQ_DMA0 == dev->irq[0]) dmac = 0;
++      else if (IRQ_DMA1 == dev->irq[0]) dmac = 1;
++      else {
++              nmdk_error("invalide dma device");
++              return(-EINVAL);
 +      }
++      socdat = dev->dev.platform_data;
++      dma_chan = (struct dma_struct *)socdat->dma_chan;
++      dirq_desc = socdat->dirqdesc;
++      p_dma_reg = dirq_desc[dev->irq[0]].chip_data;
 +
-+      if (msp == MSP_COUNT) {
-+              /* Didn't find the MSP, this must not be our interrupt */
-+              return -1;
++      p_dirqchip = socdat->dirqchip;
++      if (!(dmac)) {
++              for (i = (MAX_DMA_IRQ-MAX_DMA_CHANNELS); i < MAX_DMA_IRQ; i++) {
++                      //set_irq_chip(i, 0x00);
++                      set_irq_handler(i, handle_bad_irq);
++                      dma_chan[DMACH_FOR_IRQNO(i)].d_ops = NULL;
++              }
 +      }
 +
-+      irq_status = registers[msp]->masked_irq_status;
++      set_irq_handler(dev->irq[0], handle_bad_irq);
 +
-+      /* Disable the interrupt to prevent immediate recurrence */
-+      registers[msp]->irq_mask &= ~irq_status;
++      dma_free_coherent(NULL,
++                        ((MAX_DMA_CHANNELS*(sizeof(struct dmach_lli))*8)+256),
++                        (void *)lli_ptr_log, (dma_addr_t)lli_ptr_phy );
++      lli_ptr_phy = lli_ptr_log = NULL;
 +
-+      /* Clear the interrupt */
-+      registers[msp]->irq_clear = irq_status;
++      iounmap(p_dma_reg);
++      dirq_desc[dev->irq[0]].chip_data = 0x00;
++      /*amba_release_regions(dev);*/
 +
-+      /* Check for an error condition */
-+      msp_io_error[msp] |= irq_status & (RECEIVE_OVERRUN_ERROR_INT |
-+                                         RECEIVE_FRAME_SYNC_ERR_INT |
-+                                         TRANSMIT_UNDERRUN_ERR_INT |
-+                                         TRANSMIT_FRAME_SYNC_ERR_INT);
++      nmdk_info("Module removed");
++      return 0;
++}
 +
-+      /* Wake up the reader/writer */
-+      wake_up_interruptible(&wait[msp]);
-+      return IRQ_HANDLED;
++static struct amba_id nomadik_dma_dev_ids[] __initdata = {
++      {
++       .id = DMA_PER_ID,
++       .mask = DMA_PER_MASK,
++       },
++      {0, 0},
++};
 +
-+}
++static struct amba_driver dma_driver = {
++      .drv = {
++              .name = "DMA",
++              },
++      .id_table = nomadik_dma_dev_ids,
++      .probe = nomadik_dma_probe,
++      .remove = nomadik_dma_remove
++};
 +
-+static int transmit_data(int msp, void *data, size_t bytes)
++static int __init nomadik_dma_init(void)
 +{
-+      return transmit_receive_data(msp, tx_status[msp].work_mode,
-+                                   data, bytes, NULL, 0);
++      return amba_driver_register(&dma_driver);
 +}
 +
-+static int receive_data(int msp, void *data, size_t bytes)
++static void __exit nomadik_dma_exit(void)
 +{
-+      return transmit_receive_data(msp, rx_status[msp].work_mode,
-+                                   NULL, 0, data, bytes);
++      amba_driver_unregister(&dma_driver);
 +}
 +
-+static int transmit_receive_data(int msp, int work_mode,
-+                               void *txdata, size_t txbytes,
-+                               void *rxdata, size_t rxbytes)
-+{
-+      int status;
-+      u32 tx_offset = 0;
-+      u32 rx_offset = 0;
-+      u8 *data_src_8bit, *data_dst_8bit;
-+      u16 *data_src_16bit, *data_dst_16bit;
-+      u32 *data_src_32bit, *data_dst_32bit;
++module_init(nomadik_dma_init);
++module_exit(nomadik_dma_exit);
 +
-+      if (txdata == NULL && txbytes > 0) {
-+              printk(KERN_ERR
-+                     "transmit_receive_data received a NULL transmit buffer with bytes to transmit\n");
-+              return -EINVAL;
-+      }
++/* Module parameters */
 +
-+      if (rxdata == NULL && rxbytes > 0) {
-+              printk(KERN_ERR
-+                     "transmit_receive_data received a NULL receive buffer with bytes to receive\n");
-+              return -EINVAL;
-+      }
++MODULE_AUTHOR("ST Microelectronics");
++MODULE_DESCRIPTION("Nomadik DMA Controllers (0 and 1)");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/fsmc.c
+@@ -0,0 +1,113 @@
++/*
++ *  linux/arch/arm/mach-nomadik/fsmc.c
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
 +
-+      data_src_8bit = (u8 *) txdata;
-+      data_src_16bit = (u16 *) txdata;
-+      data_src_32bit = (u32 *) txdata;
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <asm/io.h>
++#include <asm/types.h>
++#include <asm/hardware.h>
++#include <asm/arch/fsmc.h>
 +
-+      data_dst_8bit = (u8 *) rxdata;
-+      data_dst_16bit = (u16 *) rxdata;
-+      data_dst_32bit = (u32 *) rxdata;
++struct fsmc_nomadik_info {
++      unsigned char __iomem *fsmc_reg;
++};
 +
-+      msp_io_error[msp] = 0;
++static int nomadik_fsmc_probe(struct platform_device *pdev)
++{
++      struct fsmc_platform_data *pdata = pdev->dev.platform_data;
++      struct fsmc_nomadik_info *data = NULL;
++      struct resource *res = NULL;
++      if (!pdata->init) {
++              printk("FSMC ::: platform init() function is not present\n");
++              return (-1);
++      }
 +
-+      while (tx_offset < txbytes || rx_offset < rxbytes) {
-+              if (msp_io_error[msp]) {
-+                      return -EIO;
-+              }
-+
-+              if (rx_offset < rxbytes &&
-+                  !((registers[msp]->status) & RX_FIFO_EMPTY)) {
-+                      switch (msp_context[msp].actual_data_size) {
-+                      case MSP_DATA_SIZE_8BIT:
-+                              rx_offset += sizeof(*data_dst_8bit);
-+                              *data_dst_8bit++ = registers[msp]->fifo;
-+                              break;
-+                      case MSP_DATA_SIZE_10BIT:
-+                      case MSP_DATA_SIZE_12BIT:
-+                      case MSP_DATA_SIZE_14BIT:
-+                      case MSP_DATA_SIZE_16BIT:
-+                              rx_offset += sizeof(*data_dst_16bit);
-+                              *data_dst_16bit++ = registers[msp]->fifo;
-+                              break;
-+                      case MSP_DATA_SIZE_20BIT:
-+                      case MSP_DATA_SIZE_24BIT:
-+                      case MSP_DATA_SIZE_32BIT:
-+                              rx_offset += sizeof(*data_dst_32bit);
-+                              *data_dst_32bit++ = registers[msp]->fifo;
-+                              break;
-+                      default:
-+                              printk(KERN_ERR
-+                                     "Unable to determine data size in transmit_receive_data\n");
-+                              return -EIO;
-+                      }
-+              }
-+
-+              if (tx_offset < txbytes &&
-+                  !((registers[msp]->status) & TX_FIFO_FULL)) {
-+                      switch (msp_context[msp].actual_data_size) {
-+                      case MSP_DATA_SIZE_8BIT:
-+                              tx_offset += sizeof(*data_src_8bit);
-+                              registers[msp]->fifo = *data_src_8bit++;
-+                              break;
-+                      case MSP_DATA_SIZE_10BIT:
-+                      case MSP_DATA_SIZE_12BIT:
-+                      case MSP_DATA_SIZE_14BIT:
-+                      case MSP_DATA_SIZE_16BIT:
-+                              tx_offset += sizeof(*data_src_16bit);
-+                              registers[msp]->fifo = *data_src_16bit++;
-+                              break;
-+                      case MSP_DATA_SIZE_20BIT:
-+                      case MSP_DATA_SIZE_24BIT:
-+                      case MSP_DATA_SIZE_32BIT:
-+                              tx_offset += sizeof(*data_src_32bit);
-+                              registers[msp]->fifo = *data_src_32bit++;
-+                              break;
-+                      default:
-+                              printk(KERN_ERR
-+                                     "Unable to determine data size in transmit_receive_data\n");
-+                              return -EIO;
-+                      }
-+              }
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +
-+              if (work_mode == MSP_INTERRUPT_MODE &&
-+                  (tx_offset < txbytes || rx_offset < rxbytes)) {
-+                      u32 status_mask = 0;
-+                      u32 irq_mask = 0;
-+                      if (tx_offset < txbytes) {
-+                              status_mask |= TX_FIFO_FULL;
-+                              irq_mask |= TRANSMIT_SERVICE_INT;
-+                              if (!(registers[msp]->status & TX_FIFO_FULL)) {
-+                                      continue;
-+                              }
-+                      }
-+                      if (rx_offset < rxbytes) {
-+                              status_mask |= RX_FIFO_EMPTY;
-+                              irq_mask |= RECEIVE_SERVICE_INT;
-+                              if (!(registers[msp]->status & RX_FIFO_EMPTY)) {
-+                                      continue;
-+                              }
-+                      }
-+                      registers[msp]->irq_mask |= irq_mask;
-+                      status = wait_event_interruptible(wait[msp],
-+                                                        !(registers[msp]->
-+                                                          status &
-+                                                          status_mask)
-+                                                        && msp_io_error[msp]
-+                                                        == 0);
-+                      if (status) {
-+                              return status;
-+                      }
-+              }
-+      }
++      data = kzalloc(sizeof(struct fsmc_nomadik_info), GFP_KERNEL);
++      data->fsmc_reg = ioremap(res->start, res->end - res->start + 1);
++      platform_set_drvdata(pdev, data);
 +
-+      return txbytes + rxbytes;
++      /*do platform specific fsmc init */
++      return (pdata->init());
 +}
 +
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+
-+/**
-+ * msp_controller_cmd - To execute controller specific commands for MSP
-+ * @drv_data: SPI driver private data structure
-+ * @cmd: Command which is to be executed on the controller
-+ *
-+ *
++/*
++ * Clean up routine
 + */
-+static int msp_controller_cmd(struct driver_data *drv_data, int cmd)
++static int nomadik_fsmc_remove(struct platform_device *pdev)
 +{
-+      int retval = 0;
-+      nmdk_dbg_ftrace();
-+      switch (cmd)
-+      {
-+              case DISABLE_CONTROLLER:
-+              {
-+                      nmdk_dbg2(":::: DISABLE_CONTROLLER\n");
-+                      writel((readl(MSP_GCR(drv_data->regs)) & (~(MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN ))), MSP_GCR(drv_data->regs));
-+                      break;
-+              }
-+              case ENABLE_CONTROLLER:
-+              {
-+                      nmdk_dbg2(":::: ENABLE_CONTROLLER\n");
-+                      writel((readl(MSP_GCR(drv_data->regs)) | (MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN )), MSP_GCR(drv_data->regs));
-+                      break;
-+              }
-+              case DISABLE_DMA:
-+              {
-+                      nmdk_dbg2(":::: DISABLE_DMA\n");
-+                      writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
-+                      break;
-+              }
-+              case ENABLE_DMA:
-+              {
-+                      nmdk_dbg2(":::: ENABLE_DMA\n");
-+                      writel(drv_data->cur_chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
-+                      break;
-+              }
-+              case DISABLE_ALL_INTERRUPT:
-+              {
-+                      nmdk_dbg2(":::: DISABLE_ALL_INTERRUPT\n");
-+                      writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+                      break;
-+              }
-+              case ENABLE_ALL_INTERRUPT:
-+              {
-+                      nmdk_dbg2(":::: ENABLE_ALL_INTERRUPT\n");
-+                      writel( ENABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+                      break;
-+              }
-+              case CLEAR_ALL_INTERRUPT:
-+              {
-+                      nmdk_dbg2(":::: CLEAR_ALL_INTERRUPT\n");
-+                      writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
-+                      break;
-+              }
-+              case FLUSH_FIFO:
-+              {
-+                      unsigned long limit = loops_per_jiffy << 1;
-+                      nmdk_dbg2(":::: DATA FIFO is flushed\n");
-+                      do {
-+                              while( ! (readl(MSP_FLR(drv_data->regs)) & MSP_FLR_MASK_RFE))
-+                                      readl(MSP_DR(drv_data->regs));
-+                      } while ((readl(MSP_FLR(drv_data->regs)) & (MSP_FLR_MASK_TBUSY | MSP_FLR_MASK_RBUSY)) && limit--);
-+                      retval = limit;
-+                      break;
-+              }
-+              case RESTORE_STATE:
-+              {
-+                      struct chip_data *chip = drv_data->cur_chip;
-+                      nmdk_dbg2(":::: RESTORE_STATE\n");
-+                      writel(chip->regs.mspr.gcr, MSP_GCR(drv_data->regs));
-+                      writel(chip->regs.mspr.tcf, MSP_TCF(drv_data->regs));
-+                      writel(chip->regs.mspr.rcf, MSP_RCF(drv_data->regs));
-+                      writel(chip->regs.mspr.srg, MSP_SRG(drv_data->regs));
-+                      writel(chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
-+                      writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+                      writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
-+                      break;
-+              }
-+              case LOAD_DEFAULT_CONFIG:
-+              {
-+                      nmdk_dbg2(":::: LOAD_DEFAULT_CONFIG\n");
-+                      writel(DEFAULT_MSP_REG_GCR, MSP_GCR(drv_data->regs));
-+                      writel(DEFAULT_MSP_REG_TCF, MSP_TCF(drv_data->regs));
-+                      writel(DEFAULT_MSP_REG_RCF, MSP_RCF(drv_data->regs));
-+                      writel(DEFAULT_MSP_REG_SRG, MSP_SRG(drv_data->regs));
-+                      writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
-+                      writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
-+                      writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
-+                      break;
-+              }
-+              default:
-+              {
-+                      nmdk_dbg2(":::: unknown command\n");
-+                      retval = -1;
-+                      break;
-+              }
-+      }
-+      return retval;
-+}
++      struct fsmc_nomadik_info *data = NULL;
 +
-+void msp_u8_writer(struct driver_data *drv_data)
-+{
-+      u32 cur_write = 0;
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
-+              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+                      return;
-+              writel((u32) (*(u8 *) (drv_data->tx)), MSP_DR(drv_data->regs));
-+              drv_data->tx += (drv_data->cur_chip->n_bytes);
-+              cur_write ++;
-+              if(cur_write == 8)
-+                      return;
-+      }
-+}
-+void msp_u8_reader(struct driver_data *drv_data)
-+{
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
-+              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+                      return;
-+              *(u8 *) (drv_data->rx) = (u8) readl(MSP_DR(drv_data->regs));
-+              drv_data->rx += (drv_data->cur_chip->n_bytes);
++      data = platform_get_drvdata(pdev);
++      if(data){
++              iounmap(data->fsmc_reg);
++              kfree(data);
 +      }
++      return 0;
 +}
-+void msp_u16_writer(struct driver_data *drv_data)
-+{
-+      u32 cur_write = 0;
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
 +
-+              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+                      return;
-+              writel((u32) (*(u16 *) (drv_data->tx)), MSP_DR(drv_data->regs));
-+              drv_data->tx += (drv_data->cur_chip->n_bytes);
-+              cur_write ++;
-+              if(cur_write == 8)
-+                      return;
-+      }
-+}
-+void msp_u16_reader(struct driver_data *drv_data)
++#ifdef CONFIG_PM
++
++#define FSMC_REG_SIZE 0x78
++static char vect_fsmc[FSMC_REG_SIZE];
++int nomadik_fsmc_suspend(struct platform_device *pdev, pm_message_t state)
 +{
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
-+              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+                      return;
-+              *(u16 *) (drv_data->rx) = (u16) readl(MSP_DR(drv_data->regs));
-+              drv_data->rx += (drv_data->cur_chip->n_bytes);
-+      }
++      struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
++      printk("nomadik_fsmc_suspend: called......\n");
++      memcpy(vect_fsmc, data->fsmc_reg, FSMC_REG_SIZE);
++      return 0;
 +}
 +
-+void msp_u32_writer(struct driver_data *drv_data)
++int nomadik_fsmc_resume(struct platform_device *pdev)
 +{
-+      u32 cur_write = 0;
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
++      struct fsmc_nomadik_info *data = platform_get_drvdata(pdev);
++      printk("nomadik_fsmc_resume: called......\n");
++      memcpy(data->fsmc_reg, vect_fsmc, FSMC_REG_SIZE);
 +
-+              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+                      return;
-+              /*Write Data to Data Register */
-+              writel(*(u32 *) (drv_data->tx), MSP_DR(drv_data->regs));
-+              drv_data->tx += (drv_data->cur_chip->n_bytes);
-+              cur_write ++;
-+              if(cur_write == 8)
-+                      return;
-+      }
++      return 0;
 +}
-+void msp_u32_reader(struct driver_data *drv_data)
++
++#else
++#define nomadik_fsmc_suspend NULL
++#define nomadik_fsmc_resume NULL
++
++#endif
++
++static struct platform_driver nomadik_fsmc_driver = {
++      .probe = nomadik_fsmc_probe,
++      .remove = nomadik_fsmc_remove,
++      .driver = {
++                 .owner = THIS_MODULE,
++                 .name = "NOMADIK-FSMC",
++                 },
++      .suspend = nomadik_fsmc_suspend,
++      .resume = nomadik_fsmc_resume,
++};
++
++static int __init nomadik_fsmc_init(void)
 +{
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
-+              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+                      return;
-+              *(u32 *) (drv_data->rx) = readl(MSP_DR(drv_data->regs));
-+              drv_data->rx += (drv_data->cur_chip->n_bytes);
-+      }
++      return platform_driver_register(&nomadik_fsmc_driver);
 +}
 +
-+static irqreturn_t nomadik_msp_interrupt_handler(int irq, void *dev_id)
++module_init(nomadik_fsmc_init);
++static void __exit nomadik_fsmc_exit(void)
 +{
-+      struct driver_data *drv_data = (struct driver_data *)dev_id;
-+      struct spi_message *msg = drv_data->cur_msg;
-+      u32 irq_status = 0;
-+      u32 flag = 0;
-+      if (!msg) {
-+              dev_err(&drv_data->adev->dev,
-+                      "bad message state in interrupt handler");
-+              /* Never fail */
-+              return IRQ_HANDLED;
-+      }
-+      /*Read the Interrupt Status Register */
-+      irq_status = readl(MSP_MIS(drv_data->regs));
++      platform_driver_unregister(&nomadik_fsmc_driver);
++      return;
++}
 +
-+      if (irq_status) {
-+              if (irq_status & MSP_MIS_MASK_ROEMIS) { /*Overrun interrupt */
-+                      /*Bail-out our Data has been corrupted */
-+                      nmdk_dbg3(":::: Received ROR interrupt\n");
-+                      drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
-+                      drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
-+                      drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+                      msg->state = ERROR_STATE;
-+                      tasklet_schedule(&drv_data->pump_transfers);
-+                      return IRQ_HANDLED;
-+              }
++module_exit(nomadik_fsmc_exit);
 +
-+              drv_data->read(drv_data);
-+              drv_data->write(drv_data);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
++MODULE_DESCRIPTION("FSMC driver for Nomadik Platform");
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/gpio.c
+@@ -0,0 +1,916 @@
++/*
++ *  linux/arch/arm/mach-nomadik/gpio.c
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#define GPIO_VER      "2.1.0"
 +
-+              if ((drv_data->tx == drv_data->tx_end) && (flag == 0)) {
-+                      flag = 1;
-+                      /*Disable Transmit interrupt */
-+                      writel(readl(MSP_IMSC(drv_data->regs)) & (~MSP_IMSC_MASK_TXIM) & (~MSP_IMSC_MASK_TFOIM), (drv_data->regs + 0x14));
++#include <linux/kernel_stat.h>
++#include <linux/smp.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/signal.h>
++#include <linux/amba/bus.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/interrupt.h>
++#include <asm/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/debug.h>
++
++#define GPIO_NAME             "GPIO"
++
++#ifndef GPIO_DEBUG
++#define GPIO_DEBUG 0
++#endif
++
++#define NMDK_DEBUG    GPIO_DEBUG      /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  GPIO_NAME     /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++const char *gpio_block_name[4] = {
++      "GPIO_Block0", "GPIO_Block1", "GPIO_Block2", "GPIO_Block3",
++};
++
++static spinlock_t altfun_lock = SPIN_LOCK_UNLOCKED;
++static spinlock_t pinconf_lock = SPIN_LOCK_UNLOCKED;
++static struct gpio_soc *socdat = NULL;        /*soc specific data ptr */
++extern struct irq_desc irq_desc[];    /* maintain interrupt info */
++
++#define CHK_VALID_CALL if (! socdat) { \
++              nmdk_error("called %s before initilization", __FUNCTION__); \
++              return(-EINVAL); \
 +              }
-+              /*Clearing any Transmit underrun error. overrun already handled*/
-+              drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
 +
-+              if (drv_data->rx == drv_data->rx_end) {
-+                      drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
-+                      drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
-+                      nmdk_dbg3(":::: Interrupt transfer Completed...\n");
-+                      /* Update total bytes transfered */
-+                      msg->actual_length += drv_data->cur_transfer->len;
-+                      if (drv_data->cur_transfer->cs_change)
-+                              drv_data->cur_chip->
-+                                  cs_control(SPI_CHIP_DESELECT);
-+                      /* Move to next transfer */
-+                      msg->state = next_transfer(drv_data);
-+                      tasklet_schedule(&drv_data->pump_transfers);
-+                      return IRQ_HANDLED;
++#define CHK_VALID_PIN(pin) if (irq_desc[IRQNO_GPIO(pin)].action) {\
++              nmdk_error("%s failed, gpio%d used by irq %d", __FUNCTION__, pin , IRQNO_GPIO(pin));\
++              return -EINVAL;\
 +              }
-+      }
-+      return IRQ_HANDLED;
-+}
 +
-+static int verify_msp_controller_parameters(struct nmdk_spi_config_chip *chip_info)
++static char *nomadik_gpio_owner(gpio_pin pin_id)
 +{
-+      nmdk_dbg_ftrace();
-+      /*FIXME: check clock params*/
-+      if ((chip_info->lbm != LOOPBACK_ENABLED)
-+          && (chip_info->lbm != LOOPBACK_DISABLED)) {
-+              nmdk_dbg(":::: Loopback Mode is configured incorrectly\n");
-+              return -1;
-+      }
-+      if (chip_info->iface != SPI_INTERFACE_MOTOROLA_SPI){
-+              nmdk_dbg(":::: Interface is configured incorrectly. This controller supports only MOTOROLA SPI\n");
-+              return -1;
-+      }
-+      if ((chip_info->hierarchy != SPI_MASTER)
-+          && (chip_info->hierarchy != SPI_SLAVE)) {
-+              nmdk_dbg(":::: hierarchy is configured incorrectly\n");
-+              return -1;
-+      }
-+      if ((chip_info->endian_rx != SPI_FIFO_MSB)
-+          && (chip_info->endian_rx != SPI_FIFO_LSB)) {
-+              nmdk_dbg(":::: Rx FIFO endianess is configured incorrectly\n");
-+              return -1;
-+      }
-+      if ((chip_info->endian_tx != SPI_FIFO_MSB)
-+          && (chip_info->endian_tx != SPI_FIFO_LSB)) {
-+              nmdk_dbg(":::: Tx FIFO endianess is configured incorrectly\n");
-+              return -1;
++      if (irq_desc[IRQNO_GPIO(pin_id)].action) {
++              return (char *)irq_desc[IRQNO_GPIO(pin_id)].action->name;
 +      }
-+      if (((chip_info->controller).msp.data_size < MSP_DATA_BITS_8) || ((chip_info->controller).msp.data_size > MSP_DATA_BITS_32)) {
-+              nmdk_dbg(":::: MSP DATA Size is configured incorrectly\n");
-+              return -1;
++      if (irq_desc[IRQNO_GPIO(pin_id)].chip_data) {
++              return (char *)irq_desc[IRQNO_GPIO(pin_id)].chip_data;
 +      }
-+      if ((chip_info->com_mode != INTERRUPT_TRANSFER)
-+          && (chip_info->com_mode != DMA_TRANSFER)
-+          && (chip_info->com_mode != POLLING_TRANSFER)) {
-+              nmdk_dbg(":::: Communication mode is configured incorrectly\n");
++      return (0);
++}
++
++/**
++ * nomadik_gpio_chkwr_permission - checks pin permission for write operation
++ */
++static int nomadik_gpio_chkwr_permission(gpio_pin pin_id, char *dev_name)
++{
++      char *pin_owner = nomadik_gpio_owner(pin_id);
++      if (!pin_owner) {
++              nmdk_error("pin %d not configured", pin_id);
 +              return -1;
 +      }
-+      if (chip_info->iface == SPI_INTERFACE_MOTOROLA_SPI) {
-+              if (((chip_info->proto_params).moto.clk_phase != SPI_CLK_ZERO_CYCLE_DELAY)
-+                  && ((chip_info->proto_params).moto.clk_phase != SPI_CLK_HALF_CYCLE_DELAY)) {
-+                      nmdk_dbg(":::: Clock Phase is configured incorrectly\n");
-+                      return -1;
-+              }
-+              if (((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_LOW)
-+                  && ((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_HIGH)) {
-+                      nmdk_dbg(":::: Clock Polarity is configured incorrectly\n");
++      if (pin_owner != dev_name)
++              if (!strcmp(pin_owner, dev_name)) {
++                      nmdk_error("pin %d not owned by %s", pin_id, dev_name);
 +                      return -1;
-+              }
 +      }
-+      if (chip_info->cs_control == NULL) {
-+              nmdk_dbg("::::Chip Select Function is NULL for this chip\n");
-+              chip_info->cs_control = null_cs_control;
++      if (irq_desc[IRQNO_GPIO(pin_id)].action) {
++              nmdk_error("pin %d used as irq cannot be written", pin_id);
++              return -1;
 +      }
 +      return 0;
 +}
 +
-+/**
-+ * nomadik_msp_setup - setup function registered to SPI master framework
-+ * @spi: spi device which is requesting setup
-+ *
-+ * This function is registered to the SPI framework for this SPI master
-+ * controller. If it is the first time when setup is called by this device
-+ * , this function will initialize the runtime state for this chip and save
-+ * the same in the device structure. Else it will update the runtime info
-+ * with the updated chip info.
++/*
++ * Static Function declarations
 + */
-+
-+static int nomadik_msp_setup(struct spi_device *spi)
++static gpio_error gpio_setpinconfig(gpio_pin pin_id, gpio_config * config)
 +{
-+      struct nmdk_spi_config_chip *chip_info;
-+      struct chip_data *chip;
-+      struct spi_master *master;
-+      int status = 0;
-+      u16 sckdiv = 0;
-+      struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++      unsigned long flags;
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++      gpio_error gpio_error = GPIO_OK;
++
 +      nmdk_dbg_ftrace();
-+      master = drv_data->master;
++      spin_lock_irqsave(&pinconf_lock, flags);
++      if (config->dev_name)
++              irq_desc[IRQNO_GPIO(pin_id)].chip_data = config->dev_name;
++      else
++              irq_desc[IRQNO_GPIO(pin_id)].chip_data = "unknown";
++      spin_unlock_irqrestore(&pinconf_lock, flags);
 +
-+      switch(master->bus_num) {
-+              case MSP_0_CONTROLLER:
-+                      if((drv_data->flag_msp0->user != MSP_NO_USER) && (drv_data->flag_msp0->user != MSP_USER_SPI)){
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP0 already in use in %d mode", drv_data->flag_msp0->user);
-+                      }
-+                      else {
-+                              down(&drv_data->flag_msp0->lock);
-+                              drv_data->flag_msp0->user = MSP_USER_SPI;
-+                              up(&drv_data->flag_msp0->lock);
-+                              nmdk_dbg("Flag set to MSP_USER_SPI for MSP0\n");
-+                      }
++      switch (config->mode) {
++      case GPIO_ALTF_A:
++              p_gpio_register->gpio_afsa |= mask;
++              p_gpio_register->gpio_afsb &= ~mask;
++              break;
++      case GPIO_ALTF_B:
++              p_gpio_register->gpio_afsa &= ~mask;
++              p_gpio_register->gpio_afsb |= mask;
++              break;
++      case GPIO_ALTF_C:
++              p_gpio_register->gpio_afsa |= mask;
++              p_gpio_register->gpio_afsb |= mask;
++              break;
++      case GPIO_MODE_SOFTWARE:
++              p_gpio_register->gpio_afsa &= ~mask;
++              p_gpio_register->gpio_afsb &= ~mask;
++
++              switch (config->direction) {
++              case GPIO_DIR_INPUT:
++                      p_gpio_register->gpio_dirc = mask;
 +                      break;
-+              case MSP_1_CONTROLLER:
-+                      if((drv_data->flag_msp1->user != MSP_NO_USER) && (drv_data->flag_msp1->user != MSP_USER_SPI)){
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP1 already in use in %d mode", drv_data->flag_msp1->user);
-+                      }
-+                      else {
-+                              down(&drv_data->flag_msp1->lock);
-+                              drv_data->flag_msp1->user = MSP_USER_SPI;
-+                              up(&drv_data->flag_msp1->lock);
-+                              nmdk_dbg("Flag set to MSP_USER_SPI for MSP1\n");
-+                      }
++              case GPIO_DIR_OUTPUT:
++                      p_gpio_register->gpio_dirs = mask;
 +                      break;
-+              case MSP_2_CONTROLLER:
-+                      if((drv_data->flag_msp2->user != MSP_NO_USER) && (drv_data->flag_msp2->user != MSP_USER_SPI)){
-+                              status = -EINVAL;
-+                              printk(KERN_ERR "MSP2 already in use in %d mode", drv_data->flag_msp2->user);
-+                      }
-+                      else {
-+                              down(&drv_data->flag_msp2->lock);
-+                              drv_data->flag_msp2->user = MSP_USER_SPI;
-+                              up(&drv_data->flag_msp2->lock);
-+                              nmdk_dbg("Flag set to MSP_USER_SPI for MSP2\n");
-+                      }
++              case GPIO_DIR_LEAVE_UNCHANGED:
 +                      break;
-+      }
-+      if(status)
-+              return status;
++              default:
++                      return (GPIO_INVALID_PARAMETER);
++              }
 +
-+      status = nomadik_gpio_altfuncenable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
-+      if (status < 0) {
-+              dev_err(&drv_data->adev->dev, "probe - unable to set GPIO Altfunc, %d\n", drv_data->master_info->gpio_alt_func);
-+              status = -ENODEV;
-+              goto err_out;
++              if (socdat->dbounce)
++                      gpio_error =
++                          socdat->dbounce(p_gpio_register, mask,
++                                          config->debounce,
++                                          config->debounce_time);
++              break;
++      case GPIO_MODE_LEAVE_UNCHANGED:
++              break;
++      default:
++              return (GPIO_INVALID_PARAMETER);
 +      }
++      return (gpio_error);
++}
 +
-+      status = request_irq(drv_data->adev->irq[0], nomadik_msp_interrupt_handler, 0, drv_data->master_info->device_name , drv_data);
-+      if (status < 0) {
-+              dev_err(&drv_data->adev->dev, "probe - cannot get IRQ (%d)\n", status);
-+              goto err_altfunc_enable;
++static gpio_error gpio_resetgpiopin(gpio_pin pin_id, char *dev_name)
++{
++      unsigned long flags;
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++      char *pin_dev_name;
++      gpio_error gpio_error = GPIO_OK;
++
++      nmdk_dbg_ftrace();
++      pin_dev_name = nomadik_gpio_owner(pin_id);
++      if (!pin_dev_name)
++              return 0;
++      if (strcmp(dev_name, pin_dev_name)) {
++              nmdk_error("Unable to free pin%d Current Owner is %s", pin_id,
++                         pin_dev_name);
++              return (-1);
 +      }
++      p_gpio_register->gpio_afsa &= ~mask;
++      p_gpio_register->gpio_afsb &= ~mask;    /*software mode*/
++      p_gpio_register->gpio_dirc = mask;      /*input dir*/
++      if (socdat->dbounce)                    /*disalbe debounce*/
++                      gpio_error =
++                          socdat->dbounce(p_gpio_register, mask,
++                                          GPIO_DEBOUNCE_DISABLE,
++                                          (gpio_debounce_time)NULL);
++      /* mark pin is freed */
 +
-+      /* Get controller data */
-+      chip_info = spi->controller_data;
-+      /* Get controller_state */
-+      chip = spi_get_ctldata(spi);
-+      if (chip == NULL) {
-+              chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
-+              if (!chip) {
-+                      dev_err(&spi->dev,
-+                              "setup - cannot allocate controller state");
-+                      goto err_request_irq;
-+              }
-+              chip->chip_id = spi->chip_select;
++      spin_lock_irqsave(&pinconf_lock, flags);
++      irq_desc[IRQNO_GPIO(pin_id)].chip_data = NULL;
++      spin_unlock_irqrestore(&pinconf_lock, flags);
++      if (irq_desc[IRQNO_GPIO(pin_id)].action)
++              irq_desc[IRQNO_GPIO(pin_id)].action->name = NULL;
++      return (gpio_error);
++}
 +
-+              nmdk_dbg(":::: chip Id for this client = %d\n", chip->chip_id);
-+              nmdk_dbg(":::: Allocated Memory for controller's runtime state\n");
++gpio_config altfun_pinconfig;
++static gpio_error gpio_altfunction(gpio_alt_function alt_func,
++                                 int which_altfunc, char *dev_name)
++{
++      struct gpio_altfun_data *altfun_table = socdat->altfun_tbl;
++      int max_altfun = socdat->sz_altfun_tbl;
++      int i, j, start, end;
++      unsigned long flags;
++      u8 check_pins = 1;      /*first check availability of all gpio pins */
++      gpio_error error = -1;
 +
-+              if (chip_info == NULL) {
-+                      /* spi_board_info.controller_data not is supplied */
-+                      chip_info =
-+                          kzalloc(sizeof(struct nmdk_spi_config_chip), GFP_KERNEL);
-+                      if (!chip_info) {
-+                              dev_err(&spi->dev,
-+                                      "setup - cannot allocate controller data");
-+                              status = -ENOMEM;
-+                              goto err_first_setup;
++      nmdk_dbg_ftrace();
++      spin_lock_irqsave(&altfun_lock, flags);
++      for (i = 0; i < max_altfun; i++) {
++              if (altfun_table[i].altfun != alt_func)
++                      continue;
++              start = altfun_table[i].start;
++              end = altfun_table[i].end;
++              if (start > end) {
++                      j = start;
++                      start = end;
++                      end = j;
++              }
++              if (end > GPIO_TOTAL_PINS) {
++                      nmdk_error("range upto pin%d not suported", end);
++                      error = GPIO_INVALID_PARAMETER;
++                      goto exit_altfunc;
++              }
++              for (j = start; j <= end; j++) {
++                      if (check_pins) {
++                              if (nomadik_gpio_owner(j) &&
++                                  (which_altfunc != GPIO_ALTF_DISABLE)) {
++                                      nmdk_error("pin%d not free", j);
++                                      error = -1;
++                                      goto exit_altfunc;
++                              }
++                              if (!nomadik_gpio_owner(j) &&
++                                  (which_altfunc == GPIO_ALTF_DISABLE)) {
++                                      nmdk_error
++                                          ("Trying to disable free pin%d", j);
++                                      error = -1;
++                                      goto exit_altfunc;
++                              }
++                      } else {
++                              if (which_altfunc == GPIO_ALTF_FIND) {
++                                      altfun_pinconfig.mode =
++                                          altfun_table[i].type;
++                              } else {
++                                      altfun_pinconfig.mode = which_altfunc;
++                              }
++                              altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
++                              altfun_pinconfig.debounce =
++                                  GPIO_DEBOUNCE_DISABLE;
++                              altfun_pinconfig.dev_name = dev_name;
++
++                              if (which_altfunc != GPIO_ALTF_DISABLE) {
++                                      error =
++                                          gpio_setpinconfig(j,
++                                                            &altfun_pinconfig);
++                              } else {
++                                      error = gpio_resetgpiopin(j, dev_name);
++                              }
++                              if (!error)
++                                      continue;
++                              nmdk_error
++                                  ("GPIO %d configuration failure (nmdk_error:%d)",
++                                   j, error);
++                              error = GPIO_INVALID_PARAMETER;
++                              goto exit_altfunc;
 +                      }
-+                      nmdk_dbg(":::: Allocated Memory for controller data\n");
++              }
++              if (altfun_table[i].cont == 0) {
++                      /*schedule to configure if check sucessfull */
++                      if (check_pins) {
++                              check_pins = 0;
++                              i = -1;
++                      } else {
++                              error = 0;
++                              goto exit_altfunc;
++                      }
++              }
++      }
++      exit_altfunc:
++      spin_unlock_irqrestore(&altfun_lock, flags);
++      return (error);
++}
 +
-+                      /* FIXME: Set controller data default value for MSP*/
-+                      chip_info->lbm = LOOPBACK_DISABLED;
-+                      chip_info->com_mode = POLLING_TRANSFER;
-+                      chip_info->iface = SPI_INTERFACE_MOTOROLA_SPI;
-+                      chip_info->hierarchy = SPI_MASTER;
-+                      chip_info->endian_tx = SPI_FIFO_LSB;
-+                      chip_info->endian_rx = SPI_FIFO_LSB;
-+                      (chip_info->controller).msp.data_size = MSP_DATA_BITS_32;
++/**
++ * exported functions for other drives
++ */
 +
-+                      if(spi->max_speed_hz != 0)
-+                              chip_info->freq = spi->max_speed_hz;
-+                      else
-+                              chip_info->freq = 48000;
++/*
++ * Get gpio list for /proc/gpio
++ */
++int get_gpio_list(char *buf)
++{
++      struct gpio_register *p_gpio_register;
++      uint32 mask;
++      char *p = buf;
++      char *gpiofunc;
++      char *gpio_client;
++      int i;
 +
-+                      (chip_info->proto_params).moto.clk_phase = SPI_CLK_HALF_CYCLE_DELAY;
-+                      (chip_info->proto_params).moto.clk_pol = SPI_CLK_POL_IDLE_LOW;
-+                      chip_info->cs_control = null_cs_control;
++      CHK_VALID_CALL;
++      p += sprintf(p, "Pin: %s\t%s\n", "mode", "client");
++      for (i = 0; i < GPIO_TOTAL_PINS; i++) {
++              gpio_client = nomadik_gpio_owner(i);
++              if (gpio_client) {
++                      p_gpio_register = (struct gpio_register *)
++                          get_irq_chip_data(GPIO_PIN2BLKIRQ(i));
++                      mask = 1UL << (i % GPIO_PINS_PER_BLOCK);
++                      if (irq_desc[IRQNO_GPIO(i)].action)
++                              gpiofunc = "Irq";
++                      else if ((p_gpio_register->gpio_afsa & mask)
++                               && (p_gpio_register->gpio_afsb & mask))
++                              gpiofunc = "AltFun_C";
++                      else if ((p_gpio_register->gpio_afsa & mask)
++                               && !(p_gpio_register->gpio_afsb & mask))
++                              gpiofunc = "AltFun_A";
++                      else if (!(p_gpio_register->gpio_afsa & mask)
++                               && (p_gpio_register->gpio_afsb & mask))
++                              gpiofunc = "AltFun_B";
++                      else
++                              gpiofunc = "I/O";
++                      p += sprintf(p, "%3d: %s\t%s\n", i,
++                                   gpiofunc, gpio_client);
 +              }
 +      }
++      return p - buf;
++}
 +
-+      if(chip_info->freq == 0){
-+              /*Calculate Specific Freq.*/
-+              if ( (MSP_INTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)
-+                              || ( MSP_EXTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)){
-+                      sckdiv = (chip_info->controller).msp.clk_freq.sckdiv;
++int nomadik_gpio_resetpinconfig(gpio_pin pin_id, char *dev_name)
++{
++      int error = 0;
 +
-+              }else{
-+                      status = -1;
-+                      dev_err(&spi->dev, "setup - controller clock data is incorrect");
-+                      goto err_config_params;
-+              }
-+      }else{
-+              /*Calculate Effective Freq.*/
-+              sckdiv =((DEFAULT_MSP_CLK) / (chip_info->freq)) - 1;
-+              if(sckdiv > MAX_SCKDIV){
-+                      printk("SPI: Cannot set frequency less than 48Khz, setting lowest(48 Khz)\n");
-+                      sckdiv = MAX_SCKDIV;
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++      CHK_VALID_PIN(pin_id);
++
++      if (0 != nomadik_gpio_owner(pin_id))
++              error = gpio_resetgpiopin(pin_id, dev_name);
++      return (error);
++}
++
++int nomadik_gpio_setpinconfig(gpio_pin pin_id, gpio_config * pin_config)
++{
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++      CHK_VALID_PIN(pin_id);
++      if (!irq_desc[IRQNO_GPIO(pin_id)].action) {
++              if (nomadik_gpio_owner(pin_id)) {
++                      nmdk_error("pin%d not available.. aquired by %s client",
++                                 pin_id, nomadik_gpio_owner(pin_id));
++                      return -1;
 +              }
++              return (gpio_setpinconfig(pin_id, pin_config));
++      } else {
++              nmdk_error("Cannot set gpio%d used by irq %d", pin_id,
++                         IRQNO_GPIO(pin_id));
++              return -1;
 +      }
++      return 0;
++}
 +
++int nomadik_gpio_writepin(gpio_pin pin_id, gpio_data value, char *dev_name)
++{
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
 +
-+      status = verify_msp_controller_parameters(chip_info);
-+      if (status) {
-+              dev_err(&spi->dev, "setup - controller data is incorrect");
-+              goto err_config_params;
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++      CHK_VALID_PIN(pin_id);
++      if (nomadik_gpio_chkwr_permission(pin_id, dev_name)) return -1;
++      switch (value) {
++      case GPIO_DATA_HIGH:
++              p_gpio_register->gpio_dats = mask;
++              break;
++      case GPIO_DATA_LOW:
++              p_gpio_register->gpio_datc = mask;
++              break;
++      default:
++              nmdk_error("Invalid value passed in %s", __FUNCTION__);
++              return GPIO_INVALID_PARAMETER;
 +      }
++      return GPIO_OK;
++}
 +
-+      /* Now set controller state based on controller data */
-+      chip->xfer_type = chip_info->com_mode;
-+      chip->cs_control = chip_info->cs_control;
-+
++int nomadik_gpio_readpin(gpio_pin pin_id, gpio_data * p_value)
++{
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
 +
-+      /*FIXME: write all 8 & 16 bit functions*/
-+      if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_8) {
-+              nmdk_dbg(":::: Less than 8 bits per word....\n");
-+              chip->n_bytes = 1;
-+              chip->read = msp_u8_reader;
-+              chip->write = msp_u8_writer;
-+      } else if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_16) {
-+              nmdk_dbg(":::: Less than 16 bits per word....\n");
-+              chip->n_bytes = 2;
-+              chip->read = msp_u16_reader;
-+              chip->write = msp_u16_writer;
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++      if ((p_gpio_register->gpio_dat & mask) != GPIO_ALL_ZERO) {
++              *p_value = GPIO_DATA_HIGH;
 +      } else {
-+              nmdk_dbg(":::: Less than 32 bits per word....\n");
-+              chip->n_bytes = 4;
-+              chip->read = msp_u32_reader;
-+              chip->write = msp_u32_writer;
++              *p_value = GPIO_DATA_LOW;
 +      }
++      return GPIO_OK;
++}
 +
-+      /*Now Initialize all register settings reqd. for this chip */
++int nomadik_gpio_readblock(gpio_block_id block_id, uint32 * p_value,
++                         uint32 mask)
++{
++      struct gpio_register *p_gpio_register;
 +
-+      chip->regs.mspr.gcr = 0x0;
-+      chip->regs.mspr.tcf = 0x0;
-+      chip->regs.mspr.rcf = 0x0;
-+      chip->regs.mspr.srg = 0x0;
-+      chip->regs.mspr.dmacr = 0x0;
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++      if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
++               return GPIO_INVALID_PARAMETER;
 +
-+      if ((chip_info->com_mode == DMA_TRANSFER)
-+          && ((drv_data->master_info)->enable_dma)) {
-+              chip->enable_dma = 1;
-+              chip->dma_info = kzalloc(sizeof(struct spi_dma_info), GFP_KERNEL);
-+              if(!chip->dma_info){
-+                      nmdk_dbg("Could not allocate memory for dma info of chip_data\n");
-+                      goto err_first_setup;
-+              }
-+              chip->dma_info->dma_xfer_type = chip_info->dma_xfer_type;
-+              nmdk_dbg(":::: DMA mode set in controller state\n");
-+              status = process_dma_info(chip_info, chip, (void *)drv_data);
-+              if (status < 0)
-+                      goto err_config_params;
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_RDMAE, 0);
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_TDMAE, 1);
++      if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
++              p_gpio_register =
++                  (struct gpio_register *)get_irq_chip_data(block_id -
++                                                           GPIO_BLOCK_32_BITS_0_TO_31
++                                                           + IRQ_GPIO0);
++              *p_value = p_gpio_register->gpio_dat & (mask & GPIO_32BIT_MASK);
 +
-+              /* find and request free dma chanel */
-+              chip->dma_info->rx_dmach = request_available_dma(&(chip->dma_info->rx_dma_info));
-+              if (chip->dma_info->rx_dmach < 0) {
-+                      nmdk_dbg(":::: Rx pipe request Failed: %d\n", chip->dma_info->rx_dmach);
-+                      goto err_rx_dmach_request;
++      } else {
++              p_gpio_register = (struct gpio_register *)
++                  get_irq_chip_data((block_id -
++                                    GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
++                                   IRQ_GPIO0);
++              switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
++              case 0:
++                      *p_value =
++                          (p_gpio_register->gpio_dat & (mask & 0x0000ffff));
++                      break;
++              case 1:
++                      *p_value =
++                          (p_gpio_register->
++                           gpio_dat & (mask & 0x00ffff00)) >> GPIO_SHIFT8;
++                      break;
++              case 2:
++                      *p_value =
++                          (p_gpio_register->
++                           gpio_dat & (mask & 0xffff0000)) >> GPIO_SHIFT16;
++                      break;
++              case 3:
++                      *p_value =
++                          (p_gpio_register->
++                           gpio_dat & (mask & 0xff000000)) >> GPIO_SHIFT24;
++                      p_gpio_register += SZ_4K;       /* point next bank */
++                      *p_value |=
++                          (p_gpio_register->
++                           gpio_dat & (mask & 0x000000ff)) << GPIO_SHIFT8;
++                      break;
 +              }
-+              nmdk_dbg(":::: Rx pipe Allocated = %d\n", chip->dma_info->rx_dmach);
++      }
++      return (GPIO_OK);
++}
 +
-+              status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->rx_dmach),
-+                              spi_dma_callback_handler, 0, 0,
-+                              (void *)drv_data);
-+              if (status) {
-+                      nmdk_error("Error requesting rx callback dmach intr handler %d", status);
-+                      goto err_rx_clbk_request;
-+              }
++int nomadik_gpio_writeblock(gpio_block_id block_id, uint32 p_value, uint32 mask, char *dev_name)
++{
++      struct gpio_register *p_gpio_register;
++      int i, bankno, testmask;
 +
-+              /* find and request free dma chanel */
-+              chip->dma_info->tx_dmach = request_available_dma(&(chip->dma_info->tx_dma_info));
-+              if (chip->dma_info->tx_dmach < 0) {
-+                      nmdk_dbg(":::: Tx pipe request Failed: %d\n", status);
-+                      goto err_tx_dmach_request;
-+              }
-+              nmdk_dbg(":::: Tx pipe Allocated = %d\n", chip->dma_info->tx_dmach);
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++      if (GPIO_BLOCK_16_BITS_112_TO_123 < block_id)
++              return GPIO_INVALID_PARAMETER;
 +
-+              status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->tx_dmach),
-+                              spi_dma_callback_handler, 0, 0,
-+                              (void *)drv_data);
-+              if (status) {
-+                      nmdk_error("Error requesting callback dmach intr handler %d", status);
-+                      goto err_tx_clbk_request;
++      if (GPIO_BLOCK_16_BITS_0_TO_15 > block_id) {
++              bankno = block_id * GPIO_PINS_PER_BLOCK;
++              testmask = 0x01;
++              for (i = bankno; i < (bankno + GPIO_PINS_PER_BLOCK); i++) {
++                      if ((mask & testmask) &&
++                              (!nomadik_gpio_chkwr_permission(i, dev_name))){
++                              return -1;
++                      }
++                      testmask = 1UL << i;
 +              }
-+      } else {
-+              chip->enable_dma = 0;
-+              nmdk_dbg(":::: DMA mode NOT set in controller state\n");
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_RDMAE, 0);
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_TDMAE, 1);
-+      }
 +
++              p_gpio_register =
++                  (struct gpio_register *)get_irq_chip_data(block_id -
++                                                           GPIO_BLOCK_32_BITS_0_TO_31
++                                                           + IRQ_GPIO0);
++              p_gpio_register->gpio_datc =
++                  ~(p_value & (mask & GPIO_32BIT_MASK));
++              p_gpio_register->gpio_dats = p_value & (mask & GPIO_32BIT_MASK);
 +
-+      /****   GCR Reg Config  *****/
-+
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RECEIVER_DISABLED, MSP_GCR_MASK_RXEN,0);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RX_FIFO_ENABLED, MSP_GCR_MASK_RFFEN,1);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMITTER_DISABLED, MSP_GCR_MASK_TXEN,8);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FIFO_ENABLED, MSP_GCR_MASK_TFFEN,9);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_POL_LOW, MSP_GCR_MASK_TFSPOL,10);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_INT, MSP_GCR_MASK_TFSSEL,11);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMIT_DATA_WITH_DELAY, MSP_GCR_MASK_TXDDL,15);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SAMPLE_RATE_GEN_ENABLE, MSP_GCR_MASK_SGEN,16);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_CLOCK_INTERNAL, MSP_GCR_MASK_SCKSEL,18);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_FRAME_GEN_ENABLE, MSP_GCR_MASK_FGEN,20);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, SPI_BURST_MODE_DISABLE, MSP_GCR_MASK_SPIBME,23);
-+
++      } else {
++              bankno = (block_id - GPIO_BLOCK_16_BITS_0_TO_15) * 8;
++              testmask = 0x01;
++              for (i = bankno; i < (bankno + (GPIO_PINS_PER_BLOCK / 2)); i++) {
++                      if ((mask & testmask) &&
++                              (!nomadik_gpio_chkwr_permission(i, dev_name))){
++                              return -1;
++                      }
++                      testmask = 1UL << i;
++              }
++              p_gpio_register = (struct gpio_register *)
++                  get_irq_chip_data((block_id -
++                                    GPIO_BLOCK_16_BITS_0_TO_15) / 4 +
++                                   IRQ_GPIO0);
++              switch ((block_id - GPIO_BLOCK_16_BITS_0_TO_15) & 0x03) {
++              case 0:
++                      p_gpio_register->gpio_datc =
++                          ~(p_value & (mask & 0x0000ffff));
++                      p_gpio_register->gpio_dats =
++                          p_value & (mask & 0x0000ffff);
++                      break;
++              case 1:
++                      p_gpio_register->gpio_datc =
++                          ~(((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
++                      p_gpio_register->gpio_dats =
++                          (((p_value & mask) << GPIO_SHIFT8) & 0x00ffff00);
++                      break;
++              case 2:
++                      p_gpio_register->gpio_datc =
++                          ~(((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
++                      p_gpio_register->gpio_dats =
++                          (((p_value & mask) << GPIO_SHIFT16) & 0xffff0000);
++                      break;
++              case 3:
++                      p_gpio_register->gpio_datc =
++                          ~(((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
++                      p_gpio_register->gpio_dats =
++                          (((p_value & mask) << GPIO_SHIFT24) & 0xff000000);
++                      p_gpio_register += SZ_4K;       /* point next bank */
++                      p_gpio_register->gpio_datc =
++                          ~(p_value & (mask & 0x000000ff));
++                      p_gpio_register->gpio_dats =
++                          p_value & (mask & 0x000000ff);
++                      break;
++              }
++      }
++      return (GPIO_OK);
++}
 +
-+      if(chip_info->lbm == LOOPBACK_ENABLED)
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_ENABLED, MSP_GCR_MASK_LBM, 7);
-+      else
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_DISABLED, MSP_GCR_MASK_LBM, 7);
++int nomadik_gpio_altfuncenable(gpio_alt_function altfunc, char *dev_name)
++{
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++          return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
++}
 +
++int nomadik_gpio_altfuncdisable(gpio_alt_function altfunc, char *dev_name)
++{
++      nmdk_dbg_ftrace();
++      CHK_VALID_CALL;
++          return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
++}
 +
-+      if(chip_info->hierarchy == SPI_MASTER)
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_MASTER, MSP_GCR_MASK_TCKSEL, 14);
-+      else
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_SLAVE, MSP_GCR_MASK_TCKSEL, 14);
++EXPORT_SYMBOL(nomadik_gpio_setpinconfig);
++EXPORT_SYMBOL(nomadik_gpio_resetpinconfig);
++EXPORT_SYMBOL(nomadik_gpio_writepin);
++EXPORT_SYMBOL(nomadik_gpio_readpin);
++EXPORT_SYMBOL(nomadik_gpio_readblock);
++EXPORT_SYMBOL(nomadik_gpio_writeblock);
++EXPORT_SYMBOL(nomadik_gpio_altfuncenable);
++EXPORT_SYMBOL(nomadik_gpio_altfuncdisable);
 +
++/**
++ * Interrupt handling functions
++ */
++static void nomadik_gpio_intrenable(struct gpio_register *p_gpio_register,
++                                  uint32 mask, uint32 type)
++{
++      if (socdat->irqen) {
++              socdat->irqen(p_gpio_register, mask, type);
++      } else {
++              nmdk_error("irqen SOC specific function not configured");
++      }
++}
 +
-+      if(chip_info->proto_params.moto.clk_phase == SPI_CLK_ZERO_CYCLE_DELAY)
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_ZERO_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
++static void nomadik_gpio_intrdisable(struct gpio_register *p_gpio_register,
++                                   uint32 mask)
++{
++      if (socdat->irqdis)
++              socdat->irqdis(p_gpio_register, mask);
++      else {
++              nmdk_error("irqdis SOC specific function not configured");
++      }
++}
++/**
++   * @flag if 1 means enable, 0 means disable
++ */
++int nomadik_gpio_wakeupconfig(unsigned int irq, unsigned int flag)
++{
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
++      if (flag)
++      p_gpio_register->gpio_fwimsc |= mask;
 +      else
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_HALF_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
++      p_gpio_register->gpio_fwimsc &= (~mask);
++      return 0;
++}
++void nomadik_gpio_slpmreg_config(gpio_pin pin_id)
++{
++      struct gpio_register *p_gpio_register =
++                  (struct gpio_register *)get_irq_chip_data(GPIO_PIN2BLKIRQ(pin_id));
++      uint32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
++      p_gpio_register->gpio_slpm |= mask;
++}
 +
-+      if(chip_info->proto_params.moto.clk_pol == SPI_CLK_POL_IDLE_HIGH)
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_HIGH, MSP_GCR_MASK_TCKPOL,13);
-+      else
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_LOW, MSP_GCR_MASK_TCKPOL,13);
++static void nomadik_gpio_mask(unsigned int irq)
++{
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
 +
++      nmdk_dbg_ftrace();
++      nomadik_gpio_intrdisable(p_gpio_register, mask);
++}
 +
-+      /****   RCF Reg Config  *****/
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_IGNORE_RX_FRAME_SYNC_PULSE, MSP_RCF_MASK_RFSIG, 15);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_1BIT_DATA_DELAY, MSP_RCF_MASK_RDDLY, 13);
-+      if(chip_info->endian_rx == SPI_FIFO_LSB)
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_LSB , MSP_RCF_MASK_RENDN, 12);
-+      else
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_MSB , MSP_RCF_MASK_RENDN, 12);
++static void nomadik_gpio_unmask(unsigned int irq)
++{
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
 +
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, chip_info->controller.msp.data_size , MSP_RCF_MASK_RP1ELEN, 0);
++      nmdk_dbg_ftrace();
++      if (!irq_desc[irq].handler_data) {
++              nmdk_info
++                  ("for irq%d, configuruing default type as rising edge",
++                   irq);
++              irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
++      }
++      nomadik_gpio_intrenable(p_gpio_register, mask,
++                              (uint32) irq_desc[irq].handler_data);
++}
 +
-+      /****   TCF Reg Config  *****/
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_IGNORE_TX_FRAME_SYNC_PULSE, MSP_TCF_MASK_TFSIG, 15);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_1BIT_DATA_DELAY, MSP_TCF_MASK_TDDLY, 13);
-+      if(chip_info->endian_rx == SPI_FIFO_LSB)
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_LSB , MSP_TCF_MASK_TENDN, 12);
-+      else
-+              SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_MSB , MSP_TCF_MASK_TENDN, 12);
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, chip_info->controller.msp.data_size , MSP_TCF_MASK_TP1ELEN, 0);
++static void nomadik_gpio_intrack(unsigned int irq)
++{
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
 +
-+      /****   SRG Reg Config  *****/
-+      SPI_REG_WRITE_BITS(chip->regs.mspr.srg, sckdiv , MSP_SRG_MASK_SCKDIV , 0);
++      nmdk_dbg_ftrace();
++      p_gpio_register->gpio_ic = mask;
++}
 +
-+      /* Save controller_state */
-+      spi_set_ctldata(spi, chip);
-+      return status;
++/*
++ * callback function for gpio specific set_irq_type sys call
++ * This function will be called in the context of request_irq also
++ */
++static int nomadik_gpio_intrsettype(unsigned int irq, unsigned int type)
++{
++      gpio_config settype_config;
++      char *client_name = nomadik_gpio_owner(GPIO_PIN_FOR_IRQ(irq));
++      int ret;
 +
-+err_tx_clbk_request:
-+      if (chip->dma_info->tx_dmach != -1) {
-+              free_dma(chip->dma_info->tx_dmach);
++      nmdk_dbg_ftrace();
++      type&=SA_TRIGGER_MASK;
++      /* mistake proofing for invalid entry incase if you try to configure
++       * gpiopin interrupt for priority/fiq
++       */
++      if ( (type == SA_TRIGGER_MASK) ||
++           (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_RISING)) ||
++           (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH|SA_TRIGGER_FALLING)) ||
++           (type == (SA_TRIGGER_LOW|SA_TRIGGER_HIGH))) {
++              nmdk_error("Invalid IRQ type requested for irq%d", irq);
++              return -1;
 +      }
-+err_tx_dmach_request:
-+err_rx_clbk_request:
-+      if (chip->dma_info->rx_dmach != -1) {
-+              free_dma(chip->dma_info->rx_dmach);
++      if (!irq_desc[irq].action) {
++              nmdk_error("Trying to set type for unrequested irq%d", irq);
 +      }
-+err_rx_dmach_request:
-+      chip->dma_info->tx_dmach = -1;
-+      chip->dma_info->rx_dmach = -1;
-+err_config_params:
-+err_first_setup:
-+      if(chip->dma_info)
-+              kfree(chip->dma_info);
-+      kfree(chip);
-+err_request_irq:
-+      free_irq(drv_data->adev->irq[0], drv_data);
-+err_altfunc_enable:
-+      nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
-+err_out:
-+      switch(master->bus_num) {
-+              case MSP_0_CONTROLLER:  if(drv_data->flag_msp0->user == MSP_USER_SPI) {
-+                                              down(&drv_data->flag_msp0->lock);
-+                                              drv_data->flag_msp0->user = MSP_NO_USER;
-+                                              up(&drv_data->flag_msp0->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP0\n");
-+                                      }
-+                                      else {
-+                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp0->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+              case MSP_1_CONTROLLER:  if(drv_data->flag_msp1->user == MSP_USER_SPI) {
-+                                              down(&drv_data->flag_msp1->lock);
-+                                              drv_data->flag_msp1->user = MSP_NO_USER;
-+                                              up(&drv_data->flag_msp1->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP1\n");
-+                                      }
-+                                      else {
-+                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+              case MSP_2_CONTROLLER:  if(drv_data->flag_msp2->user == MSP_USER_SPI) {
-+                                              down(&drv_data->flag_msp2->lock);
-+                                              drv_data->flag_msp2->user = MSP_NO_USER;
-+                                              up(&drv_data->flag_msp2->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP2\n");
-+                                      }
-+                                      else {
-+                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
++      if (irq_desc[irq].handler_data) {
++              nmdk_info("irq %d type already set by %s", irq,
++                        client_name);
++              return (0);
++      }
++      settype_config.mode = GPIO_MODE_SOFTWARE;
++      settype_config.direction = GPIO_DIR_INPUT;
++      settype_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
++      settype_config.dev_name = client_name;
++      ret = gpio_setpinconfig(GPIO_PIN_FOR_IRQ(irq), &settype_config);
++      if (ret < 0) {
++              nmdk_error("Error in setting irq %d (err %d)", irq, ret);
++              return (ret);
++      }
++      nmdk_dbg("set_irq_type =%d", type);
++      if (type) {
++              irq_desc[irq].handler_data = (void *)(type & SA_TRIGGER_MASK);
++      } else {
++              nmdk_info
++                  ("%s Configuring default irq type to SA_TRIGGER_RISING",
++                   __FUNCTION__);
++              irq_desc[irq].handler_data = (void *)SA_TRIGGER_RISING;
 +      }
++      if ((SA_TRIGGER_RISING == (int)irq_desc[irq].handler_data) ||
++          (SA_TRIGGER_FALLING == (int)irq_desc[irq].handler_data))
++              irq_desc[irq].handle_irq = handle_edge_irq;
++      else if ((SA_TRIGGER_LOW == (int)irq_desc[irq].handler_data) ||
++               (SA_TRIGGER_HIGH == (int)irq_desc[irq].handler_data))
++              irq_desc[irq].handle_irq = handle_level_irq;
++      /* Standard api call set_irq_handler() cannot be used from
++         the contest of set_irq_type... deadlock occures */
 +
-+      return status;
++      return (GPIO_OK);
 +}
 +
-+#endif
-+
-+
-+int msp_probe(struct amba_device *adev, void *data)
++/**
++ * callback function for enable_irq_wake and disable_irq_wake system calls
++ *
++ * @flag if 1 means enable, 0 means disable
++ */
++static int nomadik_gpio_intrwake(unsigned int irq, unsigned int flag)
 +{
-+      int status = 0;
-+      struct device *dev;
-+      struct nmdk_spi_master_cntlr *platform_info;
++      struct gpio_register *p_gpio_register =
++          (struct gpio_register *)get_irq_chip_data(GPIO_PINIRQ2BLKIRQ(irq));
++      uint32 mask = 1UL << ((irq - MAX_CHIP_IRQ) % GPIO_PINS_PER_BLOCK);
++      unsigned int type = (uint32) irq_desc[irq].handler_data;
 +
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+      struct spi_master *master;
-+      struct driver_data *drv_data = NULL;    /*Data for this driver */
-+      struct resource *res;
-+      int irq;
-+#endif
-+      dev = &adev->dev;
-+      platform_info = (struct nmdk_spi_master_cntlr *)(dev->platform_data);
-+      if (platform_info == NULL) {
-+              dev_err(&adev->dev, "probe - no platform data supplied\n");
-+              status = -ENODEV;
-+              goto err_no_pdata;
++      if (socdat->irqwake) {
++              if (!type)
++                      type = SA_TRIGGER_RISING;
++              if (!flag)
++                      type = 0xff;    /* to disable wakeup irq */
++              socdat->irqwake(p_gpio_register, mask, type);
++      } else {
++              nmdk_error("irqwake SOC specific function not configured");
++              return (-1);
 +      }
++      return (0);
++}
 +
-+      if(platform_info->id == MSP_0_CONTROLLER) {
-+              flag_msp0= kmalloc(sizeof(msp_flag), GFP_KERNEL);
-+              if(!flag_msp0) {
-+                      status = -ENOMEM;
-+                      printk(KERN_ERR "No mem available for MSP0 flag\n");
-+                      goto err_msp0;
-+              }
-+              flag_msp0->user = MSP_NO_USER;
-+              init_MUTEX(&flag_msp0->lock);
-+              init_waitqueue_head(&wait[0]);
-+              nmdk_dbg("In msp_probe flag_msp0 is %d\n", flag_msp0->user);
-+      }
-+      if(platform_info->id == MSP_1_CONTROLLER) {
-+              flag_msp1= kmalloc(sizeof(msp_flag), GFP_KERNEL);
-+              if(!flag_msp1) {
-+                      status = -ENOMEM;
-+                      printk(KERN_ERR "No mem available for MSP1 flag\n");
-+                      goto err_msp1;
-+              }
-+              flag_msp1->user = MSP_NO_USER;
-+              init_MUTEX(&flag_msp1->lock);
-+              init_waitqueue_head(&wait[1]);
-+              nmdk_dbg("In msp_probe flag_msp1 is %d\n", flag_msp1->user);
-+      }
-+      if(platform_info->id == MSP_2_CONTROLLER) {
-+              flag_msp2= kmalloc(sizeof(msp_flag), GFP_KERNEL);
-+              if(!flag_msp2) {
-+                      status = -ENOMEM;
-+                      printk(KERN_ERR "No mem available for MSP2 flag\n");
-+                      goto err_msp2;
++struct irq_chip nomadik_gpio_chip = {
++      .ack = nomadik_gpio_intrack,
++      .mask = nomadik_gpio_mask,
++      .unmask = nomadik_gpio_unmask,
++      .set_type = nomadik_gpio_intrsettype,
++      .set_wake = nomadik_gpio_intrwake,
++};
++
++static void nomadik_gpio_intr_handler(u32 irq, struct irq_desc *desc)
++{
++      struct gpio_register *p_gpio_reg =
++          (struct gpio_register *)get_irq_chip_data(irq);
++      unsigned long mis = p_gpio_reg->gpio_mis;
++
++      nmdk_dbg2("%d intr desc %p", (irq - IRQ_GPIO0), desc);
++      irq = IRQNO_GPIO((irq - IRQ_GPIO0) * GPIO_PINS_PER_BLOCK);
++      desc = irq_desc + irq;
++      while (mis) {
++              if (mis & 1) {
++                      nmdk_dbg2("handling irq %d", irq);
++                      desc->handle_irq(irq, desc);
 +              }
-+              flag_msp2->user = MSP_NO_USER;
-+              init_MUTEX(&flag_msp2->lock);
-+              init_waitqueue_head(&wait[2]);
-+              nmdk_dbg("In msp_probe flag_msp2 is %d\n", flag_msp2->user);
++              irq++;
++              desc++;
++              mis >>= 1;
 +      }
++}
++
++static int nomadik_gpio_probe(struct amba_device *dev, void *id)
++{
++      int i, ret;
++      struct gpio_register *p_gpio_register;
++
 +      nmdk_dbg_ftrace();
 +
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+      /* Allocate master with space for drv_data */
-+      master = spi_alloc_master(dev, sizeof(struct driver_data));
-+      if (master == NULL) {
-+              dev_err(&adev->dev, "probe - cannot alloc spi_master\n");
-+              status = -ENOMEM;
-+              goto err_no_mem;
++      socdat = dev->dev.platform_data;
++
++      if (!socdat) {
++              nmdk_error("platform_data struct for %s not initialized",
++                         dev->dev.bus_id);
++              ret = -1;
++              goto out;
 +      }
++      ret = amba_request_regions(dev, NULL);
++      if (ret)
++              goto out;
 +
-+      drv_data = spi_master_get_devdata(master);
-+      drv_data->master = master;
-+      drv_data->master_info = platform_info;
-+      drv_data->adev = adev;
++      for (i = 0; i < (dev->irq[1] - dev->irq[0]); i++) {
++              set_irq_chip_data((i + dev->irq[0]),
++                               (void *)ioremap((int)dev->res.start +
++                                               (i * SZ_4K), SZ_4K));
 +
-+      drv_data->dma_ongoing = 0;
++              p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
 +
-+      /*Fetch the Resources, using platform data */
++              if (!p_gpio_register) {
++                      ret = -ENOMEM;
++                      goto res_out;
++              }
 +
-+      res = &(adev->res);
-+      if (res == NULL) {
-+              dev_err(&adev->dev, "probe - MEM resources not defined\n");
-+              status = -ENODEV;
-+              goto err_no_iores;
-+      }
-+      /*Get Hold of Device Register Area... */
-+      drv_data->regs = ioremap(res->start, (res->end - res->start));
-+      if (drv_data->regs == NULL) {
-+              status = -ENODEV;
-+              goto err_no_iores;
-+      }
-+      irq = adev->irq[0];
-+      if (irq <= 0) {
-+              status = -ENODEV;
-+              goto err_no_iores;
++              set_irq_chained_handler((i + dev->irq[0]),
++                                      nomadik_gpio_intr_handler);
 +      }
 +
-+      /*Set flag for MSPx*/
-+      switch(platform_info->id) {
-+              case MSP_0_CONTROLLER:
-+                      drv_data->flag_msp0 = (spi_msp_user *)flag_msp0;
-+                      break;
-+              case MSP_1_CONTROLLER:
-+                      drv_data->flag_msp1 = (spi_msp_user *)flag_msp1;
-+                      break;
-+              case MSP_2_CONTROLLER:
-+                      drv_data->flag_msp2 = (spi_msp_user *)flag_msp2;
-+                      break;
-+              default:
-+                      dev_err(&adev->dev, "unknown controller  Id  %d\n", platform_info->id);
-+                      status = -EINVAL;
-+                      break;
++      for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
++              set_irq_chip(i, &nomadik_gpio_chip);
++              set_irq_handler(i, handle_level_irq);
++              set_irq_flags(i, IRQF_VALID);
++              set_irq_chip_data(i, NULL);     /*clear gpio client name */
++              irq_desc[i].handler_data = NULL;        /*clear gpio irq_type */
 +      }
 +
-+      if(status == -EINVAL)
-+              goto err_no_irqres;
++      nmdk_info("Module initialized Ver(" GPIO_VER ")");
++      return 0;
 +
-+      nmdk_dbg(":::: MSP Controller = %d\n", platform_info->id);
-+      drv_data->execute_cmd = msp_controller_cmd;
-+      drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
-+      master->setup = nomadik_msp_setup;
++      res_out:
++      for (; 0 == i; i--) {
++              p_gpio_register = get_irq_chip_data(i + dev->irq[0]);
 +
-+      /*Required Info for an SPI controller */
-+      /*Bus Number Which has been Assigned to this SPI controller on this board */
-+      master->bus_num = (u16) platform_info->id;
-+      master->num_chipselect = platform_info->num_chipselect;
-+      master->cleanup = nomadik_spi_cleanup;
-+      master->transfer = nomadik_spi_transfer;
++              set_irq_handler((i + dev->irq[0]), handle_bad_irq);
++              if (p_gpio_register)
++                      iounmap((void __iomem *)p_gpio_register);
++              set_irq_chip_data((i + dev->irq[0]), NULL);
 +
-+      nmdk_dbg(":::: BUSNO: %d\n", master->bus_num);
-+      /* Initialize and start queue */
-+      status = init_queue(drv_data);
-+      if (status != 0) {
-+              dev_err(&adev->dev, "probe - problem initializing queue\n");
-+              goto err_init_queue;
 +      }
-+      status = start_queue(drv_data);
-+      if (status != 0) {
-+              dev_err(&adev->dev, "probe - problem starting queue\n");
-+              goto err_start_queue;
++      amba_release_regions(dev);
++      out:
++      return (ret);
++}
++
++static int nomadik_gpio_remove(struct amba_device *dev)
++{
++      int i;
++
++      nmdk_dbg_ftrace();
++      for (i = (MAX_GPIO_IRQ - GPIO_TOTAL_PINS); i < MAX_GPIO_IRQ; i++) {
++              set_irq_chip(i, NULL);
++              set_irq_chip_data(i, NULL);
 +      }
-+      /*Initialize tasklet for DMA transfer*/
-+      tasklet_init(&drv_data->spi_dma_tasklet, nomadik_spi_tasklet,
-+                   (unsigned long)drv_data);
 +
-+      /* Register with the SPI framework */
-+      platform_set_drvdata(adev, drv_data);
-+      status = spi_register_master(master);
-+      if (status != 0) {
-+              dev_err(&adev->dev, "probe - problem registering spi master\n");
-+              goto err_spi_register;
++      for (i = dev->irq[0]; i < dev->irq[1]; i++) {
++              set_irq_handler(i, handle_bad_irq);
++              iounmap((void __iomem *)get_irq_chip_data(i));
++              set_irq_chip_data(i, NULL);
 +      }
-+      dev_dbg(dev, "probe succeded\n");
-+      nmdk_dbg(" Bus Number = %d, IRQ Line = %d, Virtual Addr: %x\n", master->bus_num, irq, (u32)(drv_data->regs) );
++      amba_release_regions(dev);
++      socdat = NULL;
++      nmdk_info("Module removed");
 +      return 0;
-+#endif
-+      return status;
-+
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+      err_init_queue:
-+      err_start_queue:
-+      err_spi_register:
-+      destroy_queue(drv_data);
-+      err_no_irqres:
-+      err_no_iores:
-+      spi_master_put(master);
-+      err_no_mem:
-+#endif
-+      if((flag_msp2) && (platform_info->id == MSP_2_CONTROLLER))
-+              kfree(flag_msp2);
-+      err_msp2:
-+      if((flag_msp1) && (platform_info->id == MSP_1_CONTROLLER))
-+              kfree(flag_msp1);
-+      err_msp1:
-+      if((flag_msp0) && (platform_info->id == MSP_0_CONTROLLER))
-+              kfree(flag_msp0);
-+      err_msp0:
-+        err_no_pdata:
-+      return status;
-+
 +}
 +
-+static int msp_remove(struct amba_device *adev)
++#if (defined CONFIG_PM && defined __STN_8815)
++static int nomadik_gpio_suspend(struct amba_device *dev, pm_message_t state)
 +{
-+      struct driver_data *drv_data = platform_get_drvdata(adev);
-+      struct device *dev = &adev->dev;
-+      struct nmdk_spi_master_cntlr *platform_info;
-+      int irq;
-+      int status = 0;
-+      if (!drv_data)
-+              return 0;
-+
-+      platform_info = dev->platform_data;
++      unsigned int i;
++      struct gpio_register *p_gpio_register;
++      struct gpio_pm_context *gpio_pm;;
 +
-+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
-+      /* Remove the queue */
-+      status = destroy_queue(drv_data);
-+      if (status != 0) {
-+              dev_err(&adev->dev, "queue remove failed (%d)\n", status);
-+              return status;
++      nmdk_dbg_ftrace();
++      dev->dev.driver_data =
++          kmalloc(sizeof(struct gpio_pm_context) * GPIO_BLOCKS_COUNT,
++                  GFP_KERNEL);
++      gpio_pm = (struct gpio_pm_context *)dev->dev.driver_data;
++      if (!gpio_pm) {
++              nmdk_error("Unable to alocate memory %s failed...",
++                         __FUNCTION__);
 +      }
-+      drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
-+
-+      irq = adev->irq[0];
-+      if (irq >= 0)
-+              free_irq(irq, drv_data);
-+
-+      /* Release map resources */
-+      iounmap(drv_data->regs);
-+      tasklet_disable(&drv_data->pump_transfers);
-+      tasklet_kill(&drv_data->spi_dma_tasklet);
-+      nomadik_gpio_altfuncdisable(platform_info->gpio_alt_func, platform_info->device_name);
++      for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
++              p_gpio_register =
++                  (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
++              gpio_pm[i].slpm = p_gpio_register->gpio_slpm;
++              gpio_pm[i].rwimsc = p_gpio_register->gpio_rwimsc;
++              gpio_pm[i].fwimsc = p_gpio_register->gpio_fwimsc;
++              gpio_pm[i].rimsc = p_gpio_register->gpio_rimsc;
++              gpio_pm[i].fimsc = p_gpio_register->gpio_fimsc;
++      }
++      return 0;
++}
 +
-+      /* Disconnect from the SPI framework */
-+      spi_unregister_master(drv_data->master);
-+      spi_master_put(drv_data->master);
++static int nomadik_gpio_resume(struct amba_device *dev)
++{
++      unsigned int i;
++      struct gpio_register *p_gpio_register;
++      struct gpio_pm_context *gpio_pm =
++          (struct gpio_pm_context *)dev->dev.driver_data;
 +
-+      /* Prevent double remove */
-+      platform_set_drvdata(adev, NULL);
-+      dev_dbg(&adev->dev, "remove succeded\n");
-+#endif
-+      if(platform_info->id == MSP_0_CONTROLLER) {
-+              if(flag_msp0)
-+                      kfree(flag_msp0);
-+              else
-+                      printk("MSP Error:why flag_msp0==NULL???");
-+      }
-+      if(platform_info->id == MSP_1_CONTROLLER) {
-+              if(flag_msp1)
-+                      kfree(flag_msp1);
-+              else
-+                      printk("MSP Error:why flag_msp1==NULL???");
-+      }
-+      if(platform_info->id == MSP_2_CONTROLLER) {
-+              if(flag_msp2)
-+                      kfree(flag_msp2);
-+              else
-+                      printk("MSP Error:why flag_msp2==NULL???");
++      nmdk_dbg_ftrace();
++      for (i = 0; i < GPIO_BLOCKS_COUNT; i++) {
++              p_gpio_register =
++                  (struct gpio_register *)get_irq_chip_data(i + dev->irq[0]);
++              p_gpio_register->gpio_slpm = gpio_pm[i].slpm;
++              p_gpio_register->gpio_rwimsc = gpio_pm[i].rwimsc;
++              p_gpio_register->gpio_fwimsc = gpio_pm[i].fwimsc;
++              p_gpio_register->gpio_rimsc = gpio_pm[i].rimsc;
++              p_gpio_register->gpio_fimsc = gpio_pm[i].fimsc;
 +      }
-+
++      kfree(gpio_pm);
 +      return 0;
 +}
++#else
++#define nomadik_gpio_suspend NULL
++#define nomadik_gpio_resume NULL
++#endif
 +
-+static struct amba_id msp_ids[] = {
++static struct amba_id nomadik_gpio_ids[] = {
 +      {
-+       .id = MSP_PER_ID,
-+       .mask = MSP_PER_MASK,
++       .id = GPIO_PER_ID,
++       .mask = GPIO_PER_MASK,
 +       },
 +      {0, 0},
 +};
 +
-+static struct amba_driver msp_driver = {
++static struct amba_driver gpio_driver = {
 +      .drv = {
-+              .name = "MSP",
++              .owner = THIS_MODULE,
++              .name = "gpio",
 +              },
-+      .id_table = msp_ids,
-+      .probe = msp_probe,
-+      .remove = msp_remove
++      .probe = nomadik_gpio_probe,
++      .remove = nomadik_gpio_remove,
++      .suspend = nomadik_gpio_suspend,
++      .resume = nomadik_gpio_resume,
++      .id_table = nomadik_gpio_ids,
 +};
 +
-+EXPORT_SYMBOL(nomadik_msp_configure);
-+EXPORT_SYMBOL(nomadik_msp_send_data);
-+EXPORT_SYMBOL(nomadik_msp_receive_data);
-+EXPORT_SYMBOL(nomadik_msp_transceive_data);
-+EXPORT_SYMBOL(nomadik_msp_enable);
-+EXPORT_SYMBOL(nomadik_msp_disable);
-+EXPORT_SYMBOL(nomadik_msp_flush_input);
-+
-+static int __init nomadik_msp_mod_init(void)
++static int __init nomadik_gpio_init(void)
 +{
-+      return amba_driver_register(&msp_driver);
++      return amba_driver_register(&gpio_driver);
 +}
 +
-+static void __exit nomadik_msp_exit(void)
++static void __exit nomadik_gpio_exit(void)
 +{
-+      amba_driver_unregister(&msp_driver);
-+      return;
++      amba_driver_unregister(&gpio_driver);
 +}
-+module_init(nomadik_msp_mod_init);
-+module_exit(nomadik_msp_exit);
 +
-+MODULE_AUTHOR("STMicroelectronics Pvt Ltd");
-+MODULE_DESCRIPTION("NOMADIK MSP driver");
++EXPORT_SYMBOL(nomadik_gpio_intrsettype);
++EXPORT_SYMBOL(nomadik_gpio_mask);
++EXPORT_SYMBOL(nomadik_gpio_unmask);
++
++module_init(nomadik_gpio_init);
++module_exit(nomadik_gpio_exit);
++
++MODULE_AUTHOR("Prafulla WADASKAR <prafulla.wadaskar@st.com>");
++MODULE_DESCRIPTION("Nomadik GPIO Driver");
 +MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/msp.h ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.h
---- linux-2.6.20/arch/arm/mach-nomadik/msp.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/msp.h    2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,383 @@
-+/*linux/drivers/char/nomadik-msp.h
-+ *
-+ *  Driver for Nomadik STN8810 MSP device.  Note that this module MUST NOT
-+ *  attempt to load before the i2c and gpio drivers are loaded.
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/irq.c
+@@ -0,0 +1,231 @@
++/*
++ *  linux/arch/arm/mach-nomadik/irq.c
 + *
-+ *  Copyright 2006 STMicroelectronics Pvt. Ltd.
++ * Copyright (C) STMicroelectronics
 + *
-+ *  This program is free sofstware; 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 free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
 + *
++ * Author     : Prafulla WADASKAR <prafulla.wadaskar@st.com>
++ * Reference  : Documentation/arm/STM-Nomadik/irq_usrguide.txt
 + */
++#include <linux/kernel_stat.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/debug.h>
 +
-+#ifndef NMDK_MSP_HEADER
-+#define NMDK_MSP_HEADER
++#define VIC_VER       "2.0.0"
++#define VIC_NAME      "VIC"
 +
-+struct msp_register
-+{
-+        u32 fifo;
-+        u32 global_ctrl;
-+        u32 tx_config;
-+        u32 rx_config;
-+        u32 srg_ctrl;
-+        u32 status;
-+        u32 dma_ctrl;
-+        u32 reserved0;
-+        u32 irq_mask;
-+        u32 raw_irq_status;
-+        u32 masked_irq_status;
-+        u32 irq_clear;
-+        u32 multichannel_ctrl;
-+        u32 rx_compare_val;
-+        u32 rx_compare_mask;
-+        u32 reserved1;
-+        u32 tx_enable_ch0;
-+        u32 tx_enable_ch1;
-+        u32 tx_enable_ch2;
-+        u32 tx_enable_ch3;
-+        u32 reserved2[4];
-+        u32 rx_enable_ch0;
-+        u32 rx_enable_ch1;
-+        u32 rx_enable_ch2;
-+        u32 rx_enable_ch3;
-+        u32 reserved3[4];
-+        u32 test_ctrl;
-+        u32 integration_test_input;
-+        u32 integration_test_output;
-+        u32 test_data;
-+};
++#ifndef VIC_DEBUG
++#define VIC_DEBUG 0
++#endif
 +
-+struct msp_context {
-+      u8  direction;
-+      u8  mode;
-+      u8  protocol;
-+      int  frame_freq;
-+      int  frame_size;
-+      enum msp_data_size requested_data_size;
-+      enum msp_data_size actual_data_size;
++#define NMDK_DEBUG    VIC_DEBUG       /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  VIC_NAME      /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+      u32 rx_channel_0_enable;
-+      u32 rx_channel_1_enable;
-+      u32 rx_channel_2_enable;
-+      u32 rx_channel_3_enable;
-+      u32 tx_channel_0_enable;
-+      u32 tx_channel_1_enable;
-+      u32 tx_channel_2_enable;
-+      u32 tx_channel_3_enable;
-+      u32 multichannel_ctrl_reg;
-+      u32 rx_compare_mask_reg;
-+      u32 irq_mask_reg;
++struct vic_basic_registers {
++      u32 irqsr;              /* IRQ Status*/
++      u32 fiqsr;              /* FIQ Status*/
++      u32 ris;                /* Raw Interrupt status*/
++      u32 isel;               /* Interrupt select*/
++      u32 iens;               /* Interrupt enable set*/
++      u32 ienc;               /* Interrupt enable clear*/
++      u32 swisr;              /* Software interrupt*/
++      u32 swicr;              /* Software interrupt clear*/
++};
 +
-+      u8  compression_mode;
-+      u8  expansion_mode;
-+      u8  coprocessor_mode;
-+      int msp_disable;
++struct vic_register {
++      struct vic_basic_registers bank[(MAXIRQNUM/32) +1];
++      u32 per;                /* Protection enable*/
++#if defined(__STN_8815)
++      u32 reserved_1[(0x50 - 0x44) >> 2];     /* Reserved*/
++      u32 isr_var;            /* ISR Vector address*/
++      u32 isr_dvar;           /* ISR Default vector address*/
++      u32 reserved_2[(0x100 - 0x58) >> 2];    /* Reserved*/
++#elif defined(__STN_8810)
++      u32 reserved_1[(0x30 - 0x24) >> 2];     /* Reserved*/
++      u32 isr_var;            /* ISR Vector address*/
++      u32 isr_dvar;           /* ISR Default vector address*/
++      u32 reserved_2[(0x100 - 0x38) >> 2];    /* Reserved*/
++#endif
++      u32 var[VIC_VECTORED_IRQ_NUM];  /* Vector address 0-15*/
++      u32 reserved_3[(0x200 - 0x140) >> 2];   /* Reserved*/
++      u32 vcr[VIC_VECTORED_IRQ_NUM];  /* Vector control 0-15*/
++      u32 reserved_4[(0x300 - 0x240) >> 2];   /* Reserved*/
++      u32 itcr;               /* Test Control register*/
++      u32 itip_1;             /* Test input nVICIRQIN/nVICFIQIN*/
++      u32 itip_2;             /* Test input VICVECADDRIN*/
++      u32 itop_1;             /* Test output nVICIRQ/nVICFIQ*/
++      u32 itop_2;             /* Test output VICVECADDROUT*/
++      u32 reserved_5[(0xFE0 - 0x314) >> 2];   /* Reserved*/
++      u32 periph_id_0;        /* Peripheral id: bits 7:0*/
++      u32 periph_id_1;        /* Peripheral id: bits 15:8*/
++      u32 periph_id_2;        /* Peripheral id: bits 23:16*/
++      u32 periph_id_3;        /* Peripheral id: bits 31:24*/
++      u32 pcell_id_0;         /* PrimeCell id: bits 7:0*/
++      u32 pcell_id_1;         /* PrimeCell id: bits 15:8*/
++      u32 pcell_id_2;         /* PrimeCell id: bits 23:16*/
++      u32 pcell_id_3;         /* PrimeCell id: bits 31:24*/
 +};
 +
-+ struct msp_mode_status
-+{
-+      int work_mode;
-+      int phase_mode;
-+      int stereo_mode;
-+      volatile u16 *it_mono_data_flow;
-+      volatile u32 *it_stereo_data_flow;
-+      volatile u32 it_halfwords_count;
-+      volatile u32 flow_error_count;  
-+} msp_mode_status;
++extern struct irq_desc irq_desc[];    /* interrupt description table */
++static volatile struct vic_register *p_vic_register =
++                      (struct vic_register *)IO_ADDRESS(NOMADIK_IC_BASE);
 +
++static int nomadik_vic_set_type(unsigned int irq, unsigned int type);
++static DEFINE_SPINLOCK(vic_lock);
 +
-+/* Single or dual phase mode */
-+enum
++static void nomadik_vic_priority_mask(unsigned int irq)
 +{
-+      MSP_SINGLE_PHASE,
-+      MSP_DUAL_PHASE
-+};
-+
++      u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
++      u32 mask = 1UL<<irq%32;
++      /*
++       * Reading the VIC_VAR register updates the interrupt controllers
++       * hardware priority register to mask lower priority interrupts.
++       * reading is done in entry-macro.S
++       */
++      p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
++      p_vic_register->bank[irq/32].ienc |= mask;
++}
 +
-+/* Transmit/Receive shifter status
-+-----------------------------------*/
-+enum
++static void nomadik_vic_priority_unmask(unsigned int irq)
 +{
-+        MSP_SxHIFTER_IDLE   = 0,
-+        MSP_SHIFTER_WORKING = 1
-+};
++      u8 priority_level = (u8)(((irq_desc[irq].action->flags)>>4) & 0x0f);
++      u32 mask = 1UL<<irq%32;
 +
++      p_vic_register->vcr[priority_level] |= VIC_VECTORED_IRQ_EN;
++      p_vic_register->bank[irq/32].iens |= mask;
++      /*
++       * Write to the VIC_VAR register.
++       * This clears the respective interrupt in the internal interrupt
++       * priority hardware.
++       */
++      p_vic_register->isr_var = (u32)NULL;
++}
 +
-+/* Transmit/Receive FIFO status
-+---------------------------------*/
-+enum
-+{
-+      MSP_FIFO_FULL,
-+      MSP_FIFO_PART_FILLED,
-+      MSP_FIFO_EMPTY
++static struct irq_chip nomadik_vic_priority_chip = {
++      .ack = nomadik_vic_priority_mask,
++      .mask = nomadik_vic_priority_mask,
++      .unmask = nomadik_vic_priority_unmask,
++      .set_type = nomadik_vic_set_type
 +};
 +
++static void nomadik_vic_mask(unsigned int irq)
++{
++      u32 mask = 1UL<<irq%32;
++      p_vic_register->bank[irq/32].ienc |= mask;
++}
 +
-+/* Frame length
-+------------------*/
-+enum
++static void nomadik_vic_unmask(unsigned int irq)
 +{
-+      MSP_FRAME_LENGTH_1              = 0,
-+      MSP_FRAME_LENGTH_2              = 1,
-+      MSP_FRAME_LENGTH_4              = 3,
-+      MSP_FRAME_LENGTH_8              = 7,
-+      MSP_FRAME_LENGTH_12             = 11,
-+      MSP_FRAME_LENGTH_16             = 15,
-+      MSP_FRAME_LENGTH_20             = 19,
-+      MSP_FRAME_LENGTH_32             = 31,
-+      MSP_FRAME_LENGTH_48             = 47,
-+      MSP_FRAME_LENGTH_64             = 63
++      u32 mask = 1UL<<irq%32;
++      p_vic_register->bank[irq/32].iens |= mask;
++}
++
++static struct irq_chip nomadik_vic_chip = {
++      .ack = nomadik_vic_mask,
++      .mask = nomadik_vic_mask,
++      .unmask = nomadik_vic_unmask,
++      .set_type = nomadik_vic_set_type
 +};
 +
-+/* Element length */
-+enum
++/**
++ * nomadik_vic_set_type - To enable/disable/change priority logic
++ *
++ * callback function for set_irq_type sys call
++ * This function will be called in the context of request_irq.
++ * This function is used to configure the interrupt priotity requested
++ * through request_irq sytem call
++ *
++ * This function can be invoked by set_irq_type sys call ,using which
++ * you can enable/disable/change preprogrammed priority
++ *
++ * Note: this function will NOT be invoked if interrupt is requested as
++ * shared irq (i.e. SA_SHIRQ is specifed during requerst_irq),
++ */
++static int nomadik_vic_set_type(unsigned int irq, unsigned int type)
 +{
-+      MSP_ELEM_LENGTH_8               = 0,
-+      MSP_ELEM_LENGTH_10              = 1,
-+      MSP_ELEM_LENGTH_12              = 2,
-+      MSP_ELEM_LENGTH_14              = 3,
-+      MSP_ELEM_LENGTH_16              = 4,
-+      MSP_ELEM_LENGTH_20              = 5,
-+      MSP_ELEM_LENGTH_24              = 6,
-+      MSP_ELEM_LENGTH_32              = 7
-+};
++      struct irq_desc *desc;
++      struct irq_chip *vic_chip;
++      unsigned long flags;
 +
++      u8 priority_level;
 +
-+/* Data delay (in bit clock cycles)
-+---------------------------------------*/
-+enum
-+{
-+      MSP_DELAY_0                     = 0,
-+      MSP_DELAY_1                     = 1,
-+      MSP_DELAY_2                     = 2,
-+      MSP_DELAY_3                     = 3
-+};
++      nmdk_dbg_ftrace();
++      if (!irq_desc[irq].action) return(-1); /*if irq not configured*/
++      /*
++       * Priority logic does not work for interrupt configured with
++       * SA_TIMER flag, hence exit if SA_TIMER flag is set for irq
++       */
++      if (irq_desc[irq].action->flags & IRQF_TIMER) return(-1);
++      if ((type & SA_NMDK_PRIORITYIRQ) != SA_NMDK_PRIORITYIRQ) return(-1);
++      /*
++       * if this function is invoked by set_irq_type call
++       * then store input type as flags
++       */
++      if (type > SA_TRIGGER_MASK) irq_desc[irq].action->flags = type;
++      /*process irq priority configuration*/
++      priority_level = (u8)(((irq_desc[irq].action->flags)>>24) & 0x0f);
++      if (p_vic_register->vcr[priority_level] & VIC_VECTORED_IRQ_EN) {
++              nmdk_info("priority change for active irq%d", irq);
++      }
++      /*configure vic for vectored priority interrupt request*/
++      p_vic_register->var[priority_level] = irq;
++      p_vic_register->vcr[priority_level] = irq;
++      /* configure appropriate chip pointer*/
++      desc = irq_desc + irq;
++      if (!priority_level) {
++              p_vic_register->vcr[priority_level] &= ~VIC_VECTORED_IRQ_EN;
++              vic_chip = &nomadik_vic_chip;
++      } else
++              vic_chip = &nomadik_vic_priority_chip;
++      spin_lock_irqsave(&vic_lock, flags);
++      desc->chip = vic_chip;
++      spin_unlock_irqrestore(&vic_lock, flags);
 +
++      nmdk_info("Configured PL%2d for irq%d", priority_level, irq);
++      return (0);
++}
 +
-+/* Configurations of clocks (transmit, receive or sample rate generator)
-+-------------------------------------------------------------------------*/
-+enum
++static void nomadik_vic_configure(unsigned int irq)
 +{
-+      MSP_RISING_EDGE                 = 0,
-+      MSP_FALLING_EDGE                = 1
-+};
++      u32 mask = 1UL<<irq%32;
 +
-+/* Protocol dependant parameters list */
-+struct msp_protocol_desc
++      nmdk_dbg("%s for irq %d", __FUNCTION__, irq);
++      /* Select interrupt line as Irq (no FIQ used currently)*/
++      p_vic_register->bank[irq/32].isel &= ~mask;
++}
++
++void __init nomadik_vic_init(void)
 +{
-+        u32 phase_mode;
-+        u32 frame_len_1;
-+        u32 frame_len_2;
-+        u32 element_len_1;
-+        u32 element_len_2;
-+        u32 data_delay;
-+        u32 tx_clock_edge;
-+        u32 rx_clock_edge;
-+};
-+
-+#define RX_ENABLE_MASK         0x00000001
-+#define RX_FIFO_ENABLE_MASK    0x00000002 
-+#define RX_FRAME_SYNC_MASK     0x00000004
-+#define DIRECT_COMPANDING_MASK 0x00000008
-+#define RX_SYNC_SEL_MASK       0x00000010
-+#define RX_CLK_POL_MASK        0x00000020
-+#define RX_CLK_SEL_MASK        0x00000040
-+#define LOOPBACK_MASK          0x00000080
-+#define TX_ENABLE_MASK         0x00000100
-+#define TX_FIFO_ENABLE_MASK    0x00000200
-+#define TX_FRAME_SYNC_MASK     0x00000400
-+#define TX_SYNC_SEL_MASK       0x00001800
-+#define TX_CLK_POL_MASK        0x00002000
-+#define TX_CLK_SEL_MASK        0x00004000
-+#define TX_EXTRA_DELAY_MASK    0x00008000
-+#define SRG_ENABLE_MASK        0x00010000
-+#define SRG_CLK_POL_MASK       0x00020000
-+#define SRG_CLK_SEL_MASK       0x000C0000
-+#define FRAME_GEN_EN_MASK      0x00100000
-+#define SPI_CLK_MODE_MASK      0x00600000
-+#define SPI_BURST_MODE_MASK    0x00800000
-+
-+#define RXEN_BIT              0
-+#define RFFEN_BIT             1
-+#define RFSPOL_BIT            2
-+#define DCM_BIT               3
-+#define RFSSEL_BIT            4
-+#define RCKPOL_BIT            5
-+#define RCKSEL_BIT            6
-+#define LBM_BIT               7
-+#define TXEN_BIT              8
-+#define TFFEN_BIT             9
-+#define TFSPOL_BIT            10
-+#define TFSSEL_BIT            11
-+#define TCKPOL_BIT            13
-+#define TCKSEL_BIT            14
-+#define TXDDL_BIT             15
-+#define SGEN_BIT              16
-+#define SCKPOL_BIT            17
-+#define SCKSEL_BIT            18
-+#define FGEN_BIT              20
-+#define SPICKM_BIT            21
-+
-+#define msp_rx_clkpol_bit(n)     ((n & 1) << RCKPOL_BIT)
-+#define msp_tx_clkpol_bit(n)     ((n & 1) << TCKPOL_BIT)
-+#define msp_spi_clk_mode_bits(n) ((n & 3) << SPICKM_BIT)
-+
-+
-+/* Use this to clear the clock mode bits to non-spi */
-+#define MSP_NON_SPI_CLK_MASK 0x00600000  
-+
-+#define P1ELEN_BIT            0
-+#define P1FLEN_BIT            3
-+#define DTYP_BIT              10
-+#define ENDN_BIT              12
-+#define DDLY_BIT              13
-+#define FSIG_BIT              15
-+#define P2ELEN_BIT            16
-+#define P2FLEN_BIT            19
-+#define P2SM_BIT              26
-+#define P2EN_BIT              27
-+
-+#define msp_p1_elem_len_bits(n) (n & 0x00000007)
-+#define msp_p2_elem_len_bits(n)  (((n) << P2ELEN_BIT) & 0x00070000)
-+#define msp_p1_frame_len_bits(n) (((n) << P1FLEN_BIT) & 0x00000378)
-+#define msp_p2_frame_len_bits(n) (((n) << P2FLEN_BIT) & 0x03780000)
-+#define msp_data_delay_bits(n)   (((n) << DDLY_BIT) & 0x00003000)
-+#define msp_data_type_bits(n)    (((n) << DTYP_BIT) & 0x00000600)
-+#define msp_p2_start_mode_bit(n) (n << P2SM_BIT)
-+#define msp_p2_enable_bit(n)     (n << P2EN_BIT)
-+
-+/* Flag register
-+--------------------*/
-+#define RX_BUSY       0x00000001
-+#define RX_FIFO_EMPTY 0x00000002
-+#define RX_FIFO_FULL  0x00000004
-+#define TX_BUSY       0x00000008
-+#define TX_FIFO_EMPTY 0x00000010
-+#define TX_FIFO_FULL  0x00000020
-+
-+#define RBUSY_BIT             0
-+#define RFE_BIT                       1
-+#define RFU_BIT                       2
-+#define TBUSY_BIT             3
-+#define TFE_BIT                       4
-+#define TFU_BIT                       5
-+
-+/* Multichannel control register
-+---------------------------------*/
-+#define RMCEN_BIT             0
-+#define RMCSF_BIT             1
-+#define RCMPM_BIT             3
-+#define TMCEN_BIT             5
-+#define TNCSF_BIT             6
-+
-+/* Sample rate generator register
-+------------------------------------*/
-+#define SCKDIV_BIT            0
-+#define FRWID_BIT             10
-+#define FRPER_BIT             16
-+
-+#define SCK_DIV_MASK 0x0000003FF
-+#define frame_width_bits(n) (((n) << FRWID_BIT)  &0x0000FC00)
-+#define frame_period_bits(n) (((n) << FRPER_BIT) &0x1FFF0000)
-+
-+
-+/* DMA controller register
-+---------------------------*/
-+#define RX_DMA_ENABLE 0x00000001
-+#define TX_DMA_ENABLE 0x00000002
-+
-+#define RDMAE_BIT             0
-+#define TDMAE_BIT             1
-+
-+/*Interrupt Register
-+-----------------------------------------*/
-+#define RECEIVE_SERVICE_INT         0x00000001
-+#define RECEIVE_OVERRUN_ERROR_INT   0x00000002
-+#define RECEIVE_FRAME_SYNC_ERR_INT  0x00000004
-+#define RECEIVE_FRAME_SYNC_INT      0x00000008
-+#define TRANSMIT_SERVICE_INT        0x00000010
-+#define TRANSMIT_UNDERRUN_ERR_INT   0x00000020
-+#define TRANSMIT_FRAME_SYNC_ERR_INT 0x00000040
-+#define TRANSMIT_FRAME_SYNC_INT     0x00000080
-+#define ALL_INT                     0x000000ff
-+
-+/* Protocol configuration values
-+* I2S: Single phase, 16 bits, 2 words per frame
-+-----------------------------------------------*/
-+#define I2S_PROTOCOL_DESC                     \
-+{                                                                     \
-+      MSP_SINGLE_PHASE,                               \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_ELEM_LENGTH_32,                             \
-+      MSP_ELEM_LENGTH_32,                             \
-+      MSP_DELAY_1,                                    \
-+      MSP_FALLING_EDGE,                               \
-+      MSP_FALLING_EDGE                        \
-+}
-+
-+/* Companded PCM: Single phase, 8 bits, 1 word per frame
-+--------------------------------------------------------*/
-+#define PCM_COMPAND_PROTOCOL_DESC     \
-+{                                                                     \
-+      MSP_SINGLE_PHASE,                               \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_ELEM_LENGTH_8,                              \
-+      MSP_ELEM_LENGTH_8,                              \
-+      MSP_DELAY_0,                                    \
-+      MSP_RISING_EDGE,                                        \
-+      MSP_FALLING_EDGE                                        \
-+}
-+
-+/* AC97: Double phase, 1 element of 16 bits during first phase,
-+* 12 elements of 20 bits in second phase.
-+--------------------------------------------------------------*/
-+#define AC97_PROTOCOL_DESC                    \
-+{                                                                     \
-+      MSP_DUAL_PHASE,                                 \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_FRAME_LENGTH_12,                    \
-+      MSP_ELEM_LENGTH_16,                             \
-+      MSP_ELEM_LENGTH_20,                             \
-+      MSP_DELAY_1,                                    \
-+      MSP_RISING_EDGE,                                        \
-+      MSP_FALLING_EDGE                                        \
-+}
++      unsigned int i;
 +
-+#define SPI_MASTER_PROTOCOL_DESC      \
-+{                                                                     \
-+      MSP_SINGLE_PHASE,                               \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_ELEM_LENGTH_8,                              \
-+      MSP_ELEM_LENGTH_8,                              \
-+      MSP_DELAY_1,                                    \
-+      MSP_FALLING_EDGE,                               \
-+      MSP_RISING_EDGE                         \
-+}
-+#define SPI_SLAVE_PROTOCOL_DESC               \
-+{                                                                     \
-+      MSP_SINGLE_PHASE,                               \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_FRAME_LENGTH_1,                             \
-+      MSP_ELEM_LENGTH_8,                              \
-+      MSP_ELEM_LENGTH_8,                              \
-+      MSP_DELAY_1,                                    \
-+      MSP_FALLING_EDGE,                               \
-+      MSP_RISING_EDGE                         \
++      nmdk_dbg_ftrace();
++      /*force default isr value to zero*/
++      p_vic_register->isr_dvar = (u32)NULL;
++      for (i = 0; i < MAX_CHIP_IRQ; i++) {
++              if (1ULL<<i & IRQ_CONF) {
++                      nomadik_vic_configure(i);
++                      set_irq_chip(i, &nomadik_vic_chip);
++                      set_irq_handler(i, handle_level_irq);
++                      set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++              }
++              if (i < VIC_VECTORED_IRQ_NUM) {
++                      /*Disable all vectored interrupts */
++                      p_vic_register->vcr[i] = (u32)NULL;
++                      p_vic_register->var[i] = (u32)NULL;
++              }
++      }
++      nmdk_info("Module initialized Ver("VIC_VER")");
 +}
-+#define FUNC_MSP0 GPIO_ALT_MSP_0
-+#define FUNC_MSP1 GPIO_ALT_MSP_1
-+#define FUNC_MSP2 GPIO_ALT_MSP_2
-+
-+#define MSP_FRAME_PERIOD_IN_MONO_MODE 256
-+#define MSP_FRAME_PERIOD_IN_STEREO_MODE 32
-+#define MSP_FRAME_WIDTH_IN_STEREO_MODE 16
-+
-+#define MSP_COUNT 3
-+
-+#endif
-+
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/mtu.c ../new/linux-2.6.20/arch/arm/mach-nomadik/mtu.c
---- linux-2.6.20/arch/arm/mach-nomadik/mtu.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/mtu.c    2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,589 @@
-+/* 
-+ * Multiple Timer Unit (MTU) driver.
-+ *    Written by Vinayak Pane <vinayak.pane@st.com>
-+ *             
-+ * Nomadik MTU driver.
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/l2cc.c
+@@ -0,0 +1,152 @@
++/*
++ *  linux/arch/arm/mach-nomadik/stn8815_devices.c
 + *
-+ *    This driver provides an interface for device drivers to utilize both MTUs.
-+ *            which includes total 8 timers, Those can be registered against various purposes 
-+ *            within kernel. 
-+ *            It keeps track of used & unused timer units. It handles MTU interrupts 
-+ *            & their respective multiplexing.
++ *  Copyright (C) STMicroelectronics
 + *
-+ * NOTE:
-+ *                    This device is NOT registered with amba bus device -:
-+ *  Even though this driver should be registered with AMBA bus devices, 
-+ *    we cant do this becasue of Amba driver initialised/probed sequence issue. 
-+ *    MTU is used as underlying part of system timer. The system timer 
-+ *    is initialised and used very early before the actual Amba devices 
-+ *    are initialised/probed. Therefore this probe function is not invoked 
-+ *    before the system timer is initialised!!
-+ *    However we can catergories this driver in platform/system drivers.
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
++ *
++ *  SOC specifc drivers whcih are used as amba devices
 + */
-+
++#include <linux/types.h>
++#include <linux/kernel.h>
 +#include <linux/init.h>
 +#include <linux/list.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
++#include <linux/dma-mapping.h>
 +#include <linux/device.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/amba/bus.h>
++#include <linux/amba/kmi.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/spi/spi.h>
++#include <linux/delay.h>
++#include <linux/amba/clcd.h>
 +
-+#include <asm/system.h>
-+#include <asm/irq.h>
 +#include <asm/hardware.h>
 +#include <asm/io.h>
-+
++#include <asm/irq.h>
++#include <asm/dma.h>
++#include <asm/setup.h>
++#include <asm/param.h>
++#include <asm/system.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
 +#include <asm/arch/timex.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/arch/mtu.h>
++#include <asm/arch/debug.h>
 +
-+#ifdef DEBUG_MTU
-+#define dbg_mtu(format, arg...)               printk(KERN_WARNING "" format "\n", ##arg)
-+#else
-+#define dbg_mtu(format, arg...)               do { } while (0)
-+#endif
 +
-+static irqreturn_t(*mtu_irqs[MTU_MAX_TIMERS + 1]) (mtu_timer_t timer_id) = {
-+NULL};
-+unsigned char mtu_inuse = 0;
-+static spinlock_t mtu_inuse_lock;
++#define L210_CACHE_SYNC                       0x730
++#define L210_INV_LINE_PA              0x770
++#define L210_INV_WAY                  0x77C
++#define L210_CLEAN_LINE_PA            0x7B0
++#define L210_CLEAN_LINE_IDX           0x7B8
++#define L210_CLEAN_WAY                        0x7BC
++#define L210_CLEAN_INV_LINE_PA                0x7F0
++#define L210_CLEAN_INV_LINE_IDX               0x7F8
++#define L210_CLEAN_INV_WAY            0x7FC
 +
-+static spinlock_t mtu0_spinlock, mtu1_spinlock;
++static void __iomem *l210_base = (void __iomem *)IO_ADDRESS(NOMADIK_L2CC_BASE);
++static unsigned long way_size = 0x4000;
 +
-+              /* functions to read/write control registers */
-+static inline unsigned long mtu_readl(unsigned int timer,
-+                                    unsigned long ctrl_register)
++static inline void sync_writel(unsigned long val, unsigned long reg,
++                             unsigned long complete_mask)
 +{
-+      unsigned long value, r_address = MTU_CTRL_REG(timer, ctrl_register);
-+      value = readl(r_address);
-+      return value;
++      writel(val, l210_base + reg);
++      /* wait for the operation to complete not required for l210 controller */
++      //while (readl(l210_base + reg) & complete_mask);
 +}
 +
-+static inline void mtu_writel(unsigned int timer, long value,
-+                            unsigned long ctrl_register)
++static inline void cache_sync(void)
 +{
-+      unsigned long w_address = MTU_CTRL_REG(timer, ctrl_register);
-+      writel(value, w_address);
++      sync_writel(0, L210_CACHE_SYNC, 1);
 +}
 +
-+              /* functions to read/write interrupt registers */
-+inline unsigned long mtu_intr_reg_readl(unsigned int timer,
-+                                      unsigned long ctrl_register)
++static inline void cacheline_index_op(unsigned long addr, unsigned long reg)
 +{
-+      unsigned long value, r_address = MTU_INTR_REG(timer, ctrl_register);
-+      value = readl(r_address);
-+      return value;
-+}
++      unsigned long way, index;
 +
-+static inline void mtu_intr_reg_writel(unsigned int timer, long value,
-+                                     unsigned long ctrl_register)
-+{
-+      unsigned long w_address = MTU_INTR_REG(timer, ctrl_register);
-+      writel(value, w_address);
++      for (way = 0; way < 8; way++)
++              for (index = 0; index < way_size; index += PAGE_SIZE) {
++                      unsigned long val = (way << 29) | index | (addr & (PAGE_SIZE - 1));
++                      sync_writel(val, reg, 1);
++              }
 +}
 +
-+static
-+void mtu_set_timer_mode(mtu_timer_t timer, mtu_timer_mode_t mode)
++inline void l210_inv_all(void)
 +{
-+      unsigned long timer_cr = 0;
-+
-+      timer_cr = mtu_readl(timer, TyCR);      /* read original control register */
-+      switch (mode) {
-+      case MTU_PERIODIC:
-+              timer_cr &= ~MTU_ONE_SHOT;      /* clear the one-shot mode */
-+              timer_cr = timer_cr | MTU_PERIODIC;
-+              break;
-+
-+      case MTU_FREE_RUN:
-+              timer_cr = timer_cr & MTU_FREE_RUN;
-+              break;
-+      case MTU_ONE_SHOT:
-+              timer_cr = timer_cr | MTU_ONE_SHOT;
-+              break;
-+      }
-+      mtu_writel(timer, timer_cr, TyCR);      /* write back CR */
-+      dbg_mtu("MTU: timer_mode : after CR = %ld\n", timer_cr);
++      /* invalidate all ways */
++      sync_writel(0xff, L210_INV_WAY, 0xff);
++      cache_sync();
 +}
++EXPORT_SYMBOL(l210_inv_all);
 +
-+#define TyEN  0x0080
-+static int mtu_enable_timer(mtu_timer_t timer)
++inline void l210_clean_all(void)
 +{
-+      unsigned long timer_cr = 0;
-+      if (timer > MTU_MAX_TIMERS)
-+              return -1;
-+      timer_cr = mtu_readl(timer, TyCR);
-+      timer_cr |= TyEN;
-+      mtu_writel(timer, timer_cr, TyCR);
-+      dbg_mtu("MTU: After enable timer CR = %ld\n", timer_cr);
-+      return 0;
++      /* clean all ways */
++      sync_writel(0xff, L210_CLEAN_WAY, 0xff);
++      cache_sync();
 +}
++EXPORT_SYMBOL(l210_clean_all);
 +
-+static void mtu_disable_timer(mtu_timer_t timer)
++inline void l210_flush_all(void)
 +{
-+      unsigned long timer_cr;
-+      timer_cr = mtu_readl(timer, TyCR);
-+      timer_cr &= ~(unsigned long)TyEN;
-+      mtu_writel(timer, timer_cr, TyCR);
++      /* clean and invalidate all ways */
++      sync_writel(0xff, L210_CLEAN_INV_WAY, 0xff);
++      cache_sync();
 +}
++EXPORT_SYMBOL(l210_flush_all);
 +
-+#define TySZ  0x0002
-+static int mtu_change_counter_size(mtu_timer_t timer)
++void l210_inv_range(unsigned long start, unsigned long end)
 +{
-+      /* by default the timer counter is 16-bit only, 
-+         we can change its size to 32-bit here. */
-+
-+      unsigned long timer_cr = 0;
-+      timer_cr = mtu_readl(timer, TyCR);
-+      timer_cr |= TySZ;
-+      mtu_writel(timer, timer_cr, TyCR);
-+      dbg_mtu("MTU: after change_counter_size CR = %ld\n", timer_cr);
-+      return 0;
++      l210_inv_all();
 +}
++EXPORT_SYMBOL(l210_inv_range);
 +
-+#define DIVIDE_BY_ONE         0xfffffff3
-+#define DIVIDE_BY_SIXTEEN     0x00000004
-+#define DIVIDE_BY_256         0x00000008
-+
-+static int mtu_change_timer_prescaler(unsigned int timer,
-+                                    mtu_prescale_t prescaler_factor)
++void l210_clean_range(unsigned long start, unsigned long end)
 +{
-+      unsigned long timer_prescaler = 0;
-+      timer_prescaler = mtu_readl(timer, TyCR);
++      unsigned long size = end - start;
++      unsigned long addr;
 +
-+      switch (prescaler_factor) {
-+      case MTU_PRESCALE_BY_ONE:
-+              timer_prescaler &= DIVIDE_BY_ONE;
-+              break;
-+      case MTU_PRESCALE_BY_SIXTEEN:
-+              timer_prescaler &= DIVIDE_BY_ONE;       /* reset first */
-+              timer_prescaler |= DIVIDE_BY_SIXTEEN;   /* set it to 01b now */
-+              break;
-+      case MTU_PRESCALE_BY_256:
-+              timer_prescaler &= DIVIDE_BY_ONE;
-+              timer_prescaler |= DIVIDE_BY_256;
-+              break;
++      if (size >= PAGE_SIZE) {
++              l210_clean_all();
++              return;
 +      }
-+      mtu_writel(timer, timer_prescaler, TyCR);
-+      return 0;
-+}
-+unsigned long mtu_get_decrementing_counter_value(mtu_timer_t timer)
-+{
-+      unsigned long decrementing_counter = 0;
-+      decrementing_counter = mtu_readl(timer, TyVAL);
-+      return decrementing_counter;
++
++      /* no physical address information, flush by index/way */
++      for (addr = start & ~(32 - 1); addr < end; addr += 32)
++              cacheline_index_op(addr, L210_CLEAN_LINE_IDX);
++      cache_sync();
 +}
++EXPORT_SYMBOL(l210_clean_range);
 +
-+EXPORT_SYMBOL(mtu_get_decrementing_counter_value);
 +
-+static inline void mtu_load_counter(mtu_timer_t timer,
-+                                  unsigned long timer_load_register)
++void l210_flush_range(unsigned long start, unsigned long end)
 +{
-+      mtu_writel(timer, timer_load_register, TyLR);
-+}
++      unsigned long addr,way,val;
 +
-+inline void mtu_bg_load_counter(mtu_timer_t timer,
-+                              unsigned long timer_load_register)
-+{
-+      mtu_writel(timer, timer_load_register, TyBGLR);
++      //printk("\nl2 flushing hit\n");
++      /* no physical address information, flush by index/way */
++      for (addr = start & ~(32 - 1); addr < end; addr += 32)
++              cacheline_index_op(addr, L210_CLEAN_INV_LINE_IDX);
++
++      /*for (addr = start; addr < end; addr += 32) {
++              for (way = 0; way < 8; way++) {
++                      //val = (way << 29) |  ((addr & 0x1ff) << 5);
++                      val = (way << 29) |  (addr << 5);
++                      sync_writel(val, L220_CLEAN_INV_LINE_IDX, 1);
++              }
++      }*/
++      cache_sync();
 +}
++EXPORT_SYMBOL(l210_flush_range);
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/msp.c
+@@ -0,0 +1,2062 @@
++/*
++ *  Driver for Nomadik STN8810/STN8815 MSP device.
++ *
++ *  Copyright 2006 STMicroelectronics Pvt. Ltd.
++ *
++ *  This program is free sofstware; 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.
++ *
++ */
 +
-+EXPORT_SYMBOL(mtu_bg_load_counter);
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++#include <linux/interrupt.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/amba/bus.h>
++#include <linux/delay.h>
 +
-+/***************************************************************
-+ *    functiion :     mtu0_timer_interrupt_handler
-+ *    Description: 
-+ *                    Interrupt of MTU Unit 0 is handled.
-+ *                    With the priority as MTU0_T0, MTU0_T1,
-+ *                    MTU0_T2, MTU0_T3. And then the corrosponding 
-+ *                    timer unit's interrupt handler will be called.
-+ *    Returns: 
-+ *                    IRQ_HANDLED - ret val from the sub-irq
-+ *                    IRQ_HANDLED - if the corrosponding irq is not present.
-+ ****************************************************************/
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <asm/irq.h>
 +
-+static irqreturn_t mtu0_timer_interrupt_handler(int irq, void *dev_id)
-+{
-+      unsigned long status;
-+      unsigned long icr_flag = 0;
-+      mtu_timer_t timer = 0;
++#include <asm/arch/hardware.h>
++#include <asm/arch/defs.h>
++#include <asm/arch/debug.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/gpio.h>
 +
-+      spin_lock(&mtu0_spinlock);
-+      status = mtu_intr_reg_readl(MTU0_T0, TxRIS);
-+      timer = ffs(status);
-+      if ( timer != 1)
-+      {
-+      icr_flag |= 1UL << (timer - 1);
-+      mtu_intr_reg_writel(timer, icr_flag, TxICR);    /* clear ICR bit */
-+      }
-+      spin_unlock(&mtu0_spinlock);
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++#include <asm/arch/spi.h>
++#include <asm/arch/msp-spi.h>
++#endif
 +
-+      if (likely(mtu_irqs[timer]))
-+              return mtu_irqs[timer] (timer);
-+      else {
-+              dbg_mtu("MTU0:Interrupt on this timer[%d] is not handled.\n",
-+                      timer);
-+              return IRQ_HANDLED;
-+      }
++#include <asm/arch/msp.h>
 +
-+      return IRQ_HANDLED;
-+}
++#include "msp.h"
 +
-+static irqreturn_t mtu1_timer_interrupt_handler(int irq, void *dev_id)
-+{
-+      unsigned long status;
-+      unsigned long icr_flag = 0;
-+      mtu_timer_t timer = 0;
++#ifndef MSP_DEBUG
++#define MSP_DEBUG 0
++#endif
 +
-+      spin_lock(&mtu1_spinlock);
-+      status = mtu_intr_reg_readl(MTU1_T0, TxRIS);
-+      /* which timer the interrupt is for */
-+      timer = ffs(status);
-+      icr_flag |= 1UL << (timer - 1);
-+      timer = timer + 4;
-+      mtu_intr_reg_writel(timer, icr_flag, TxICR);    /* clear ICR bit */
++#define NMDK_MSP_NAME         "NOMADIK_MSP"
 +
-+      spin_unlock(&mtu1_spinlock);
-+      /* call corrsponding Irq handler */
-+      if (likely(mtu_irqs[timer]))
-+              return mtu_irqs[timer] (timer);
-+      else {
-+              dbg_mtu("MTU1:Interrupt on this timer[%d] is not handled.\n",
-+                      timer);
-+              return IRQ_HANDLED;
-+      }
++#define NMDK_DEBUG    MSP_DEBUG       /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  NMDK_MSP_NAME /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+      return IRQ_HANDLED;
-+}
++char MSP_NAME[] = "msp";
 +
-+struct irqaction mtu0_timer_irq = {
-+      .name = "MTU0 Timer Tick",
-+      .flags = SA_INTERRUPT | IRQF_TIMER,
-+      .handler = mtu0_timer_interrupt_handler,
-+      .dev_id = NULL,
++static volatile struct msp_register *registers[MSP_COUNT] = {
++      (struct msp_register *)IO_ADDRESS(NOMADIK_MSP0_BASE),
++#if MSP_COUNT > 1
++      (struct msp_register *)IO_ADDRESS(NOMADIK_MSP1_BASE),
++#endif
++#if MSP_COUNT > 2
++      (struct msp_register *)IO_ADDRESS(NOMADIK_MSP2_BASE),
++#endif
 +};
 +
-+struct irqaction mtu1_timer_irq = {
-+      .name = "MTU1 Timer Tick",
-+      .flags = SA_INTERRUPT | IRQF_TIMER,
-+      .handler = mtu1_timer_interrupt_handler,
-+      .dev_id = NULL,
++static int altfunc[MSP_COUNT] = {
++      GPIO_ALT_MSP_0,
++#if MSP_COUNT > 1
++      GPIO_ALT_MSP_1,
++#endif
++#if MSP_COUNT > 2
++      GPIO_ALT_MSP_2,
++#endif
 +};
++static int msp_irq = IRQ_MSP0;
 +
-+static int mtu_irq_initialize(mtu_timer_t timer,
-+                            irqreturn_t(*mtu_sub_irq) (mtu_timer_t timer_id))
-+{
-+      unsigned long icr_flag = 0, clean_icrs = 0;
-+      unsigned long imsc = 0;
-+      unsigned long flags;
-+
-+      if (mtu_sub_irq == NULL)
-+              return -1;
-+
-+      spin_lock(&mtu_inuse_lock);
-+      /*      make sure that unregistered timer interrupts are cleared 
-+         icr_flag = mtu_intr_reg_readl(timer, TxICR); 
-+         : returns Zero always.                                               */
-+      if (timer > 4)
-+              clean_icrs = mtu_inuse >> 4;
-+      else
-+              clean_icrs = mtu_inuse;
-+      /* register the irq sub-handler */
-+      mtu_irqs[timer] = mtu_sub_irq;
-+      spin_unlock(&mtu_inuse_lock);
++static wait_queue_head_t wait[MSP_COUNT];
++static volatile int msp_io_error[MSP_COUNT];
 +
-+      /* the INTR bits/registers will be affected here */
-+      if (timer > 4)
-+              spin_lock_irqsave(&mtu1_spinlock, flags);
-+      else
-+              spin_lock_irqsave(&mtu0_spinlock, flags);
++static struct msp_context msp_context[MSP_COUNT];
 +
-+      icr_flag = ~clean_icrs;
-+      icr_flag |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
-+      mtu_intr_reg_writel(timer, icr_flag, TxICR);
++static struct msp_mode_status tx_status[MSP_COUNT];
++static struct msp_mode_status rx_status[MSP_COUNT];
 +
-+      /* enable interrupt */
-+      imsc = mtu_intr_reg_readl(timer, TxIMSC);
-+      imsc |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
-+      mtu_intr_reg_writel(timer, imsc, TxIMSC);
++static u32 input_clock[MSP_COUNT];
++static u32 spi_clock_mode[MSP_COUNT];
++static u32 spi_burst_mode[MSP_COUNT];
 +
-+      if (timer > 4)
-+              spin_unlock_irqrestore(&mtu1_spinlock, flags);
-+      else
-+              spin_unlock_irqrestore(&mtu0_spinlock, flags);
-+      return 0;
-+}
++/*Usage Flag for MSPs*/
++msp_flag *flag_msp0, *flag_msp1, *flag_msp2;
 +
-+int mtu_register_timer(struct mtu_struct *mtu)
++static const struct msp_protocol_desc protocol_desc_tab[] =   /* Protocol desciptors */
 +{
-+      u64 mtu_interval_ns;
-+      mtu_prescale_t mtu_prescale;
-+      if (mtu == NULL)
-+              return -EINVAL;
-+      if (mtu->timer > MTU_MAX_TIMERS)
-+              return -EINVAL;
++      I2S_PROTOCOL_DESC,
++      /*  PCM_PROTOCOL_DESC */
++      {
++       MSP_SINGLE_PHASE,
++       MSP_FRAME_LENGTH_1,
++       MSP_FRAME_LENGTH_1,
++       MSP_ELEM_LENGTH_16,
++       MSP_ELEM_LENGTH_16,
++       /*below three settings are platform specific */
++       MSP_DATA_DELAY,
++       MSP_TX_CLOCK_EDGE,
++       MSP_RX_CLOCK_EDGE},
++      PCM_COMPAND_PROTOCOL_DESC,
++      AC97_PROTOCOL_DESC,
++      SPI_MASTER_PROTOCOL_DESC,
++      SPI_SLAVE_PROTOCOL_DESC
++};
++/* local functions */
++static irqreturn_t handle_irq(int irq, void *dev_id);
++static int transmit_data(int msp, void *data, size_t bytes);
++static int receive_data(int msp, void *data, size_t bytes);
++static int transmit_receive_data(int msp, int work_mode,
++                               void *txdata, size_t txbytes, void *rxdata,
++                               size_t rxbytes);
++static int configure_clock(int msp, int protocol, u32 input_clock,
++                         u32 frame_freq, int frame_size);
++static int configure_protocol(int msp, int protocol, int direction,
++                            enum msp_data_size data_size);
 +
-+#ifndef CONFIG_NOMADIK_MTU_SYSTEM_TICK
-+      /* if the MTU0 IRQ is not set here, we cant use the timers:
-+       * MTU0_T0, MTU0_T1, MTU0_T2 & MTU0_T3
-+       */
-+      if (mtu->timer <= 4) {
-+              printk(KERN_WARNING
-+                     "MTU: Can not register, since MTU0 support is absent.\n");
-+              return -EINVAL;
-+      }
-+#endif
 +
-+      spin_lock(&mtu_inuse_lock);
-+      if (mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) {
-+              printk(KERN_WARNING
-+                     "MTU: This timer unit is already in use.\n");
-+              spin_unlock(&mtu_inuse_lock);
-+              return -EBUSY;
-+      } else {
-+              mtu_inuse |= (unsigned char)0x1 << (mtu->timer - 1);
-+      }
-+      spin_unlock(&mtu_inuse_lock);
++/**
++ * nomadik_msp_configure - configures the MSP controller
++ * @msp - specifies the msp controller to configure.
++ * @config - specifies the configuration parameters.
++ */
++int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user)
++{
++      u32 old_reg;
++      u32 new_reg;
++      u32 mask;
++      int status = 0;
 +
-+      if (mtu->mtu_irq) {
-+              mtu_irq_initialize(mtu->timer, mtu->mtu_irq);
-+      } else {
-+              printk(KERN_WARNING
-+                     "MTU: Must specify the action handler for timer.\n");
++      if (msp < 0 || msp > MSP_COUNT) {
++              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
 +              return -EINVAL;
 +      }
++      nmdk_dbg("In nomadik_msp_configure, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
++      nmdk_dbg("In nomadik_msp_configure, flag_msp1 is %d\n", flag_msp1->user);
++      nmdk_dbg("In nomadik_msp_configure, flag_msp2 is %d\n", flag_msp2->user);
 +
-+      mtu_set_timer_mode(mtu->timer, mtu->mode);
-+      mtu_interval_ns = ktime_to_ns(mtu->interval);
-+
-+      /* calculate the timer load register value from ktime(sec,nsec) format */
-+#if BITS_PER_LONG != 64
-+      /* XXX  the arithmatic part shall be replaced by ktime_ns-ops */
-+      dbg_mtu("MTU: nano second interval passed is : %lld \n",
-+              mtu_interval_ns);
-+
-+      if (mtu_interval_ns / USEC_PER_SEC < (0x6FA * MSEC_PER_SEC)) {
-+              mtu_prescale = MTU_PRESCALE_BY_ONE;
-+              mtu_interval_ns = mtu_interval_ns * 24 * MSEC_PER_SEC;
-+              do_div(mtu_interval_ns, 10);
-+      } else {
-+              if (mtu_interval_ns / USEC_PER_SEC < (0xB2F * MSEC_PER_SEC)) {
-+                      mtu_prescale = MTU_PRESCALE_BY_SIXTEEN;
-+                      mtu_interval_ns = mtu_interval_ns * 15 * MSEC_PER_SEC;
-+                      do_div(mtu_interval_ns, 100);
-+              } else {
-+                      mtu_prescale = MTU_PRESCALE_BY_256;
-+                      mtu_interval_ns = mtu_interval_ns * 93 * MSEC_PER_SEC;
-+                      do_div(mtu_interval_ns, 10000);
-+              }
++      switch(msp) {
++              case 0: if((flag_msp0->user != MSP_NO_USER) && (flag_msp0->user != user)){
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP0 already in use in %d mode", flag_msp0->user);
++                      }
++                      else {
++                              down(&flag_msp0->lock);
++                              flag_msp0->user = user;
++                              up(&flag_msp0->lock);
++                      }
++                      break;
++              case 1: if((flag_msp1->user != MSP_NO_USER) && (flag_msp1->user != user)){
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP1 already in use in %d mode", flag_msp1->user);
++                      }
++                      else {
++                              down(&flag_msp1->lock);
++                              flag_msp1->user = user;
++                              up(&flag_msp1->lock);
++                      }
++                      break;
++              case 2: if((flag_msp2->user != MSP_NO_USER) && (flag_msp2->user != user)){
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP2 already in use in %d mode", flag_msp2->user);
++                      }
++                      else
++                              down(&flag_msp2->lock);
++                              flag_msp2->user = user;
++                              up(&flag_msp2->lock);
++                      break;
 +      }
-+
-+      do_div(mtu_interval_ns, USEC_PER_SEC);
-+
-+      if (mtu_interval_ns >> 32) {
-+              printk(KERN_WARNING
-+                     "MTU: The interval specified is too big to fit in reload value.\n");
-+              spin_lock(&mtu_inuse_lock);
-+              mtu_irqs[mtu->timer] = NULL;
-+              spin_unlock(&mtu_inuse_lock);
-+              return -EINVAL;
++      if(status) {
++              printk(KERN_ERR "Error in setting flag bit for MSP\n");
++              return status;
 +      }
 +
-+      dbg_mtu("MTU: setting the prescaler of timer to [%x]\n", mtu_prescale);
-+      mtu_change_timer_prescaler(mtu->timer, mtu_prescale);
++      /* First do the global config register */
++      mask =
++          RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FRAME_SYNC_MASK |
++          TX_FRAME_SYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
++          RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK;
 +
-+      if (mtu_interval_ns >> 16) {
-+              dbg_mtu("MTU: changing the counter size to 32 bits\n");
-+              mtu_change_counter_size(mtu->timer);
-+      }
++      new_reg =
++          (config->tx_clock_sel | config->rx_clock_sel | config->
++           rx_frame_sync_pol | config->tx_frame_sync_pol | config->
++           rx_frame_sync_sel | config->tx_frame_sync_sel | config->
++           rx_fifo_config | config->tx_fifo_config | config->srg_clock_sel);
 +
-+      dbg_mtu("MTU:Using %lld as calculated interval for timer\n",
-+              mtu_interval_ns);
-+      /* lets ignore the LSB part now, MTU supports 32bit counter regi only */
-+      mtu_load_counter(mtu->timer, mtu_interval_ns);
++      old_reg = (registers[msp]->global_ctrl);
++      old_reg &= ~mask;
++      old_reg |= new_reg;
++      (registers[msp]->global_ctrl) = old_reg;
 +
-+      /* XXX: if BG-load-register is passed we have to calculate the 
-+       * mtu_bg_interval_ns load value and then load it. */
-+      if (mtu->bg_interval.tv64 == mtu->interval.tv64)        /* right now, this much is supported */
-+              mtu_bg_load_counter(mtu->timer, mtu_interval_ns);
++      /* Now do the tx_config and rx_config registers */
++      old_reg = registers[msp]->rx_config;
++      mask = MSP_NON_MODE_BIT_MASK;
++      new_reg = config->rx_endianess | config->rx_unexpect_frame_sync;
++      old_reg &= ~mask;
++      old_reg |= new_reg;
++      (registers[msp]->rx_config) = old_reg;
++      old_reg = registers[msp]->tx_config;
++      new_reg = config->tx_endianess | config->tx_unexpect_frame_sync;
++      old_reg &= ~mask;
++      old_reg |= new_reg;
++      (registers[msp]->tx_config) = old_reg;
 +
-+      /* finally enable and start the timer */
-+      mtu_enable_timer(mtu->timer);
-+#else
-+      printk(KERN_WARNING "MTU:Functionality is not implemented!\n");
-+#endif
++      /* Set global input clock and spi clock mode, needed by other config ops */
 +
++      input_clock[msp] = config->input_clock_freq;
++      spi_clock_mode[msp] = config->spi_clk_mode;
++      spi_burst_mode[msp] = config->spi_burst_mode;
 +      return 0;
 +}
 +
-+EXPORT_SYMBOL(mtu_register_timer);
-+
-+int mtu_unregister_timer(struct mtu_struct *mtu)
++/**
++ * nomadik_msp_enable - Enable the msp controller with given configuration
++ * @msp - specifies the msp controller
++ * @direction - specifies the transmit/receive direction
++ * @work_mode - specifies DMA/Interrupt/Polling mode
++ * @protocol - Either PCM/I2S
++ * @frame_freq - specifies the frequency.
++ * @frame_size - specifies frame size
++ * @data_size -  specifies element size
++ */
++int nomadik_msp_enable(int msp, int direction, int work_mode, int protocol,
++                     int frame_freq, int frame_size,
++                     enum msp_data_size data_size, t_msp_user user)
 +{
-+      unsigned long icr_clear = 0, imsc;
-+      unsigned long flags;
-+      icr_clear |=
-+          1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1));
-+
-+      spin_lock(&mtu_inuse_lock);
-+
-+      /* check if the caller has right to unregister this timer */
-+      if (mtu->mtu_irq != mtu_irqs[mtu->timer]) {
-+            unregister_failed:
-+              spin_unlock(&mtu_inuse_lock);
++      int status = 0;
++      int skip_irq;
++      if (msp < 0 || msp > MSP_COUNT) {
++              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
 +              return -EINVAL;
 +      }
 +
-+      if ((mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) == 0) {
-+              /* if the timer unit was not registered successfully */
-+              goto unregister_failed;
-+      } else
-+              /* clear the inuse bit */
-+              mtu_inuse &= ~((unsigned char)0x1 << (mtu->timer - 1));
-+      spin_unlock(&mtu_inuse_lock);
++      nmdk_dbg("In nomadik_msp_enable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
++      switch(msp) {
++              case 0: if(flag_msp0->user != user) {
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP0 not usable in Non SPI mode\n");
++                      }
++                      break;
++              case 1: if(flag_msp1->user != user) {
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP1 not usable in Non SPI mode\n");
++                      }
++                      break;
++              case 2: if(flag_msp2->user != user) {
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP2 not usable in Non SPI mode\n");
++                      }
++                      break;
++      }
++      if(status) {
++              printk(KERN_ERR "Error in setting flag bit for MSP, status is %d\n", status);
++              return status;
++      }
 +
-+      if (mtu->timer > 4)
-+              spin_lock_irqsave(&mtu1_spinlock, flags);
-+      else
-+              spin_lock_irqsave(&mtu0_spinlock, flags);
++      skip_irq = (registers[msp]->global_ctrl) & (TX_ENABLE | RX_ENABLE);
 +
-+      mtu_disable_timer(mtu->timer);
++      if(!skip_irq) {
++              switch (msp) {
++                      case 0:
++                              status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_0");
++                              break;
++                      case 1:
++                              status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_1");
++                              break;
++                      case 2:
++                              status = nomadik_gpio_altfuncenable(altfunc[msp], "MSP_2");
++                              break;
++              }
++              if (status) {
++                      printk(KERN_ERR "Error in nomadik_gpio_altfuncenable, status is %d\n", status);
++                      return status;
++              }
++      }
 +
-+      /* disable the interrupt */
-+      imsc = mtu_intr_reg_readl(mtu->timer, TxIMSC);
-+      imsc &=
-+          ~(1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1)));
-+      mtu_intr_reg_writel(mtu->timer, imsc, TxIMSC);
++      /* Store context data for power management */
++      msp_context[msp].direction = direction;
++      msp_context[msp].mode = work_mode;
++      msp_context[msp].protocol = protocol;
++      msp_context[msp].frame_freq = frame_freq;
++      msp_context[msp].frame_size = frame_size;
++      msp_context[msp].requested_data_size = data_size;
 +
-+      /* clear the interrupt of this timer */
-+      mtu_intr_reg_writel(mtu->timer, icr_clear, TxICR);
++      /* Configure msp with protocol dependent settings */
++      configure_protocol(msp, protocol, direction, data_size);
 +
-+      mtu_load_counter(mtu->timer, 0);
++      configure_clock(msp, protocol, input_clock[msp], frame_freq,
++                      frame_size);
 +
-+      spin_lock(&mtu_inuse_lock);
-+      mtu_irqs[mtu->timer] = NULL;
-+      spin_unlock(&mtu_inuse_lock);
++      switch (direction) {
++      case MSP_TRANSMIT_MODE:
++              registers[msp]->irq_mask |= TRANSMIT_UNDERRUN_ERR_INT;
++              if (work_mode == MSP_DMA_MODE) {
++                      registers[msp]->dma_ctrl |= TX_DMA_ENABLE;
++              }
 +
-+      if (mtu->timer > 4)
-+              spin_unlock_irqrestore(&mtu1_spinlock, flags);
-+      else
-+              spin_unlock_irqrestore(&mtu0_spinlock, flags);
++              tx_status[msp].work_mode = work_mode;
++              if (protocol == MSP_I2S_PROTOCOL) {
++                      tx_status[msp].stereo_mode = MSP_STEREO;
++              } else {
++                      tx_status[msp].stereo_mode = MSP_MONO;
++              }
 +
-+      return 0;
-+}
++              (registers[msp]->global_ctrl) &= ~RX_ENABLE;
++              (registers[msp]->global_ctrl) |= TX_ENABLE;
++              break;
++      case MSP_RECEIVE_MODE:
++              registers[msp]->irq_mask |= RECEIVE_OVERRUN_ERROR_INT;
++              if (work_mode == MSP_DMA_MODE) {
++                      registers[msp]->dma_ctrl |= RX_DMA_ENABLE;
++              }
 +
-+EXPORT_SYMBOL(mtu_unregister_timer);
++              rx_status[msp].work_mode = work_mode;
++              if (protocol == MSP_I2S_PROTOCOL) {
++                      rx_status[msp].stereo_mode = MSP_STEREO;
++              } else {
++                      rx_status[msp].stereo_mode = MSP_MONO;
++              }
 +
-+static struct {
-+      u32 tmr_value;
-+      u32 tmr_control;
-+      u32 tmr_bgload;
-+}mtu_tmr_context[8];
++              (registers[msp]->global_ctrl) |= RX_ENABLE;
++              (registers[msp]->global_ctrl) &= ~TX_ENABLE;
++              break;
++      case MSP_BOTH_T_R_MODE:
++              registers[msp]->irq_mask |=
++                  TRANSMIT_UNDERRUN_ERR_INT | RECEIVE_OVERRUN_ERROR_INT;
++              if (work_mode == MSP_DMA_MODE) {
++                      registers[msp]->dma_ctrl |=
++                          TX_DMA_ENABLE | RX_DMA_ENABLE;
++              }
 +
-+static u32 nomadik_mtu0_imsc[2];
++              tx_status[msp].work_mode = work_mode;
++              rx_status[msp].work_mode = work_mode;
++              if (protocol == MSP_I2S_PROTOCOL) {
++                      tx_status[msp].stereo_mode = MSP_STEREO;
++                      rx_status[msp].stereo_mode = MSP_STEREO;
++              } else {
++                      tx_status[msp].stereo_mode = MSP_MONO;
++                      rx_status[msp].stereo_mode = MSP_MONO;
++              }
 +
-+int nomadik_mtu_suspend(void)
-+{
-+      /* Use spin lock */
-+      int inuse = mtu_inuse & ~1;
-+      int tmr_no;
++              (registers[msp]->global_ctrl) |= RX_ENABLE;
++              (registers[msp]->global_ctrl) |= TX_ENABLE;
++              break;
++      default:
++              printk(KERN_ERR "Invalid direction parameter\n");
++              return -EINVAL;
++      }
 +
-+      nomadik_mtu0_imsc[0] = mtu_intr_reg_readl(MTU0_T0, TxIMSC);
-+      nomadik_mtu0_imsc[1] = mtu_intr_reg_readl(MTU1_T0, TxIMSC);
-+      while(inuse)
-+      {
-+              tmr_no = ffs(inuse);
-+              mtu_tmr_context[tmr_no-1].tmr_value = mtu_readl(tmr_no, TyVAL);
-+              mtu_tmr_context[tmr_no-1].tmr_control = mtu_readl(tmr_no, TyCR);
-+              mtu_tmr_context[tmr_no-1].tmr_bgload = mtu_readl(tmr_no, TyBGLR);
-+              inuse = inuse & ~(1 << ( tmr_no - 1 ));
++      /* enable frame generation logic */
++      (registers[msp]->global_ctrl) |= FRAME_GEN_ENABLE;
++      msp_context[msp].msp_disable = 0;
++      if (!skip_irq) {
++              status = request_irq(msp_irq, handle_irq,
++                                   SA_INTERRUPT | SA_SHIRQ, MSP_NAME,
++                                   (void *)registers[msp]);
++      if(status)
++              printk(KERN_ERR "Error while request_irq, err is %d\n", status);
 +      }
-+      return 0;
++      return status;
 +}
 +
-+int nomadik_mtu_resume(void)
++void nomadik_msp_flush_input(int msp)
 +{
-+      /* Use spin lock */
-+      int inuse = mtu_inuse & ~1;
-+      int tmr_no;
-+
-+      mtu_intr_reg_writel(MTU0_T0, nomadik_mtu0_imsc[0], TxIMSC);
-+      mtu_intr_reg_writel(MTU1_T0, nomadik_mtu0_imsc[1], TxIMSC);
-+      while(inuse)
-+      {
-+              tmr_no = ffs(inuse);
-+              mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_value, TyLR);
-+              mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_control, TyCR);
-+              mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_bgload, TyBGLR);
-+              inuse = inuse & ~(1 << ( tmr_no - 1 ));
++      u32 dummy;
++      while (!(registers[msp]->status & RX_FIFO_EMPTY)) {
++              dummy = registers[msp]->fifo;
 +      }
-+      return 0;
 +}
 +
-+
-+int __init nomadik_mtu_init(void)
++int nomadik_msp_send_data(int msp, void *data, size_t bytes)
 +{
-+      unsigned long all_icr_clear = 0xf;
-+      volatile unsigned long *psrc_cr =
-+          (volatile unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE);
-+      unsigned long src_cr;
-+      src_cr = *psrc_cr;
-+      src_cr |= 0x2AAA8000;
-+      *psrc_cr = src_cr;
++      int status;
 +
-+      spin_lock_init(&mtu0_spinlock);
-+      spin_lock_init(&mtu1_spinlock);
++      if (msp < 0 || msp > MSP_COUNT) {
++              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++              return -EINVAL;
++      }
 +
-+      mtu_irqs[0] = NULL;
-+      /* clear the interrupts */
++      if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
++              printk(KERN_ERR
++                     "Trying to transmit with transmit not enabled\n");
++              return -EPERM;
++      }
 +
-+      mtu_intr_reg_writel(MTU1_T0, all_icr_clear, TxICR);
++      switch (tx_status[msp].work_mode) {
++      case MSP_DMA_MODE:
++              printk(KERN_WARNING "Function not authorized in DMA mode\n");
++              return -ENOSYS;
++              break;
++      case MSP_POLLING_MODE:
++      case MSP_INTERRUPT_MODE:
++              status = transmit_data(msp, data, bytes);
++              break;
++      default:
++              printk(KERN_ERR "tx work mode invalid: %d\n",
++                     tx_status[msp].work_mode);
++              return -EINVAL;
++              break;
++      }
 +
-+      /* 
-+       * setup an interrupt for the Timer units
-+       */
-+#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
-+      /* Cannt use if module! It might screw the system "timer_tick" */
-+      mtu_intr_reg_writel(MTU0_T0, all_icr_clear, TxICR);
++      return status;
++}
 +
-+      setup_irq(IRQ_MTU0, &mtu0_timer_irq);
-+      printk(KERN_INFO "MTU: Registered MTU0 timer unit.\n");
++int nomadik_msp_receive_data(int msp, void *data, size_t bytes)
++{
++      int status;
 +
-+      setup_irq(IRQ_MTU1, &mtu1_timer_irq);
-+      printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
-+#else
-+      request_irq(IRQ_MTU1, mtu1_timer_irq.handler, mtu1_timer_irq.flags,
-+                  mtu1_timer_irq.name, NULL);
-+      printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
-+#endif
++      if (msp < 0 || msp > MSP_COUNT) {
++              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++              return -EINVAL;
++      }
 +
-+      return 0;
++      if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
++              printk(KERN_ERR "Trying to receive with receive not enabled\n");
++              return -EPERM;
++      }
++
++      switch (rx_status[msp].work_mode) {
++      case MSP_DMA_MODE:
++              printk(KERN_WARNING "Function not authorized in DMA mode\n");
++              return -ENOSYS;
++              break;
++      case MSP_POLLING_MODE:
++      case MSP_INTERRUPT_MODE:
++              status = receive_data(msp, data, bytes);
++              break;
++      default:
++              printk(KERN_ERR "rx work mode invalid: %d\n",
++                     rx_status[msp].work_mode);
++              return -EINVAL;
++              break;
++      }
++
++      return status;
 +}
 +
-+void __exit nomadik_mtu_exit(void)
++int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
++                              void *rxdata, size_t rxbytes)
 +{
-+      mtu_timer_t timer;
-+      /* disabling the registered timers */
-+      while (mtu_inuse) {
-+              timer = ffs(mtu_inuse);
-+              mtu_disable_timer(timer);
-+              mtu_inuse &= ~((unsigned char)0x1 << timer);
++      int status;
++
++      if (msp < 0 || msp > MSP_COUNT) {
++              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++              return -EINVAL;
 +      }
 +
-+      free_irq(IRQ_MTU1, NULL);
++      if (!((registers[msp]->global_ctrl) & RX_ENABLE)) {
++              printk(KERN_ERR "Trying to receive with receive not enabled\n");
++              return -EPERM;
++      }
 +
-+#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
-+      free_irq(IRQ_MTU0, NULL);
-+#endif
-+}
++      if (!((registers[msp]->global_ctrl) & TX_ENABLE)) {
++              printk(KERN_ERR
++                     "Trying to transmit with transmit not enabled\n");
++              return -EPERM;
++      }
 +
-+#ifndef CONFIG_MTU0
-+module_init(nomadik_mtu_init);
-+#endif
-+module_exit(nomadik_mtu_exit);
++      if (tx_status[msp].work_mode != rx_status[msp].work_mode) {
++              printk(KERN_ERR "Inconsistent transmit/reveive modes\n");
++              return -EINVAL;
++      }
 +
-+MODULE_LICENSE("Proprietary");
-+MODULE_DESCRIPTION("Nomadik MTU Driver");
-+MODULE_AUTHOR("ST Microelectronics");
++      switch (tx_status[msp].work_mode) {
++      case MSP_DMA_MODE:
++              printk(KERN_WARNING "Function not authorized in DMA mode\n");
++              return -ENOSYS;
++              break;
++      case MSP_POLLING_MODE:
++      case MSP_INTERRUPT_MODE:
++              status = transmit_receive_data(msp, tx_status[msp].work_mode,
++                                             txdata, txbytes,
++                                             rxdata, rxbytes);
++              break;
++      default:
++              printk(KERN_ERR "work mode invalid: %d\n",
++                     tx_status[msp].work_mode);
++              return -EINVAL;
++              break;
++      }
 +
-+/* vim: set ts=4 noet sw=4 */
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig     2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,28 @@
-+if NOMADIK_NDK10_CUT_A1
++      return status;
++}
 +
-+#target name configuration
-+config NOMADIK_TARGET
-+      string 
-+      default NDK10_Cut_A1
-+ 
-+# nomadik soc chip name configuration for this target
-+config NOMADIK_SOC
-+      string
-+      default stn8810
++static int nomadik_msp_wait_for_tx_complete(int msp)
++{
++      while (!(registers[msp]->status & TX_FIFO_EMPTY));
++      return 0;
++}
 +
-+# nomadik platform name configuration for this target
-+config NOMADIK_PLATFORM
-+      string
-+      default ndk10
++/**
++ * nomadik_msp_disable - disable the given msp controller
++ * @msp - specifies the msp contoller
++ * @direction - specifies the transmit/receive direction
++ */
++int nomadik_msp_disable(int msp, int direction, t_msp_user user)
++{
++      int status = 0;
++      if (msp < 0 || msp > MSP_COUNT) {
++              printk(KERN_ERR "Invalid msp specified:%d\n", msp);
++              return -EINVAL;
++      }
 +
-+# EXTRA_CFLAGS configuration for this target
-+config NOMADIK_TARGET_EXTRA_CFLAGS
-+      string
-+      default "-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++      nmdk_dbg("In nomadik_msp_disable, flag_msp0 is %d, user is %d\n", flag_msp0->user, user);
++      /*Set global flag to free state*/
++      switch(msp) {
++              case 0: if(flag_msp0->user == user) {
++                                              down(&flag_msp0->lock);
++                                              flag_msp0->user = MSP_NO_USER;
++                                              up(&flag_msp0->lock);
++                                              nmdk_dbg("Flag cleanup for MSP0\n");
++                                      }
++                                      else {
++                                              nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp0->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++              case 1: if(flag_msp1->user == user) {
++                                              down(&flag_msp1->lock);
++                                              flag_msp1->user = MSP_NO_USER;
++                                              up(&flag_msp1->lock);
++                                              nmdk_dbg("Flag cleanup for MSP1\n");
++                                      }
++                                      else {
++                                              nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp1->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++              case 2: if(flag_msp2->user == user) {
++                                              down(&flag_msp2->lock);
++                                              flag_msp2->user = MSP_NO_USER;
++                                              up(&flag_msp2->lock);
++                                              nmdk_dbg("Flag cleanup for MSP2\n");
++                                      }
++                                      else {
++                                              nmdk_dbg("Trying to free MSP from NON-SPI-mode , already configured in mode%d\n", flag_msp2->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++      }
++      if(status)
++              return status;
 +
-+# Basic platform type configuration for this target (optional will be removed latter)
-+config NOMADIK_NDK10
-+      bool
-+      default y
++      if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
++              goto disable_alt;
++      }
 +
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,35 @@
-+if NOMADIK_NDK10_CUT_B06
++      if (direction != MSP_RECEIVE_MODE) {
++              int status = nomadik_msp_wait_for_tx_complete(msp);
++              if (status) {
++                  goto disable_alt;
++              }
++      }
++      switch (direction) {
++      case MSP_RECEIVE_MODE:
++              registers[msp]->global_ctrl &= ~RX_ENABLE;
++              registers[msp]->dma_ctrl &= ~RX_DMA_ENABLE;
++              registers[msp]->irq_mask &= ~(RECEIVE_SERVICE_INT |
++                                            RECEIVE_OVERRUN_ERROR_INT);
++              rx_status[msp].flow_error_count = 0;
++              break;
++      case MSP_TRANSMIT_MODE:
++              registers[msp]->global_ctrl &= ~TX_ENABLE;
++              registers[msp]->dma_ctrl &= ~TX_DMA_ENABLE;
++              registers[msp]->irq_mask &= ~(TRANSMIT_SERVICE_INT |
++                                            TRANSMIT_UNDERRUN_ERR_INT);
++              tx_status[msp].flow_error_count = 0;
++              break;
++      case MSP_BOTH_T_R_MODE:
++              registers[msp]->global_ctrl &= ~(TX_ENABLE | RX_ENABLE);
++              registers[msp]->dma_ctrl &= ~(TX_DMA_ENABLE | RX_DMA_ENABLE);
++              registers[msp]->irq_mask &= ~ALL_INT;
++              tx_status[msp].flow_error_count = 0;
++              rx_status[msp].flow_error_count = 0;
++              break;
++      default:
++              printk(KERN_ERR "Invalid direction param\n");
++              status = -EINVAL;
++              goto disable_alt;
++      }
 +
-+comment "Nomadik chip used STRn8810B2S12HPB cut B (chip secure)"
++      msp_context[msp].msp_disable = 1;
 +
-+#target name configuration for this target
-+config NOMADIK_TARGET
-+      string 
-+      default NDK10_Cut_B06
-+ 
-+# nomadik soc chip name configuration for this target
-+config NOMADIK_SOC
-+      string
-+      default stn8810
++      if (!(registers[msp]->global_ctrl & (TX_ENABLE | RX_ENABLE))) {
++              /* disable sample rate and frame generators */
++              registers[msp]->global_ctrl &= ~(FRAME_GEN_ENABLE | SRG_ENABLE);
 +
-+# nomadik soc chip cut name configuration for this targe only
-+config NOMADIK_STRn8810B2S12HPB
-+      bool
-+      default y
++              free_irq(msp_irq, (void *)registers[msp]);
++      }
 +
-+# nomadik platform name configuration for this target
-+config NOMADIK_PLATFORM
-+      string
-+      default ndk10
 +
-+# EXTRA_CFLAGS configuration for this target
-+config NOMADIK_TARGET_EXTRA_CFLAGS
-+      string
-+      default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++disable_alt:
++              switch (msp) {
++                      case 0:
++                              nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_0");
++                              break;
++                      case 1:
++                              nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_1");
++                              break;
++                      case 2:
++                              nomadik_gpio_altfuncdisable(altfunc[msp], "MSP_2");
++                              break;
++              }
 +
-+# Basic platform type configuration for this target
-+config NOMADIK_NDK10
-+      bool
-+      default y
++      return status;
++}
 +
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig     2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,35 @@
-+if NOMADIK_NDK10_CUT_B0
++static int configure_protocol(int msp, int protocol, int direction,
++                            enum msp_data_size data_size)
++{
++      u32 temp_reg;
 +
-+comment "Nomadik chip used STRn8810B2S12 cut B"
++      if ((protocol < 0) || (protocol >= MSP_INVALID_PROTOCOL)) {
++              printk(KERN_ERR
++                     "invalid protocol requested in configure_protocol()\n");
++              return -EINVAL;
++      }
 +
-+#target name configuration for this target
-+config NOMADIK_TARGET
-+      string 
-+      default NDK10_Cut_B0
-+ 
-+# nomadik soc chip name configuration for this target
-+config NOMADIK_SOC
-+      string
-+      default stn8810
++      if (data_size < MSP_DATA_SIZE_DEFAULT
++          || data_size > MSP_DATA_SIZE_32BIT) {
++              printk(KERN_ERR
++                     "invalid data size requested in configure_protocol()\n");
++              return -EINVAL;
++      }
 +
-+# nomadik soc chip cut name configuration for this targe only
-+config NOMADIK_STRn8810B2S12
-+      bool
-+      default y
++      switch (direction) {
++      case MSP_TRANSMIT_MODE:
++              tx_status[msp].phase_mode =
++                  protocol_desc_tab[protocol].phase_mode;
 +
-+# nomadik platform name configuration for this target
-+config NOMADIK_PLATFORM
-+      string
-+      default ndk10
++              /* Use a temp for setup. Clear everything except the two non-mode
++               * dependent bits, then add back the bits for the selected protocol
++               */
++              temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
 +
-+# EXTRA_CFLAGS configuration for this target
-+config NOMADIK_TARGET_EXTRA_CFLAGS
-+      string
-+      default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++              temp_reg |=
++                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++              temp_reg |=
++                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_1);
++              temp_reg |=
++                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_2);
++              if (data_size == MSP_DATA_SIZE_DEFAULT) {
++                      temp_reg |=
++                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_1);
++                      temp_reg |=
++                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_2);
++                      if (protocol_desc_tab[protocol].element_len_1 ==
++                          protocol_desc_tab[protocol].element_len_2) {
++                              msp_context[msp].actual_data_size =
++                                  protocol_desc_tab[protocol].element_len_1;
++                      } else {
++                              msp_context[msp].actual_data_size = data_size;
++                      }
++              } else {
++                      temp_reg |= msp_p1_elem_len_bits(data_size);
++                      temp_reg |= msp_p2_elem_len_bits(data_size);
++                      msp_context[msp].actual_data_size = data_size;
++              }
++              temp_reg |=
++                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
 +
-+# Basic platform type configuration for this target
-+config NOMADIK_NDK10
-+      bool
-+      default y
++              (registers[msp]->tx_config) = temp_reg;
 +
-+endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c  2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1225 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/ndk10_devices.c
-+ *
-+ *  Copyright (C) 2000-2003 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 <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/amba/bus.h>
-+#include <linux/spi/spi.h>
-+#include <linux/amba/kmi.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/setup.h>
-+#include <asm/param.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/time.h>
-+#include <asm/arch/i2c.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/kpd.h>
-+#include <asm/arch/touchp.h>
-+#include <asm/arch/fsmc.h>
-+#ifdef CONFIG_MTD
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/concat.h>
-+#include <asm/arch/nandflash.h>
-+#include <asm/mach/flash.h>
-+#endif
-+#include <asm/arch/debug.h>
++              /* The tx_config register is done, now set the clock mode (rising
++               * or falling edge). We first clear the bit using the ~RISING value.
++               */
++              temp_reg = (registers[msp]->global_ctrl) & ~TX_CLK_POL_RISING;
++              temp_reg |=
++                  msp_tx_clkpol_bit(protocol_desc_tab[protocol].
++                                    tx_clock_edge);
++              temp_reg |= TX_EXTRA_DELAY_ENABLE;
++              temp_reg |= msp_data_delay_bits(MSP_DELAY_1);
 +
-+/*
-+ * epio
-+ */
-+#define EPIO_NAME             "EPIO"
++              (registers[msp]->global_ctrl) = temp_reg;
++              break;
++      case MSP_RECEIVE_MODE:
++              rx_status[msp].phase_mode =
++                  protocol_desc_tab[protocol].phase_mode;
 +
-+#ifndef EPIO_DEBUG
-+#define EPIO_DEBUG 0
-+#endif
++              /* Use a temp for setup. Clear everything except the two non-mode
++               * dependent bits, then add back the bits for the selected protocol
++               */
++              temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
 +
-+#define NMDK_DEBUG    EPIO_DEBUG      /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  EPIO_NAME     /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++              temp_reg |=
++                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++              temp_reg |=
++                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_1);
++              temp_reg |=
++                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_2);
++              if (data_size == MSP_DATA_SIZE_DEFAULT) {
++                      temp_reg |=
++                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_1);
++                      temp_reg |=
++                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_2);
++                      if (protocol_desc_tab[protocol].element_len_1 ==
++                          protocol_desc_tab[protocol].element_len_2) {
++                              msp_context[msp].actual_data_size =
++                                  protocol_desc_tab[protocol].element_len_1;
++                      } else {
++                              msp_context[msp].actual_data_size = data_size;
++                      }
++              } else {
++                      temp_reg |= msp_p1_elem_len_bits(data_size);
++                      temp_reg |= msp_p2_elem_len_bits(data_size);
++                      msp_context[msp].actual_data_size = data_size;
++              }
++              temp_reg |=
++                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
 +
-+static spinlock_t epio_cob_ctl_read = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_cob_ctl_write = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_kp_read = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_kp_write = SPIN_LOCK_UNLOCKED;
++              (registers[msp]->rx_config) = temp_reg;
 +
-+static unsigned long epio_lgcl_addr_cob_ident_reg;
-+static unsigned long epio_lgcl_addr_cob_ctl_reg;
-+static unsigned long epio_lgcl_addr_kp_reg;
-+static unsigned long epio_lgcl_addr_exp_ctrl_reg;
-+static spinlock_t epio_exp_ctrl_read = SPIN_LOCK_UNLOCKED;
-+static spinlock_t epio_exp_ctrl_write = SPIN_LOCK_UNLOCKED;
++              /* The rx_config register is done, now set the clock mode (rising
++               * or falling edge). We first clear the bit using the ~RISING value.
++               */
++              temp_reg = (registers[msp]->global_ctrl) & ~RX_CLK_POL_RISING;
++              temp_reg |=
++                  msp_rx_clkpol_bit(protocol_desc_tab[protocol].
++                                    rx_clock_edge);
 +
-+/*
-+ * nomadik_epio_read_cob_ident - reads COB_IDENT register of CPLD
-+ *
-+ * Reads the core bord version and CPLD version information stored in
-+ * COB_IDENT register of CPLD on NDK10
-+ */
-+static short nomadik_epio_read_cob_ident(void)
-+{
-+      return ((short)
-+              *((volatile unsigned short *)epio_lgcl_addr_cob_ident_reg));
-+}
++              (registers[msp]->global_ctrl) = temp_reg;
++              break;
++      case MSP_BOTH_T_R_MODE:
++              rx_status[msp].phase_mode =
++                  protocol_desc_tab[protocol].phase_mode;
++              tx_status[msp].phase_mode =
++                  protocol_desc_tab[protocol].phase_mode;
 +
-+/**
-+ * nomadik_epio_read_cob_ctl - reads COB_CTL register of CPLD
-+ *
-+ * Reads the present value of the core-board-configuration register of CPLD
-+ * on NDK10 board
-+ */
-+short nomadik_epio_read_cob_ctl(void)
-+{
-+      short i;
++              /* Use a temp for setup. Clear everything except the two non-mode
++               * dependent bits, then add back the bits for the selected protocol
++               * do rx_config first
++               */
++              temp_reg = (registers[msp]->rx_config) & MSP_NON_MODE_BIT_MASK;
 +
-+      spin_lock(&epio_cob_ctl_read);
-+      i = *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg);
-+      spin_unlock(&epio_cob_ctl_read);
-+      return (i);
-+}
++              temp_reg |=
++                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++              temp_reg |=
++                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_1);
++              temp_reg |=
++                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_2);
++              if (data_size == MSP_DATA_SIZE_DEFAULT) {
++                      temp_reg |=
++                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_1);
++                      temp_reg |=
++                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_2);
++                      if (protocol_desc_tab[protocol].element_len_1 ==
++                          protocol_desc_tab[protocol].element_len_2) {
++                              msp_context[msp].actual_data_size =
++                                  protocol_desc_tab[protocol].element_len_1;
++                      } else {
++                              msp_context[msp].actual_data_size = data_size;
++                      }
++              } else {
++                      temp_reg |= msp_p1_elem_len_bits(data_size);
++                      temp_reg |= msp_p2_elem_len_bits(data_size);
++                      msp_context[msp].actual_data_size = data_size;
++              }
++              temp_reg |=
++                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
 +
-+/**
-+ * nomadik_epio_write_cob_ctl - writes COB_CTL register of CPLD
-+ * @expctrlval: value to be written
-+ *
-+ * Write the provided 16bit value into the core-board-configuration register
-+ * of CPLD on NDK10 board
-+ */
-+void nomadik_epio_write_cob_ctl(unsigned short expctrlval)
-+{
-+      spin_lock(&epio_cob_ctl_write);
-+      *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg) = expctrlval;
-+      spin_unlock(&epio_cob_ctl_write);
-+}
++              (registers[msp]->rx_config) = temp_reg;
 +
-+/**
-+ * nomadik_epio_read_keypad - reads KEYPAD register of CPLD
-+ *
-+ * Reads the present value of the keypad assignment register of CPLD on NDK10
-+ */
-+short nomadik_epio_read_keypad(void)
-+{
-+      short i;
++              /* Now tx_config */
++              temp_reg = (registers[msp]->tx_config) & MSP_NON_MODE_BIT_MASK;
 +
-+      spin_lock(&epio_kp_read);
-+      i = (0x07FF & *((volatile unsigned short *)epio_lgcl_addr_kp_reg));
-+      spin_unlock(&epio_kp_read);
-+      return (i);
-+}
++              temp_reg |=
++                  msp_p2_enable_bit(protocol_desc_tab[protocol].phase_mode);
++              temp_reg |=
++                  msp_p1_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_1);
++              temp_reg |=
++                  msp_p2_frame_len_bits(protocol_desc_tab[protocol].
++                                        frame_len_2);
++              if (data_size == MSP_DATA_SIZE_DEFAULT) {
++                      temp_reg |=
++                          msp_p1_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_1);
++                      temp_reg |=
++                          msp_p2_elem_len_bits(protocol_desc_tab[protocol].
++                                               element_len_2);
++              } else {
++                      temp_reg |= msp_p1_elem_len_bits(data_size);
++                      temp_reg |= msp_p2_elem_len_bits(data_size);
++              }
++              temp_reg |=
++                  msp_data_delay_bits(protocol_desc_tab[protocol].data_delay);
 +
-+/**
-+ * nomadik_epio_write_keypad - writes KEYPAD register of CPLD
-+ * @keypadval: value to be written
-+ *
-+ * Writes the provided value to the keypad assignment reg of CPLD on NDK10
-+ */
-+void nomadik_epio_write_keypad(unsigned short kpdval)
-+{
-+      unsigned short i;
++              (registers[msp]->tx_config) = temp_reg;
++              /* The [rt]x_config register is done, now set the clock mode (rising
++               * or falling edge). We first clear the bit using the ~RISING value.
++               */
++              temp_reg =
++                  (registers[msp]->
++                   global_ctrl) & ~(TX_CLK_POL_RISING | RX_CLK_POL_RISING);
++              temp_reg |=
++                  msp_rx_clkpol_bit(protocol_desc_tab[protocol].
++                                    rx_clock_edge);
++              temp_reg |=
++                  msp_tx_clkpol_bit(protocol_desc_tab[protocol].
++                                    tx_clock_edge);
 +
-+      spin_lock(&epio_kp_write);
-+      i = *((volatile unsigned short *)epio_lgcl_addr_kp_reg);
-+      i &= 0xF800;
-+      i |= kpdval & 0x07ff;
-+      *((volatile unsigned short *)epio_lgcl_addr_kp_reg) = i;
-+      spin_unlock(&epio_kp_write);
-+}
++              (registers[msp]->global_ctrl) = temp_reg;
++              break;
++      default:
++              printk(KERN_ERR "Invalid direction given\n");
++              return -EINVAL;
++      }
 +
-+/**
-+ * nomadik_epio_read_exp_ctrl - reads exp ctrl register of CPLD
-+ *
-+ * Reads the 16bit value of the expansion-board-control register of CPLD on NDK10
-+ */
-+short nomadik_epio_read_exp_ctrl(void)
-+{
-+      short i = 0;
-+      spin_lock(&epio_exp_ctrl_read);
-+      i = *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg);
-+      spin_unlock(&epio_exp_ctrl_read);
-+      return (i);
++      return 0;
 +}
 +
-+/**
-+ * nomadik_epio_write_exp_ctrl - writes exp ctrl register of CPLD
-+ * @expctrlval: value to be written
-+ *
-+ * Writes the provided 16bit value into the expansion-board-control register
-+ * of CPLD on NDK10
-+ */
-+void nomadik_epio_write_exp_ctrl(unsigned short expctrlval)
++static int configure_clock(int msp, int protocol, u32 input_clock,
++                         u32 frame_freq, int frame_size)
 +{
-+      spin_lock(&epio_exp_ctrl_write);
-+      *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg) = expctrlval;
-+      spin_unlock(&epio_exp_ctrl_write);
-+}
++      u32 dummy;
++      u32 frame_per = 0;
++      u32 sck_div = 0;
++      u32 frame_width = 0;
++      u32 temp_reg = 0;
++      u32 data_size;
 +
-+/**
-+ * nomadik_epio_init - epio module init call.
-+ */
-+static int __init nomadik_epio_init(void)
-+{
-+      unsigned short i;
++      (registers[msp]->global_ctrl) &= ~SRG_ENABLE;
 +
-+      nmdk_dbg_ftrace();
-+      epio_lgcl_addr_cob_ident_reg =
-+          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x000, (unsigned long)2);
-+      epio_lgcl_addr_cob_ctl_reg =
-+          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x002, (unsigned long)2);
-+      epio_lgcl_addr_kp_reg =
-+          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x004, (unsigned long)2);
-+      epio_lgcl_addr_exp_ctrl_reg =
-+          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x006, (unsigned long)2);
++      switch (msp_context[msp].actual_data_size) {
++      case MSP_DATA_SIZE_8BIT:
++              data_size = 8;
++              break;
++      case MSP_DATA_SIZE_10BIT:
++              data_size = 10;
++              break;
++      case MSP_DATA_SIZE_12BIT:
++              data_size = 12;
++              break;
++      case MSP_DATA_SIZE_14BIT:
++              data_size = 14;
++              break;
++      case MSP_DATA_SIZE_16BIT:
++              data_size = 16;
++              break;
++      case MSP_DATA_SIZE_20BIT:
++              data_size = 20;
++              break;
++      case MSP_DATA_SIZE_24BIT:
++              data_size = 24;
++              break;
++      case MSP_DATA_SIZE_32BIT:
++              data_size = 32;
++              break;
++      default:
++              printk(KERN_ERR
++                     "Unable to determine data size in configure_clock\n");
++              return -EINVAL;
++      }
 +
-+      i = nomadik_epio_read_cob_ident();
-+      nmdk_info("Core Board Revision %d.%d,  CPLD Code Revision %d.%d",
-+                (i & COB_REV_BITS) >> COB_REV_BITS_POS,
-+                (i & COB_REV_SUBBITS) >> COB_REV_SUBBITS_POS,
-+                (i & CPLD_REV_BITS) >> CPLD_REV_BITS_POS,
-+                (i & CPLD_REV_SUBBITS));
-+      return 0;
-+}
-+#undef NMDK_DEBUG     /*epio*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
++      switch (protocol) {
++      case MSP_PCM_PROTOCOL:
++      case MSP_PCM_COMPAND_PROTOCOL:
++      case MSP_MASTER_SPI_PROTOCOL:
++              if (frame_size < 0) {
++                      frame_per = data_size;
++                      if (protocol == MSP_MASTER_SPI_PROTOCOL) {
++                              /* Need 1 clock between start of frame and start
++                               * of data, and 1 clock to indicate end of frame
++                               */
++                              frame_per += 2;
++                      }
++              } else {
++                      frame_per = data_size;
++              }
++              if (frame_per < data_size) {
++                      printk(KERN_ERR
++                             "Frame size too small in configure_clock\n");
++                      return -EINVAL;
++              }
++              frame_width = 1;
 +
-+/*
-+ * board init
-+ */
-+#define BOARD_NAME            CONFIG_NOMADIK_PLATFORM
-+#ifndef BOARD_DEBUG
-+#define BOARD_DEBUG 0
-+#endif
++              sck_div = input_clock / (frame_freq << 8);
++              frame_per = MSP_FRAME_PERIOD_IN_MONO_MODE;
 +
-+#define NMDK_DEBUG    BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++              break;
++      case MSP_I2S_PROTOCOL:
++              sck_div = input_clock / (frame_freq << 5);
++              frame_per = MSP_FRAME_PERIOD_IN_STEREO_MODE;
++              frame_width = MSP_FRAME_WIDTH_IN_STEREO_MODE;
 +
-+void __init nomadik_pepperpot_board_init(void)
-+{
-+      int err;
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot |
-+                                 CAM_RSTnot);
-+      err = 0;
-+      while (err < 0xffffff)
-+              err++;
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000);
-+      err = 0;
-+      while (err < 0xffffff)
-+              err++;
-+}
++              break;
++      case MSP_AC97_PROTOCOL:
++              /* Not supported */
++              printk(KERN_WARNING "AC97 protocol not supported\n");
++              return -ENOSYS;
++      case MSP_SLAVE_SPI_PROTOCOL:
++              sck_div = 1;
++              break;
++      default:
++              printk(KERN_ERR "Invalid mode attempted for setting clocks\n");
++              return -EINVAL;
++      }
 +
-+void __init nomadik_platform_board_init(void)
-+{
-+      unsigned char __iomem *gpio0_base;
-+      unsigned char __iomem *gpio1_base;
-+      unsigned char __iomem *cpld_base;
-+      unsigned char __iomem *rgpo1_base;
-+      unsigned char __iomem *pmu_base;
-+      unsigned char __iomem *base;
++      temp_reg = (sck_div - 1) & SCK_DIV_MASK;
++      temp_reg |= frame_width_bits(frame_width - 1);
++      temp_reg |= frame_period_bits(frame_per - 1);
++      registers[msp]->srg_ctrl = temp_reg;
 +
-+      gpio0_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO0_BASE);
-+      gpio1_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO1_BASE);
++      /* Wait a bit */
++      dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
 +
-+      rgpo1_base = (unsigned char *)IO_ADDRESS(NOMADIK_CPLD_RGPO1_BASE);
-+      cpld_base = ioremap(NOMADIK_CPLD_BASE, SZ_4K);
-+      base = ioremap(0x36400000, SZ_4K);
++      /* Enable clock */
++      registers[msp]->global_ctrl |= SRG_ENABLE;
 +
-+      /*
-+       * Set Display control LCD*     
-+       * Set bit 26 of pmu->ctrl register to 0. CLCD/DIF selection
-+       */
-+      pmu_base = (unsigned char *)IO_ADDRESS(NOMADIK_PMU_BASE);
-+      writel((0xFBBFFFFF & readl(pmu_base)), pmu_base);
++      /* Another wait */
++      dummy = ((registers[msp]->srg_ctrl) >> FRWID_BIT) & 0x0000003F;
++      /* reconfigure spi clock mode */
++      temp_reg = registers[msp]->global_ctrl;
++      temp_reg &= ~SPI_CLK_MODE_MASK;
++      temp_reg |= spi_clock_mode[msp];
++      temp_reg &= ~SPI_BURST_MODE_MASK;
++      temp_reg |= spi_burst_mode[msp];
 +
-+      /*
-+       * Enabling alt func A for gpio0-gpio7 :UART0
-+       */
-+      writel(0xff, gpio0_base + 0x20);
++      registers[msp]->global_ctrl = temp_reg;
++      return 0;
++}
 +
-+      /*
-+       * Enabling alt func A for gpio51,52,56,57 :UART1
-+       */
-+      writel(0x3180000, gpio1_base + 0x20);
++static irqreturn_t handle_irq(int irq, void *dev_id)
++{
++      int msp;
++      u32 irq_status;
 +
-+      /*
-+       * Enabling alt func B for gpio32-39
-+       */
-+      writel(0xff, gpio1_base + 0x24);
++      /* dev_id should be the register base address, find out which MSP
++       * we are dealing with. */
++      for (msp = 0; msp < MSP_COUNT; msp++) {
++              if (dev_id == registers[msp]) {
++                      break;
++              }
++      }
 +
-+      /*
-+       * Change in cpld register on cob10
-+       * UART1 trasnceiver enable, uart0 enable 
-+       */
-+      writew((0x218 | (readw(cpld_base + 02) & ~(0x238))), (cpld_base + 02));
++      if (msp == MSP_COUNT) {
++              /* Didn't find the MSP, this must not be our interrupt */
++              return -1;
++      }
 +
-+      /*
-+       *  CPLD setting for pepperport camera poweron
-+       *
-+       */
-+      writew((0xc00 | readw(cpld_base + 02)), (cpld_base + 02));
++      irq_status = registers[msp]->masked_irq_status;
 +
-+      /* 
-+       * Setting as copied from CMM file (backlite disabled)
-+       */
-+      writew(0xc000, base);
-+      writew(0x900f, rgpo1_base);
-+      writew(0x53ff, cpld_base + 6);
-+      writew(0xdfff, rgpo1_base);
-+      writew(0x8001, rgpo1_base);
++      /* Disable the interrupt to prevent immediate recurrence */
++      registers[msp]->irq_mask &= ~irq_status;
 +
-+      writew(readw(cpld_base + 0x6) | 0x1000, cpld_base + 6);
++      /* Clear the interrupt */
++      registers[msp]->irq_clear = irq_status;
 +
-+      /*
-+       * Change in cpld uib register
-+       * Enable uart0
-+       */
-+      writew((0x8000 | readw(rgpo1_base)), rgpo1_base);
++      /* Check for an error condition */
++      msp_io_error[msp] |= irq_status & (RECEIVE_OVERRUN_ERROR_INT |
++                                         RECEIVE_FRAME_SYNC_ERR_INT |
++                                         TRANSMIT_UNDERRUN_ERR_INT |
++                                         TRANSMIT_FRAME_SYNC_ERR_INT);
++
++      /* Wake up the reader/writer */
++      wake_up_interruptible(&wait[msp]);
++      return IRQ_HANDLED;
 +
-+      iounmap(cpld_base);
-+      iounmap(base);
-+      printk("%s done\n", __FUNCTION__);
 +}
 +
-+/**
-+ * nomadik_clcd_board_enable - enables board specific clcd prameters
-+ *
-+ * Settings to enable backlight and pannel voltage regulator for NDK10
-+ * bit 10 to set backlight on, bit 11 to set LCD power regulator on
-+ */
-+void nomadik_clcd_enable(void *fbp)
++static int transmit_data(int msp, void *data, size_t bytes)
 +{
-+#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT)
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x0c00);
-+#endif
++      return transmit_receive_data(msp, tx_status[msp].work_mode,
++                                   data, bytes, NULL, 0);
 +}
 +
-+/**
-+ * nomadik_clcd_board_disable - disables board specific clcd prameters
-+ *
-+ * Settings to disable backlight and pannel voltage regulator for NDK10
-+ * bit 10 to reset backlight off, bit 11 to reset LCD power regulator off
-+ */
-+void nomadik_clcd_disable(void *fbp)
++static int receive_data(int msp, void *data, size_t bytes)
 +{
-+#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT)
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & (~0x0c00));
-+#endif
++      return transmit_receive_data(msp, rx_status[msp].work_mode,
++                                   NULL, 0, data, bytes);
 +}
 +
-+/*
-+ * Settings to configure MMC controller for NDK10
-+ */
-+int nomadik_mmc_configure(struct amba_device *dev)
++static int transmit_receive_data(int msp, int work_mode,
++                               void *txdata, size_t txbytes,
++                               void *rxdata, size_t rxbytes)
 +{
-+      int ret;
-+      gpio_config mmc_pin;
-+      char x = val_volt;
-+
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() |
-+                                  MASK_MMC_EPIO);
-+      mmc_pin.dev_name = "mmc";
-+      mmc_pin.mode = GPIO_MODE_SOFTWARE;
-+      mmc_pin.direction = GPIO_DIR_OUTPUT;
-+      mmc_pin.trig = GPIO_TRIG_DISABLE;
-+      mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
-+
-+      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
-+      if (ret) {
-+              nmdk_error("Error in setting GPIO_PIN_75");
-+              goto exit_last;
-+      }
-+      /* this enables power path from toureg to mmc */
-+      ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, "mmc");
-+      if (ret) {
-+              nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
-+              goto deallocate_pin_75;
-+      }
++      int status;
++      u32 tx_offset = 0;
++      u32 rx_offset = 0;
++      u8 *data_src_8bit, *data_dst_8bit;
++      u16 *data_src_16bit, *data_dst_16bit;
++      u32 *data_src_32bit, *data_dst_32bit;
 +
-+      ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
-+      if (ret) {
-+              nmdk_error("Error in writing value to touareg register");
-+              goto deallocate_pin_75;
++      if (txdata == NULL && txbytes > 0) {
++              printk(KERN_ERR
++                     "transmit_receive_data received a NULL transmit buffer with bytes to transmit\n");
++              return -EINVAL;
 +      }
 +
-+      ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, "mmc");
-+      if (ret) {
-+              nmdk_error("Error in gpio Altfunction enable");
-+              goto deallocate_pin_75;
++      if (rxdata == NULL && rxbytes > 0) {
++              printk(KERN_ERR
++                     "transmit_receive_data received a NULL receive buffer with bytes to receive\n");
++              return -EINVAL;
 +      }
-+      return ret;
 +
-+      deallocate_pin_75:
-+      nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc");
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
-+                                  ~MASK_MMC_EPIO);
-+      exit_last:
-+      return ret;
++      data_src_8bit = (u8 *) txdata;
++      data_src_16bit = (u16 *) txdata;
++      data_src_32bit = (u32 *) txdata;
 +
-+}
++      data_dst_8bit = (u8 *) rxdata;
++      data_dst_16bit = (u16 *) rxdata;
++      data_dst_32bit = (u32 *) rxdata;
 +
-+void nomadik_mmc_restore_default(struct amba_device *dev)
-+{
-+      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, "mmc");
-+      nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc");
++      msp_io_error[msp] = 0;
 +
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
-+                                  ~MASK_MMC_EPIO);
++      while (tx_offset < txbytes || rx_offset < rxbytes) {
++              if (msp_io_error[msp]) {
++                      return -EIO;
++              }
++
++              if (rx_offset < rxbytes &&
++                  !((registers[msp]->status) & RX_FIFO_EMPTY)) {
++                      switch (msp_context[msp].actual_data_size) {
++                      case MSP_DATA_SIZE_8BIT:
++                              rx_offset += sizeof(*data_dst_8bit);
++                              *data_dst_8bit++ = registers[msp]->fifo;
++                              break;
++                      case MSP_DATA_SIZE_10BIT:
++                      case MSP_DATA_SIZE_12BIT:
++                      case MSP_DATA_SIZE_14BIT:
++                      case MSP_DATA_SIZE_16BIT:
++                              rx_offset += sizeof(*data_dst_16bit);
++                              *data_dst_16bit++ = registers[msp]->fifo;
++                              break;
++                      case MSP_DATA_SIZE_20BIT:
++                      case MSP_DATA_SIZE_24BIT:
++                      case MSP_DATA_SIZE_32BIT:
++                              rx_offset += sizeof(*data_dst_32bit);
++                              *data_dst_32bit++ = registers[msp]->fifo;
++                              break;
++                      default:
++                              printk(KERN_ERR
++                                     "Unable to determine data size in transmit_receive_data\n");
++                              return -EIO;
++                      }
++              }
++
++              if (tx_offset < txbytes &&
++                  !((registers[msp]->status) & TX_FIFO_FULL)) {
++                      switch (msp_context[msp].actual_data_size) {
++                      case MSP_DATA_SIZE_8BIT:
++                              tx_offset += sizeof(*data_src_8bit);
++                              registers[msp]->fifo = *data_src_8bit++;
++                              break;
++                      case MSP_DATA_SIZE_10BIT:
++                      case MSP_DATA_SIZE_12BIT:
++                      case MSP_DATA_SIZE_14BIT:
++                      case MSP_DATA_SIZE_16BIT:
++                              tx_offset += sizeof(*data_src_16bit);
++                              registers[msp]->fifo = *data_src_16bit++;
++                              break;
++                      case MSP_DATA_SIZE_20BIT:
++                      case MSP_DATA_SIZE_24BIT:
++                      case MSP_DATA_SIZE_32BIT:
++                              tx_offset += sizeof(*data_src_32bit);
++                              registers[msp]->fifo = *data_src_32bit++;
++                              break;
++                      default:
++                              printk(KERN_ERR
++                                     "Unable to determine data size in transmit_receive_data\n");
++                              return -EIO;
++                      }
++              }
++
++              if (work_mode == MSP_INTERRUPT_MODE &&
++                  (tx_offset < txbytes || rx_offset < rxbytes)) {
++                      u32 status_mask = 0;
++                      u32 irq_mask = 0;
++                      if (tx_offset < txbytes) {
++                              status_mask |= TX_FIFO_FULL;
++                              irq_mask |= TRANSMIT_SERVICE_INT;
++                              if (!(registers[msp]->status & TX_FIFO_FULL)) {
++                                      continue;
++                              }
++                      }
++                      if (rx_offset < rxbytes) {
++                              status_mask |= RX_FIFO_EMPTY;
++                              irq_mask |= RECEIVE_SERVICE_INT;
++                              if (!(registers[msp]->status & RX_FIFO_EMPTY)) {
++                                      continue;
++                              }
++                      }
++                      registers[msp]->irq_mask |= irq_mask;
++                      status = wait_event_interruptible(wait[msp],
++                                                        !(registers[msp]->
++                                                          status &
++                                                          status_mask)
++                                                        && msp_io_error[msp]
++                                                        == 0);
++                      if (status) {
++                              return status;
++                      }
++              }
++      }
++
++      return txbytes + rxbytes;
 +}
 +
-+/*
-+ * nomadik_fsmc_init - fsmc initialization on system start
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++
++/**
++ * msp_controller_cmd - To execute controller specific commands for MSP
++ * @drv_data: SPI driver private data structure
++ * @cmd: Command which is to be executed on the controller
++ *
++ *
 + */
-+static __init void nomadik_fsmc_init(void)
++static int msp_controller_cmd(struct driver_data *drv_data, int cmd)
 +{
-+      unsigned char __iomem *fsmc_base;
-+
++      int retval = 0;
 +      nmdk_dbg_ftrace();
-+      /*Following Settings done for NAND flash protect off */
-+      fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
++      switch (cmd)
++      {
++              case DISABLE_CONTROLLER:
++              {
++                      nmdk_dbg2(":::: DISABLE_CONTROLLER\n");
++                      writel((readl(MSP_GCR(drv_data->regs)) & (~(MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN ))), MSP_GCR(drv_data->regs));
++                      break;
++              }
++              case ENABLE_CONTROLLER:
++              {
++                      nmdk_dbg2(":::: ENABLE_CONTROLLER\n");
++                      writel((readl(MSP_GCR(drv_data->regs)) | (MSP_GCR_MASK_TXEN | MSP_GCR_MASK_RXEN )), MSP_GCR(drv_data->regs));
++                      break;
++              }
++              case DISABLE_DMA:
++              {
++                      nmdk_dbg2(":::: DISABLE_DMA\n");
++                      writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
++                      break;
++              }
++              case ENABLE_DMA:
++              {
++                      nmdk_dbg2(":::: ENABLE_DMA\n");
++                      writel(drv_data->cur_chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
++                      break;
++              }
++              case DISABLE_ALL_INTERRUPT:
++              {
++                      nmdk_dbg2(":::: DISABLE_ALL_INTERRUPT\n");
++                      writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++                      break;
++              }
++              case ENABLE_ALL_INTERRUPT:
++              {
++                      nmdk_dbg2(":::: ENABLE_ALL_INTERRUPT\n");
++                      writel( ENABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++                      break;
++              }
++              case CLEAR_ALL_INTERRUPT:
++              {
++                      nmdk_dbg2(":::: CLEAR_ALL_INTERRUPT\n");
++                      writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
++                      break;
++              }
++              case FLUSH_FIFO:
++              {
++                      unsigned long limit = loops_per_jiffy << 1;
++                      nmdk_dbg2(":::: DATA FIFO is flushed\n");
++                      do {
++                              while( ! (readl(MSP_FLR(drv_data->regs)) & MSP_FLR_MASK_RFE))
++                                      readl(MSP_DR(drv_data->regs));
++                      } while ((readl(MSP_FLR(drv_data->regs)) & (MSP_FLR_MASK_TBUSY | MSP_FLR_MASK_RBUSY)) && limit--);
++                      retval = limit;
++                      break;
++              }
++              case RESTORE_STATE:
++              {
++                      struct chip_data *chip = drv_data->cur_chip;
++                      nmdk_dbg2(":::: RESTORE_STATE\n");
++                      writel(chip->regs.mspr.gcr, MSP_GCR(drv_data->regs));
++                      writel(chip->regs.mspr.tcf, MSP_TCF(drv_data->regs));
++                      writel(chip->regs.mspr.rcf, MSP_RCF(drv_data->regs));
++                      writel(chip->regs.mspr.srg, MSP_SRG(drv_data->regs));
++                      writel(chip->regs.mspr.dmacr, MSP_DMACR(drv_data->regs));
++                      writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++                      writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
++                      break;
++              }
++              case LOAD_DEFAULT_CONFIG:
++              {
++                      nmdk_dbg2(":::: LOAD_DEFAULT_CONFIG\n");
++                      writel(DEFAULT_MSP_REG_GCR, MSP_GCR(drv_data->regs));
++                      writel(DEFAULT_MSP_REG_TCF, MSP_TCF(drv_data->regs));
++                      writel(DEFAULT_MSP_REG_RCF, MSP_RCF(drv_data->regs));
++                      writel(DEFAULT_MSP_REG_SRG, MSP_SRG(drv_data->regs));
++                      writel(DEFAULT_MSP_REG_DMACR, MSP_DMACR(drv_data->regs));
++                      writel(DISABLE_ALL_MSP_INTERRUPTS, MSP_IMSC(drv_data->regs));
++                      writel(CLEAR_ALL_MSP_INTERRUPTS, MSP_ICR(drv_data->regs));
++                      break;
++              }
++              default:
++              {
++                      nmdk_dbg2(":::: unknown command\n");
++                      retval = -1;
++                      break;
++              }
++      }
++      return retval;
++}
 +
-+      /* for NOR accesss */
-+      /* Initialize the fsmc bank 0 */
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
-+      /* Initialize the fsmc bank 1 */
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db;
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702;
++void msp_u8_writer(struct driver_data *drv_data)
++{
++      u32 cur_write = 0;
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
++              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++                      return;
++              writel((u32) (*(u8 *) (drv_data->tx)), MSP_DR(drv_data->regs));
++              drv_data->tx += (drv_data->cur_chip->n_bytes);
++              cur_write ++;
++              if(cur_write == 8)
++                      return;
++      }
++}
++void msp_u8_reader(struct driver_data *drv_data)
++{
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
++              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++                      return;
++              *(u8 *) (drv_data->rx) = (u8) readl(MSP_DR(drv_data->regs));
++              drv_data->rx += (drv_data->cur_chip->n_bytes);
++      }
++}
++void msp_u16_writer(struct driver_data *drv_data)
++{
++      u32 cur_write = 0;
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
 +
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
-+      /* Above Settings done for NAND flash protect off */
++              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++                      return;
++              writel((u32) (*(u16 *) (drv_data->tx)), MSP_DR(drv_data->regs));
++              drv_data->tx += (drv_data->cur_chip->n_bytes);
++              cur_write ++;
++              if(cur_write == 8)
++                      return;
++      }
++}
++void msp_u16_reader(struct driver_data *drv_data)
++{
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
++              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++                      return;
++              *(u16 *) (drv_data->rx) = (u16) readl(MSP_DR(drv_data->regs));
++              drv_data->rx += (drv_data->cur_chip->n_bytes);
++      }
 +}
 +
-+int nomadik_pepperpot_init(void)
++void msp_u32_writer(struct driver_data *drv_data)
 +{
-+      int err;
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot |
-+                                 CAM_RSTnot);
-+      err = 0;
-+      while (err < 0xffffff)
-+              err++;
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000);
-+      err = 0;
-+      while (err < 0xffffff)
-+              err++;
++      u32 cur_write = 0;
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
 +
-+      return 0;
++              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++                      return;
++              /*Write Data to Data Register */
++              writel(*(u32 *) (drv_data->tx), MSP_DR(drv_data->regs));
++              drv_data->tx += (drv_data->cur_chip->n_bytes);
++              cur_write ++;
++              if(cur_write == 8)
++                      return;
++      }
++}
++void msp_u32_reader(struct driver_data *drv_data)
++{
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
++              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++                      return;
++              *(u32 *) (drv_data->rx) = readl(MSP_DR(drv_data->regs));
++              drv_data->rx += (drv_data->cur_chip->n_bytes);
++      }
 +}
 +
-+EXPORT_SYMBOL(nomadik_pepperpot_init);
++static irqreturn_t nomadik_msp_interrupt_handler(int irq, void *dev_id)
++{
++      struct driver_data *drv_data = (struct driver_data *)dev_id;
++      struct spi_message *msg = drv_data->cur_msg;
++      u32 irq_status = 0;
++      u32 flag = 0;
++      if (!msg) {
++              dev_err(&drv_data->adev->dev,
++                      "bad message state in interrupt handler");
++              /* Never fail */
++              return IRQ_HANDLED;
++      }
++      /*Read the Interrupt Status Register */
++      irq_status = readl(MSP_MIS(drv_data->regs));
 +
-+#ifdef CONFIG_MTD
++      if (irq_status) {
++              if (irq_status & MSP_MIS_MASK_ROEMIS) { /*Overrun interrupt */
++                      /*Bail-out our Data has been corrupted */
++                      nmdk_dbg3(":::: Received ROR interrupt\n");
++                      drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
++                      drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
++                      drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++                      msg->state = ERROR_STATE;
++                      tasklet_schedule(&drv_data->pump_transfers);
++                      return IRQ_HANDLED;
++              }
 +
-+static struct resource nandflash_resources[] = {
-+      [0] = {
-+             .name = "cmem_address",
-+             .start = NAND_B0_CMEM_ADDR,
-+             .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [1] = {
-+             .name = "cmem_command",
-+             .start = NAND_B0_CMEM_CMD,
-+             .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [2] = {
-+             .name = "cmem_data",
-+             .start = NAND_B0_CMEM_DATA,
-+             .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+};
++              drv_data->read(drv_data);
++              drv_data->write(drv_data);
 +
-+#define NAND_STM_LP_OPTIONS \
-+              (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
++              if ((drv_data->tx == drv_data->tx_end) && (flag == 0)) {
++                      flag = 1;
++                      /*Disable Transmit interrupt */
++                      writel(readl(MSP_IMSC(drv_data->regs)) & (~MSP_IMSC_MASK_TXIM) & (~MSP_IMSC_MASK_TFOIM), (drv_data->regs + 0x14));
++              }
++              /*Clearing any Transmit underrun error. overrun already handled*/
++              drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
 +
-+int nomadik_nandflash_exit(void)
-+{
-+      if(nomadik_gpio_resetpinconfig(NAND_GPIO, "nand"))
-+              return -1;
-+      return 0;
++              if (drv_data->rx == drv_data->rx_end) {
++                      drv_data->execute_cmd(drv_data, DISABLE_ALL_INTERRUPT);
++                      drv_data->execute_cmd(drv_data, CLEAR_ALL_INTERRUPT);
++                      nmdk_dbg3(":::: Interrupt transfer Completed...\n");
++                      /* Update total bytes transfered */
++                      msg->actual_length += drv_data->cur_transfer->len;
++                      if (drv_data->cur_transfer->cs_change)
++                              drv_data->cur_chip->
++                                  cs_control(SPI_CHIP_DESELECT);
++                      /* Move to next transfer */
++                      msg->state = next_transfer(drv_data);
++                      tasklet_schedule(&drv_data->pump_transfers);
++                      return IRQ_HANDLED;
++              }
++      }
++      return IRQ_HANDLED;
 +}
 +
-+void nomadik_nandflash_init(void)
++static int verify_msp_controller_parameters(struct nmdk_spi_config_chip *chip_info)
 +{
-+      /* 
-+       * FSMC initialization 
-+       * 0x0000001e => PCR0
-+       * 0x000d0a00 => PMEM0
-+       * 0x00100a00 => PATT0
-+       */
-+
-+/*    pcr0.address_low        = 0;*/
-+      gpio_config nmdknand_pin_config;
-+      nmdknand_pin_config.dev_name = "nand";
-+      nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
-+      nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
-+      nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
-+      nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config))
-+              return -1;                      
-+      if(nomadik_gpio_writepin(NAND_GPIO, 1, "nand"))
++      nmdk_dbg_ftrace();
++      /*FIXME: check clock params*/
++      if ((chip_info->lbm != LOOPBACK_ENABLED)
++          && (chip_info->lbm != LOOPBACK_DISABLED)) {
++              nmdk_dbg(":::: Loopback Mode is configured incorrectly\n");
 +              return -1;
-+
-+
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
-+          DEFAULT_PCR0_VALUE;
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
-+          DEFAULT_PMEM0_VALUE;
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
-+          DEFAULT_PATT0_VALUE;
++      }
++      if (chip_info->iface != SPI_INTERFACE_MOTOROLA_SPI){
++              nmdk_dbg(":::: Interface is configured incorrectly. This controller supports only MOTOROLA SPI\n");
++              return -1;
++      }
++      if ((chip_info->hierarchy != SPI_MASTER)
++          && (chip_info->hierarchy != SPI_SLAVE)) {
++              nmdk_dbg(":::: hierarchy is configured incorrectly\n");
++              return -1;
++      }
++      if ((chip_info->endian_rx != SPI_FIFO_MSB)
++          && (chip_info->endian_rx != SPI_FIFO_LSB)) {
++              nmdk_dbg(":::: Rx FIFO endianess is configured incorrectly\n");
++              return -1;
++      }
++      if ((chip_info->endian_tx != SPI_FIFO_MSB)
++          && (chip_info->endian_tx != SPI_FIFO_LSB)) {
++              nmdk_dbg(":::: Tx FIFO endianess is configured incorrectly\n");
++              return -1;
++      }
++      if (((chip_info->controller).msp.data_size < MSP_DATA_BITS_8) || ((chip_info->controller).msp.data_size > MSP_DATA_BITS_32)) {
++              nmdk_dbg(":::: MSP DATA Size is configured incorrectly\n");
++              return -1;
++      }
++      if ((chip_info->com_mode != INTERRUPT_TRANSFER)
++          && (chip_info->com_mode != DMA_TRANSFER)
++          && (chip_info->com_mode != POLLING_TRANSFER)) {
++              nmdk_dbg(":::: Communication mode is configured incorrectly\n");
++              return -1;
++      }
++      if (chip_info->iface == SPI_INTERFACE_MOTOROLA_SPI) {
++              if (((chip_info->proto_params).moto.clk_phase != SPI_CLK_ZERO_CYCLE_DELAY)
++                  && ((chip_info->proto_params).moto.clk_phase != SPI_CLK_HALF_CYCLE_DELAY)) {
++                      nmdk_dbg(":::: Clock Phase is configured incorrectly\n");
++                      return -1;
++              }
++              if (((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_LOW)
++                  && ((chip_info->proto_params).moto.clk_pol != SPI_CLK_POL_IDLE_HIGH)) {
++                      nmdk_dbg(":::: Clock Polarity is configured incorrectly\n");
++                      return -1;
++              }
++      }
++      if (chip_info->cs_control == NULL) {
++              nmdk_dbg("::::Chip Select Function is NULL for this chip\n");
++              chip_info->cs_control = null_cs_control;
++      }
 +      return 0;
 +}
 +
-+static const unsigned char lookup_t[256] = {
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
-+};
++/**
++ * nomadik_msp_setup - setup function registered to SPI master framework
++ * @spi: spi device which is requesting setup
++ *
++ * This function is registered to the SPI framework for this SPI master
++ * controller. If it is the first time when setup is called by this device
++ * , this function will initialize the runtime state for this chip and save
++ * the same in the device structure. Else it will update the runtime info
++ * with the updated chip info.
++ */
 +
-+int nmdknand_compute_ecc512(struct mtd_info *mtd, unsigned char *data,
-+                          unsigned char ecc[3])
++static int nomadik_msp_setup(struct spi_device *spi)
 +{
-+      unsigned int sumCol = 0;
-+      unsigned int datum, temp;
-+      unsigned int glob_parity;
-+      const int ecc_n_bytes = 512;
-+      int i;
-+
-+      unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
-+      unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
-+          0, parit32_1 = 0, parit32_2 = 0;
-+      unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
-+          0, parit256_1 = 0, parit256_2 = 0;
-+      unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
-+          0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++      struct nmdk_spi_config_chip *chip_info;
++      struct chip_data *chip;
++      struct spi_master *master;
++      int status = 0;
++      u16 sckdiv = 0;
++      struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++      nmdk_dbg_ftrace();
++      master = drv_data->master;
 +
-+      for (i = ecc_n_bytes - 1; i >= 0; --i) {
-+              datum = data[i];
-+              sumCol ^= datum;
-+              temp = lookup_t[datum];
++      switch(master->bus_num) {
++              case MSP_0_CONTROLLER:
++                      if((drv_data->flag_msp0->user != MSP_NO_USER) && (drv_data->flag_msp0->user != MSP_USER_SPI)){
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP0 already in use in %d mode", drv_data->flag_msp0->user);
++                      }
++                      else {
++                              down(&drv_data->flag_msp0->lock);
++                              drv_data->flag_msp0->user = MSP_USER_SPI;
++                              up(&drv_data->flag_msp0->lock);
++                              nmdk_dbg("Flag set to MSP_USER_SPI for MSP0\n");
++                      }
++                      break;
++              case MSP_1_CONTROLLER:
++                      if((drv_data->flag_msp1->user != MSP_NO_USER) && (drv_data->flag_msp1->user != MSP_USER_SPI)){
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP1 already in use in %d mode", drv_data->flag_msp1->user);
++                      }
++                      else {
++                              down(&drv_data->flag_msp1->lock);
++                              drv_data->flag_msp1->user = MSP_USER_SPI;
++                              up(&drv_data->flag_msp1->lock);
++                              nmdk_dbg("Flag set to MSP_USER_SPI for MSP1\n");
++                      }
++                      break;
++              case MSP_2_CONTROLLER:
++                      if((drv_data->flag_msp2->user != MSP_NO_USER) && (drv_data->flag_msp2->user != MSP_USER_SPI)){
++                              status = -EINVAL;
++                              printk(KERN_ERR "MSP2 already in use in %d mode", drv_data->flag_msp2->user);
++                      }
++                      else {
++                              down(&drv_data->flag_msp2->lock);
++                              drv_data->flag_msp2->user = MSP_USER_SPI;
++                              up(&drv_data->flag_msp2->lock);
++                              nmdk_dbg("Flag set to MSP_USER_SPI for MSP2\n");
++                      }
++                      break;
++      }
++      if(status)
++              return status;
 +
-+              if (i & 0x01)
-+                      parit8_1 ^= temp;
-+              if (i & 0x02)
-+                      parit16_1 ^= temp;
-+              if (i & 0x04)
-+                      parit32_1 ^= temp;
-+              if (i & 0x08)
-+                      parit64_1 ^= temp;
-+              if (i & 0x10)
-+                      parit128_1 ^= temp;
-+              if (i & 0x20)
-+                      parit256_1 ^= temp;
-+              if (i & 0x40)
-+                      parit512_1 ^= temp;
-+              if (i & 0x80)
-+                      parit1024_1 ^= temp;
-+              if (i & 0x100)
-+                      parit2048_1 ^= temp;
++      status = nomadik_gpio_altfuncenable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
++      if (status < 0) {
++              dev_err(&drv_data->adev->dev, "probe - unable to set GPIO Altfunc, %d\n", drv_data->master_info->gpio_alt_func);
++              status = -ENODEV;
++              goto err_out;
 +      }
 +
-+      glob_parity = lookup_t[sumCol];
++      status = request_irq(drv_data->adev->irq[0], nomadik_msp_interrupt_handler, 0, drv_data->master_info->device_name , drv_data);
++      if (status < 0) {
++              dev_err(&drv_data->adev->dev, "probe - cannot get IRQ (%d)\n", status);
++              goto err_altfunc_enable;
++      }
 +
-+      parit1_1 =
-+          ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
-+      parit1_2 =
-+          ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
-+      parit2_1 =
-+          ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+      parit2_2 =
-+          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
-+      parit4_1 =
-+          ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+      parit4_2 =
-+          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++      /* Get controller data */
++      chip_info = spi->controller_data;
++      /* Get controller_state */
++      chip = spi_get_ctldata(spi);
++      if (chip == NULL) {
++              chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
++              if (!chip) {
++                      dev_err(&spi->dev,
++                              "setup - cannot allocate controller state");
++                      goto err_request_irq;
++              }
++              chip->chip_id = spi->chip_select;
 +
-+      parit8_2 = glob_parity ^ parit8_1;
-+      parit16_2 = glob_parity ^ parit16_1;
-+      parit32_2 = glob_parity ^ parit32_1;
-+      parit64_2 = glob_parity ^ parit64_1;
-+      parit128_2 = glob_parity ^ parit128_1;
-+      parit256_2 = glob_parity ^ parit256_1;
-+      parit512_2 = glob_parity ^ parit512_1;
-+      parit1024_2 = glob_parity ^ parit1024_1;
-+      parit2048_2 = glob_parity ^ parit2048_1;
++              nmdk_dbg(":::: chip Id for this client = %d\n", chip->chip_id);
++              nmdk_dbg(":::: Allocated Memory for controller's runtime state\n");
 +
-+      /* Pack bits */
-+      ecc[0] =
-+          ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
-+            (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
-+                                                                      << 1) |
-+            parit8_2);
-+      ecc[1] =
-+          ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
-+            (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
-+            (parit128_1 << 1) | parit128_2);
-+      ecc[2] =
-+          ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
-+            (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
-+                                                                   << 1) |
-+            parit2048_2);
++              if (chip_info == NULL) {
++                      /* spi_board_info.controller_data not is supplied */
++                      chip_info =
++                          kzalloc(sizeof(struct nmdk_spi_config_chip), GFP_KERNEL);
++                      if (!chip_info) {
++                              dev_err(&spi->dev,
++                                      "setup - cannot allocate controller data");
++                              status = -ENOMEM;
++                              goto err_first_setup;
++                      }
++                      nmdk_dbg(":::: Allocated Memory for controller data\n");
 +
-+      return 0;
-+}
++                      /* FIXME: Set controller data default value for MSP*/
++                      chip_info->lbm = LOOPBACK_DISABLED;
++                      chip_info->com_mode = POLLING_TRANSFER;
++                      chip_info->iface = SPI_INTERFACE_MOTOROLA_SPI;
++                      chip_info->hierarchy = SPI_MASTER;
++                      chip_info->endian_tx = SPI_FIFO_LSB;
++                      chip_info->endian_rx = SPI_FIFO_LSB;
++                      (chip_info->controller).msp.data_size = MSP_DATA_BITS_32;
 +
-+static struct nand_ecclayout nand_oob = {
-+      .eccbytes = 6,
-+      .eccpos = {2, 3, 4, 5, 6, 7},
-+      .oobavail = MTD_NANDECC_AUTOPLACE,
-+      .oobfree = {            
-+              { .offset = 8,
-+               .length = 8,
-+              },
-+              },
-+};
++                      if(spi->max_speed_hz != 0)
++                              chip_info->freq = spi->max_speed_hz;
++                      else
++                              chip_info->freq = 48000;
 +
-+#ifdef CONFIG_NOMADIK_NDK10_CUT_B06
-+static struct mtd_partition nandflash_main_partitions[] = {
++                      (chip_info->proto_params).moto.clk_phase = SPI_CLK_HALF_CYCLE_DELAY;
++                      (chip_info->proto_params).moto.clk_pol = SPI_CLK_POL_IDLE_LOW;
++                      chip_info->cs_control = null_cs_control;
++              }
++      }
 +
-+      {.name = "X-Loader(NAND)",
-+       .offset = 0,
-+       .size = 2 * 0x000020000},      /*256 Kbytes */
-+      {.name = "MemInit(NAND)",
-+       .offset = 2 * 0x000020000,
-+       .size = 2 * 0x000020000},      /*128 KBytes */
-+      {.name = "BootLoader(NAND)",
-+       .offset = 4 * 0x000020000,
-+       .size = 16 * 0x00020000},      /*2Mbytes */
-+      {.name = "Kernel zImage(NAND)",
-+       .offset = 20 * 0x000020000,
-+       .size = 24 * 0x000020000},     /*3Mbytes */
-+      {.name = "Root Filesystem(NAND)",
-+       .offset = 44 * 0x000020000,
-+       .size = 176 * 0x000020000},    /*22 Mbytes */
-+      {.name = "User Filesystem(NAND)",
-+       .offset = 220 * 0x000020000,
-+       .size = 800 * 0x000020000},    /*100 Mbytes */
-+};
-+#else
-+static const struct mtd_partition nandflash_main_partitions[] = {
-+      {.name = "X-Loader(NAND)",
-+       .offset = 0,
-+       .size = 4 * 0x00004000},
-+      {.name = "MemInit(NAND)",
-+       .offset = 4 * 0x00004000,
-+       .size = 1 * 0x00004000},
-+      {.name = "BootLoader(NAND)",
-+       .offset = 5 * 0x00004000,
-+       .size = 16 * 0x0004000},
-+      {.name = "Kernel zImage(NAND)",
-+       .offset = 21 * 0x00004000,
-+       .size = 3 * 0x00100000},
-+      {.name = "Root Filesystem(NAND)",
-+       .offset = 0x354000,
-+       .size = 0x0a00000},
-+      {.name = "User Filesystem(NAND)",
-+       .offset = 0xd54000,
-+       .size = 0x12aC000},
-+};
++      if(chip_info->freq == 0){
++              /*Calculate Specific Freq.*/
++              if ( (MSP_INTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)
++                              || ( MSP_EXTERNAL_CLK == (chip_info->controller).msp.clk_freq.clk_src)){
++                      sckdiv = (chip_info->controller).msp.clk_freq.sckdiv;
 +
-+#endif
++              }else{
++                      status = -1;
++                      dev_err(&spi->dev, "setup - controller clock data is incorrect");
++                      goto err_config_params;
++              }
++      }else{
++              /*Calculate Effective Freq.*/
++              sckdiv =((DEFAULT_MSP_CLK) / (chip_info->freq)) - 1;
++              if(sckdiv > MAX_SCKDIV){
++                      printk("SPI: Cannot set frequency less than 48Khz, setting lowest(48 Khz)\n");
++                      sckdiv = MAX_SCKDIV;
++              }
++      }
 +
-+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 +
-+static struct nand_bbt_descr bbt_desc = {
-+      .options = 0,
-+      .offs = 0,
-+      .len = 2,
-+      .pattern = scan_ff_pattern
-+};
++      status = verify_msp_controller_parameters(chip_info);
++      if (status) {
++              dev_err(&spi->dev, "setup - controller data is incorrect");
++              goto err_config_params;
++      }
 +
-+static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
-+                                  unsigned int ctrl)
-+{
-+      struct nomadik_nand_info *drvdata =
-+          container_of(mtd, struct nomadik_nand_info, mtd);
++      /* Now set controller state based on controller data */
++      chip->xfer_type = chip_info->com_mode;
++      chip->cs_control = chip_info->cs_control;
 +
-+      if (cmd == NAND_CMD_NONE)
-+              return;
 +
-+      if (ctrl & NAND_NCE) {
-+              *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
-+                                           0x40)) |= 0x04;
-+      }
-+      if (ctrl & NAND_CLE) {
-+              writeb(cmd,drvdata->cmemc_va);
-+      }
-+      if (ctrl & NAND_ALE) {
-+              writeb(cmd,drvdata->cmema_va);
++      /*FIXME: write all 8 & 16 bit functions*/
++      if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_8) {
++              nmdk_dbg(":::: Less than 8 bits per word....\n");
++              chip->n_bytes = 1;
++              chip->read = msp_u8_reader;
++              chip->write = msp_u8_writer;
++      } else if ((chip_info->controller).msp.data_size <= MSP_DATA_BITS_16) {
++              nmdk_dbg(":::: Less than 16 bits per word....\n");
++              chip->n_bytes = 2;
++              chip->read = msp_u16_reader;
++              chip->write = msp_u16_writer;
++      } else {
++              nmdk_dbg(":::: Less than 32 bits per word....\n");
++              chip->n_bytes = 4;
++              chip->read = msp_u32_reader;
++              chip->write = msp_u32_writer;
 +      }
-+}
-+
-+static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
-+      .parts = nandflash_main_partitions,
-+      .num_parts = ARRAY_SIZE(nandflash_main_partitions),
-+      .lp_options = NAND_STM_LP_OPTIONS,
-+      .eccsize = 512,
-+      .eccsteps = 1,
-+      .badblockpos = 1,
-+      .init = nomadik_nandflash_init,
-+      .exit = nomadik_nandflash_exit,
-+      .nand_oob = &nand_oob,
-+      .bbt_desc = &bbt_desc,
-+      .compute_ecc = nmdknand_compute_ecc512,
-+      .hwcontrol = nmdknand_hwcontrol,
-+};
-+
-+static struct platform_device nomadik_nand_flash = {
-+      .name = "NOMADIK-NAND",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &nomadik_nand_flash_data,
-+              },
-+      .num_resources = ARRAY_SIZE(nandflash_resources),
-+      .resource = nandflash_resources,
-+};
 +
-+static struct mtd_partition nmdkflash_main_partitions[] = {
-+      {.name = "BootLoader(NOR)",
-+       .size = 0x00040000,    /*256K */
-+       .offset = 0,},
-+      {.name = "Kernel zImage(NOR)",
-+       .size = 0x001C0000,    /*1.75MB */
-+       .offset = MTDPART_OFS_APPEND,},
-+      {.name = "Root Filesystem(NOR)",
-+       .size = 0x01200000,    /*18MB */
-+       .offset = MTDPART_OFS_APPEND,},
-+      {.name = "User Filesystem(NOR)",
-+       .size = 0x00800000,    /*8MB */
-+       .offset = MTDPART_OFS_APPEND,},
-+      {.name = "initrd(NOR)",
-+       .size = 0x00200000,    /*4MB */
-+       .offset = MTDPART_OFS_APPEND,}
-+};
++      /*Now Initialize all register settings reqd. for this chip */
 +
-+static struct flash_platform_data nomadik_nor_flash_data = {
-+      .name = "nomadik_nor",
-+      .map_name = "cfi_probe",
-+      //.width                = NMDK_FLASH_BUSWIDTH, 
-+      .parts = nmdkflash_main_partitions,
-+      .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
-+};
++      chip->regs.mspr.gcr = 0x0;
++      chip->regs.mspr.tcf = 0x0;
++      chip->regs.mspr.rcf = 0x0;
++      chip->regs.mspr.srg = 0x0;
++      chip->regs.mspr.dmacr = 0x0;
 +
-+static struct resource norflash_resources[] = {
-+      [0] = {
-+             .name = "norflash-regs",
-+             .start = NMDK_FLASH_BASE,
-+             .end = (NMDK_FLASH_BASE + SZ_16M - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [1] = {
-+             .name = "norflash-regs",
-+             .start = NMDK_FLASH_BASE + SZ_16M,
-+             .end = (NMDK_FLASH_BASE + SZ_32M - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+};
++      if ((chip_info->com_mode == DMA_TRANSFER)
++          && ((drv_data->master_info)->enable_dma)) {
++              chip->enable_dma = 1;
++              chip->dma_info = kzalloc(sizeof(struct spi_dma_info), GFP_KERNEL);
++              if(!chip->dma_info){
++                      nmdk_dbg("Could not allocate memory for dma info of chip_data\n");
++                      goto err_first_setup;
++              }
++              chip->dma_info->dma_xfer_type = chip_info->dma_xfer_type;
++              nmdk_dbg(":::: DMA mode set in controller state\n");
++              status = process_dma_info(chip_info, chip, (void *)drv_data);
++              if (status < 0)
++                      goto err_config_params;
++              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_RDMAE, 0);
++              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x1, MSP_DMACR_MASK_TDMAE, 1);
 +
-+static struct platform_device nomadik_nor_flash = {
-+      .name = "NOMADIK-NOR",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &nomadik_nor_flash_data,
-+              },
-+      .num_resources = ARRAY_SIZE(norflash_resources),
-+      .resource = norflash_resources,
-+};
++              /* find and request free dma chanel */
++              chip->dma_info->rx_dmach = request_available_dma(&(chip->dma_info->rx_dma_info));
++              if (chip->dma_info->rx_dmach < 0) {
++                      nmdk_dbg(":::: Rx pipe request Failed: %d\n", chip->dma_info->rx_dmach);
++                      goto err_rx_dmach_request;
++              }
++              nmdk_dbg(":::: Rx pipe Allocated = %d\n", chip->dma_info->rx_dmach);
 +
-+#endif
++              status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->rx_dmach),
++                              spi_dma_callback_handler, 0, 0,
++                              (void *)drv_data);
++              if (status) {
++                      nmdk_error("Error requesting rx callback dmach intr handler %d", status);
++                      goto err_rx_clbk_request;
++              }
 +
-+static void nomadik_smc91x_irq_init(void)
-+{
-+      int err;
-+      gpio_config smx91x_clkpin;
++              /* find and request free dma chanel */
++              chip->dma_info->tx_dmach = request_available_dma(&(chip->dma_info->tx_dma_info));
++              if (chip->dma_info->tx_dmach < 0) {
++                      nmdk_dbg(":::: Tx pipe request Failed: %d\n", status);
++                      goto err_tx_dmach_request;
++              }
++              nmdk_dbg(":::: Tx pipe Allocated = %d\n", chip->dma_info->tx_dmach);
 +
-+      smx91x_clkpin.dev_name = "smc91x";
-+      smx91x_clkpin.mode = GPIO_ALTF_A;
-+      err = nomadik_gpio_setpinconfig(GPIO_PIN_55, &smx91x_clkpin);
-+      if (err) {
-+              nmdk_error("Error in configuring pin%d for clkout", GPIO_PIN_55);
++              status = request_irq(IRQNO_FOR_DMACH(chip->dma_info->tx_dmach),
++                              spi_dma_callback_handler, 0, 0,
++                              (void *)drv_data);
++              if (status) {
++                      nmdk_error("Error requesting callback dmach intr handler %d", status);
++                      goto err_tx_clbk_request;
++              }
++      } else {
++              chip->enable_dma = 0;
++              nmdk_dbg(":::: DMA mode NOT set in controller state\n");
++              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_RDMAE, 0);
++              SPI_REG_WRITE_BITS(chip->regs.mspr.dmacr, 0x0, MSP_DMACR_MASK_TDMAE, 1);
 +      }
-+      
-+      /* disable NOR flash write protection */
-+      /* CHECK if this clashes with NOR and NAND settings of FSMC */
-+      *((volatile unsigned short *)(NOMADIK_CPLD_RGPO1_VA)) |=
-+          ETH_DAUGHTER_CARD_RESET;
 +
-+      set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING);
-+}
 +
-+static struct resource smc91x_resources[] = {
-+      [0] = {
++      /****   GCR Reg Config  *****/
 +
-+             .name = "smc91x-regs",
-+             .start = (NOMADIK_ETH0_BASE + 0x300),
-+             .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [1] = {
-+             .start = IRQNO_GPIO(SMC91111_IRQ),
-+             .end = IRQNO_GPIO(SMC91111_IRQ),
-+             .flags = IORESOURCE_IRQ,
-+             },
-+};
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RECEIVER_DISABLED, MSP_GCR_MASK_RXEN,0);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_RX_FIFO_ENABLED, MSP_GCR_MASK_RFFEN,1);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMITTER_DISABLED, MSP_GCR_MASK_TXEN,8);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FIFO_ENABLED, MSP_GCR_MASK_TFFEN,9);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_POL_LOW, MSP_GCR_MASK_TFSPOL,10);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_FRAME_SYNC_INT, MSP_GCR_MASK_TFSSEL,11);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TRANSMIT_DATA_WITH_DELAY, MSP_GCR_MASK_TXDDL,15);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SAMPLE_RATE_GEN_ENABLE, MSP_GCR_MASK_SGEN,16);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_CLOCK_INTERNAL, MSP_GCR_MASK_SCKSEL,18);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_FRAME_GEN_ENABLE, MSP_GCR_MASK_FGEN,20);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, SPI_BURST_MODE_DISABLE, MSP_GCR_MASK_SPIBME,23);
 +
-+static struct platform_device smc91x_device = {
-+      .name = "smc91x",
-+      .id = 0,
-+      .num_resources = ARRAY_SIZE(smc91x_resources),
-+      .resource = smc91x_resources,
-+};
 +
-+/*
-+ * touchpanel
-+ */
-+#ifndef TOUCHP_DEBUG
-+#define TOUCHP_DEBUG 0                /* default debug messages are disabled */
-+#endif                                /*  */
++      if(chip_info->lbm == LOOPBACK_ENABLED)
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_ENABLED, MSP_GCR_MASK_LBM, 7);
++      else
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_LOOPBACK_DISABLED, MSP_GCR_MASK_LBM, 7);
 +
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#define NMDK_DEBUG    TOUCHP_DEBUG    /* enables/disables debug msgs */
-+#define NMDK_DEBUG_PFX  TPDRVNAME     /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+/**
-+ * nomadik_tp_ssp_board_init - board specific ssp data path setup
-+ *
-+ * This routine initializes the SSP for touchpanel operation
-+ * SSP is interfaced with ADS7843 through CPLD hence respective
-+ * interface need to be enabled for NDK10
-+ * make bit COB_CTL(MSP2_SSP_SWAP) low to connect STn8810 SSP to EXP SSP
-+ * make bit COB_CTL(SSP_EN) high to enable SSP on STn8810 side
-+ */
-+int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
-+{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_cob_ctl((nomadik_epio_read_cob_ctl() &
-+                                  (~MSP2_SSP_SWAP)) | SSP_EN);
-+      return (0);
-+}
++      if(chip_info->hierarchy == SPI_MASTER)
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_MASTER, MSP_GCR_MASK_TCKSEL, 14);
++      else
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_IS_SPI_SLAVE, MSP_GCR_MASK_TCKSEL, 14);
 +
-+/**
-+ * nomadik_tp_gpio_board_init - board specific gpio initialization
-+ * @mode: mode of operation (polling[0] or interrupt[<0]
-+ *
-+ * This routine initializes the GPIO for touchpanel operation
-+ * RETURN: GPIO nmdk_error code
-+ */
-+gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
-+{
-+      gpio_error status = GPIO_OK;
-+      nmdk_dbg_ftrace();
 +
-+      /* Set PENIRQ pin configuration */
-+      set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING);
-+      /* Enable GPIOs through CPLD for access/interrupts on ndk10 */
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | GPIO_EN);
++      if(chip_info->proto_params.moto.clk_phase == SPI_CLK_ZERO_CYCLE_DELAY)
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_ZERO_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
++      else
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_SPI_PHASE_HALF_CYCLE_DELAY , MSP_GCR_MASK_SPICKM, 21);
 +
-+      return status;
-+}
++      if(chip_info->proto_params.moto.clk_pol == SPI_CLK_POL_IDLE_HIGH)
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_HIGH, MSP_GCR_MASK_TCKPOL,13);
++      else
++              SPI_REG_WRITE_BITS(chip->regs.mspr.gcr, MSP_TX_CLOCK_POL_LOW, MSP_GCR_MASK_TCKPOL,13);
 +
-+/**
-+ * nomadik_tp_pen_down - returns pen touch status
-+ */
-+t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
-+{
-+      gpio_data pen_down;
 +
-+      nmdk_dbg_ftrace();
-+      nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
-+      nmdk_dbg2("%s(): pen_down = 0x%d", __FUNCTION__, pen_down);
-+      return ((t_bool) pen_down);
-+}
++      /****   RCF Reg Config  *****/
++      SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_IGNORE_RX_FRAME_SYNC_PULSE, MSP_RCF_MASK_RFSIG, 15);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_1BIT_DATA_DELAY, MSP_RCF_MASK_RDDLY, 13);
++      if(chip_info->endian_rx == SPI_FIFO_LSB)
++              SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_LSB , MSP_RCF_MASK_RENDN, 12);
++      else
++              SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, MSP_RX_ENDIANESS_MSB , MSP_RCF_MASK_RENDN, 12);
 +
-+/**
-+ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
-+{
-+      nmdk_dbg_ftrace();
-+//    enable_irq(p_adsContext->irq);
-+}
++      SPI_REG_WRITE_BITS(chip->regs.mspr.rcf, chip_info->controller.msp.data_size , MSP_RCF_MASK_RP1ELEN, 0);
 +
-+/**
-+ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
-+{
-+      nmdk_dbg_ftrace();
-+//    disable_irq(p_adsContext->irq);
-+}
++      /****   TCF Reg Config  *****/
++      SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_IGNORE_TX_FRAME_SYNC_PULSE, MSP_TCF_MASK_TFSIG, 15);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_1BIT_DATA_DELAY, MSP_TCF_MASK_TDDLY, 13);
++      if(chip_info->endian_rx == SPI_FIFO_LSB)
++              SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_LSB , MSP_TCF_MASK_TENDN, 12);
++      else
++              SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, MSP_TX_ENDIANESS_MSB , MSP_TCF_MASK_TENDN, 12);
++      SPI_REG_WRITE_BITS(chip->regs.mspr.tcf, chip_info->controller.msp.data_size , MSP_TCF_MASK_TP1ELEN, 0);
 +
-+/**
-+ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
-+ *
-+ * set TOUCHP_SSP_CS pin high to disable SSP chip select for ads7843
-+ */
-+void nomadik_tp_spi_cs_disable(void)
-+{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() |
-+                                  TOUCHP_SSP_CS);
-+}
++      /****   SRG Reg Config  *****/
++      SPI_REG_WRITE_BITS(chip->regs.mspr.srg, sckdiv , MSP_SRG_MASK_SCKDIV , 0);
 +
-+/**
-+ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
-+ *
-+ * set TOUCHP_SSP_CS pin low to enable SSP chip select for ads7843
-+ */
-+void nomadik_tp_spi_cs_enable(void)
-+{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
-+                                  (~TOUCHP_SSP_CS));
-+}
++      /* Save controller_state */
++      spi_set_ctldata(spi, chip);
++      return status;
 +
-+static struct touchp_device touchp_board = {
-+      .ssp_init = nomadik_tp_ssp_board_init,
-+      .gpio_init = nomadik_tp_gpio_board_init,
-+      .pdown = nomadik_tp_pen_down,
-+      .pirq_en = nomadik_tp_pen_down_irq_enable,
-+      .pirq_dis = nomadik_tp_pen_down_irq_disable,
-+      .cs_en = nomadik_tp_spi_cs_disable,
-+      .cs_dis = nomadik_tp_spi_cs_enable,
-+      .samples = 100, /*samples per second*/
-+      .pollsamples = 10, /*polling per second*/
-+};
++err_tx_clbk_request:
++      if (chip->dma_info->tx_dmach != -1) {
++              free_dma(chip->dma_info->tx_dmach);
++      }
++err_tx_dmach_request:
++err_rx_clbk_request:
++      if (chip->dma_info->rx_dmach != -1) {
++              free_dma(chip->dma_info->rx_dmach);
++      }
++err_rx_dmach_request:
++      chip->dma_info->tx_dmach = -1;
++      chip->dma_info->rx_dmach = -1;
++err_config_params:
++err_first_setup:
++      if(chip->dma_info)
++              kfree(chip->dma_info);
++      kfree(chip);
++err_request_irq:
++      free_irq(drv_data->adev->irq[0], drv_data);
++err_altfunc_enable:
++      nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
++err_out:
++      switch(master->bus_num) {
++              case MSP_0_CONTROLLER:  if(drv_data->flag_msp0->user == MSP_USER_SPI) {
++                                              down(&drv_data->flag_msp0->lock);
++                                              drv_data->flag_msp0->user = MSP_NO_USER;
++                                              up(&drv_data->flag_msp0->lock);
++                                              nmdk_dbg("Flag cleanup for MSP0\n");
++                                      }
++                                      else {
++                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp0->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++              case MSP_1_CONTROLLER:  if(drv_data->flag_msp1->user == MSP_USER_SPI) {
++                                              down(&drv_data->flag_msp1->lock);
++                                              drv_data->flag_msp1->user = MSP_NO_USER;
++                                              up(&drv_data->flag_msp1->lock);
++                                              nmdk_dbg("Flag cleanup for MSP1\n");
++                                      }
++                                      else {
++                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++              case MSP_2_CONTROLLER:  if(drv_data->flag_msp2->user == MSP_USER_SPI) {
++                                              down(&drv_data->flag_msp2->lock);
++                                              drv_data->flag_msp2->user = MSP_NO_USER;
++                                              up(&drv_data->flag_msp2->lock);
++                                              nmdk_dbg("Flag cleanup for MSP2\n");
++                                      }
++                                      else {
++                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++      }
 +
-+static struct resource touchp_resources[] = {
-+      [0] = {
-+             .start = IRQNO_GPIO(TOUCHP_IRQ),
-+             .end = IRQNO_GPIO(TOUCHP_IRQ),
-+             .flags = IORESOURCE_IRQ,
-+             },
-+};
++      return status;
++}
 +
-+static struct platform_device touchp_device = {
-+      .name = "nmdk-tp",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &touchp_board,
-+              },
-+      .num_resources = ARRAY_SIZE(touchp_resources),
-+      .resource = touchp_resources,
-+};
++#endif
 +
-+/*
-+ ***********************************************************************
-+ */
-+#define KEYPAD_NAME           "KEYPAD"
 +
-+#ifndef KEYPAD_DEBUG
-+#define KEYPAD_DEBUG 0
++int msp_probe(struct amba_device *adev, void *data)
++{
++      int status = 0;
++      struct device *dev;
++      struct nmdk_spi_master_cntlr *platform_info;
++
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++      struct spi_master *master;
++      struct driver_data *drv_data = NULL;    /*Data for this driver */
++      struct resource *res;
++      int irq;
 +#endif
++      dev = &adev->dev;
++      platform_info = (struct nmdk_spi_master_cntlr *)(dev->platform_data);
++      if (platform_info == NULL) {
++              dev_err(&adev->dev, "probe - no platform data supplied\n");
++              status = -ENODEV;
++              goto err_no_pdata;
++      }
 +
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#define NMDK_DEBUG    KEYPAD_DEBUG    /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  KEYPAD_NAME   /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++      if(platform_info->id == MSP_0_CONTROLLER) {
++              flag_msp0= kmalloc(sizeof(msp_flag), GFP_KERNEL);
++              if(!flag_msp0) {
++                      status = -ENOMEM;
++                      printk(KERN_ERR "No mem available for MSP0 flag\n");
++                      goto err_msp0;
++              }
++              flag_msp0->user = MSP_NO_USER;
++              init_MUTEX(&flag_msp0->lock);
++              init_waitqueue_head(&wait[0]);
++              nmdk_dbg("In msp_probe flag_msp0 is %d\n", flag_msp0->user);
++      }
++      if(platform_info->id == MSP_1_CONTROLLER) {
++              flag_msp1= kmalloc(sizeof(msp_flag), GFP_KERNEL);
++              if(!flag_msp1) {
++                      status = -ENOMEM;
++                      printk(KERN_ERR "No mem available for MSP1 flag\n");
++                      goto err_msp1;
++              }
++              flag_msp1->user = MSP_NO_USER;
++              init_MUTEX(&flag_msp1->lock);
++              init_waitqueue_head(&wait[1]);
++              nmdk_dbg("In msp_probe flag_msp1 is %d\n", flag_msp1->user);
++      }
++      if(platform_info->id == MSP_2_CONTROLLER) {
++              flag_msp2= kmalloc(sizeof(msp_flag), GFP_KERNEL);
++              if(!flag_msp2) {
++                      status = -ENOMEM;
++                      printk(KERN_ERR "No mem available for MSP2 flag\n");
++                      goto err_msp2;
++              }
++              flag_msp2->user = MSP_NO_USER;
++              init_MUTEX(&flag_msp2->lock);
++              init_waitqueue_head(&wait[2]);
++              nmdk_dbg("In msp_probe flag_msp2 is %d\n", flag_msp2->user);
++      }
++      nmdk_dbg_ftrace();
 +
-+/*key scan constants*/
-+#define KSCAN_ALLROWS   0x001F
-+#define KSCAN_ALLCOLS   0x07E0
-+#define KSCAN_ROW0      0x0001
-+#define KSCAN_ROW1      0x0002
-+#define KSCAN_ROW2      0x0004
-+#define KSCAN_ROW3      0x0008
-+#define KSCAN_ROW4      0x0010
-+#define KSCAN_COL0      0x0020
-+#define KSCAN_COL1      0x0040
-+#define KSCAN_COL2      0x0080
-+#define KSCAN_COL3      0x0100
-+#define KSCAN_COL4      0x0200
-+#define KSCAN_AUX     0x0400  /* this line needs to set to get keypad intr */
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++      /* Allocate master with space for drv_data */
++      master = spi_alloc_master(dev, sizeof(struct driver_data));
++      if (master == NULL) {
++              dev_err(&adev->dev, "probe - cannot alloc spi_master\n");
++              status = -ENOMEM;
++              goto err_no_mem;
++      }
 +
-+unsigned short const keychkval_set[] = {
-+      (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS
-+};
++      drv_data = spi_master_get_devdata(master);
++      drv_data->master = master;
++      drv_data->master_info = platform_info;
++      drv_data->adev = adev;
 +
-+unsigned short const keychkval_read[] = {
-+      KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4
-+};
++      drv_data->dma_ongoing = 0;
 +
-+/**
-+ * nomadik_kp_ghostkey_detect - ghost key detect function
-+ * @rowval: row in which ghost key to be detected
-+ *
-+ * when more than one key is pressed in the same row the keypad logic cannot
-+ * detect proper key press, the logic here detects multiple keypress on a
-+ * single row and returns error
-+ */
-+int nomadik_kp_ghostkey_detect(short rowval)
-+{
-+      int row;
-+      int ghcnt = 0;
++      /*Fetch the Resources, using platform data */
 +
-+      for (row = 0; row < MAX_KPROW; row++) {
-+              if (0 == (rowval & keychkval_read[row])) {
-+                      /*keypr detected */
-+                      ghcnt++;
-+              }
-+              /* return error if more than one keys are pressed in a row */
-+              if (1 < ghcnt)
-+                      return (-1);
++      res = &(adev->res);
++      if (res == NULL) {
++              dev_err(&adev->dev, "probe - MEM resources not defined\n");
++              status = -ENODEV;
++              goto err_no_iores;
++      }
++      /*Get Hold of Device Register Area... */
++      drv_data->regs = ioremap(res->start, (res->end - res->start));
++      if (drv_data->regs == NULL) {
++              status = -ENODEV;
++              goto err_no_iores;
++      }
++      irq = adev->irq[0];
++      if (irq <= 0) {
++              status = -ENODEV;
++              goto err_no_iores;
 +      }
-+      return (0);
-+}
-+
-+/**
-+ * nomadik_kp_key_scan - keypad scan and report event function
-+ *
-+ * Scans through keypad hardware and updates the key status for key press
-+ * or key release event to upper layer
-+ */
-+int nomadik_kp_key_scan(struct keypad_t *kp)
-+{
-+      short val;
-+      u8 row, col;
-+      int keyp_cnt = 0;
-+      u8 *p_kcode;;
 +
-+      nmdk_dbg_ftrace();
-+      for (col = 0; col < MAX_KPCOL; col++) {
-+              p_kcode = kp->board->kcode_tbl + col;
-+              nomadik_epio_write_keypad(keychkval_set[col]);
-+              val = nomadik_epio_read_keypad();
-+              val &= KSCAN_ALLROWS;
-+              if (0 == nomadik_kp_ghostkey_detect(val)) {
-+                      for (row = 0; row < MAX_KPROW; row++) {
-+                              if (0 == (val & keychkval_read[row])) {
-+                                      /*keypr detected */
-+                                      keyp_cnt++;
-+                                      if (kp->key_state[row][col] ==
-+                                          KEYPAD_STATE_DEFAULT) {
-+                                              input_report_key(kp->inp_dev,
-+                                                               *p_kcode, 1);
-+                                              nmdk_dbg("P:%d ", *p_kcode);
-+                                              kp->key_state[row][col] =
-+                                                  KEYPAD_STATE_PRESSACK;
-+                                      }
-+                              } else {
-+                                      /*key not pressed detected */
-+                                      if (kp->key_state[row][col] ==
-+                                          KEYPAD_STATE_PRESSACK) {
-+                                              input_report_key(kp->inp_dev,
-+                                                               *p_kcode, 0);
-+                                              nmdk_dbg("R:%d ", *p_kcode);
-+                                              kp->key_state[row][col] =
-+                                                  KEYPAD_STATE_DEFAULT;
-+                                      }
-+                              }
-+                              p_kcode += MAX_KPROW;
-+                      }
-+              } else
-+                      keyp_cnt += 0x100;      /* to flag ghost keypress detection */
++      /*Set flag for MSPx*/
++      switch(platform_info->id) {
++              case MSP_0_CONTROLLER:
++                      drv_data->flag_msp0 = (spi_msp_user *)flag_msp0;
++                      break;
++              case MSP_1_CONTROLLER:
++                      drv_data->flag_msp1 = (spi_msp_user *)flag_msp1;
++                      break;
++              case MSP_2_CONTROLLER:
++                      drv_data->flag_msp2 = (spi_msp_user *)flag_msp2;
++                      break;
++              default:
++                      dev_err(&adev->dev, "unknown controller  Id  %d\n", platform_info->id);
++                      status = -EINVAL;
++                      break;
 +      }
-+      /* pull down all rows to detect any keypress */
-+      nomadik_epio_write_keypad(KSCAN_ALLROWS);
-+      return (keyp_cnt);
-+}
 +
-+/**
-+ * nomadik_kp_init_key_hardware -  keypad hardware initialization
-+ *
-+ * Initializes the keypad hardware specific parameters.
-+ * This function will be called by nomadik_keypad_init function during init
-+ * Initialize keypad interrupt handler for interrupt mode operation if enabled
-+ * Initialize Keyscan matrix
-+ ****************************************************************************
-+ */
-+int nomadik_kp_init_key_hardware(struct keypad_t *kp)
-+{
-+      int err;
-+      gpio_data pin;
++      if(status == -EINVAL)
++              goto err_no_irqres;
 +
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_keypad(KSCAN_ALLROWS | KSCAN_ALLCOLS);
-+      nomadik_epio_read_keypad();
-+      if ((KSCAN_ALLROWS | KSCAN_ALLCOLS) != nomadik_epio_read_keypad()) {
-+              /*check wrong key */
-+              nmdk_error("H/w error....");
-+              goto kphwiniterr_hwer;
++      nmdk_dbg(":::: MSP Controller = %d\n", platform_info->id);
++      drv_data->execute_cmd = msp_controller_cmd;
++      drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
++      master->setup = nomadik_msp_setup;
++
++      /*Required Info for an SPI controller */
++      /*Bus Number Which has been Assigned to this SPI controller on this board */
++      master->bus_num = (u16) platform_info->id;
++      master->num_chipselect = platform_info->num_chipselect;
++      master->cleanup = nomadik_spi_cleanup;
++      master->transfer = nomadik_spi_transfer;
++
++      nmdk_dbg(":::: BUSNO: %d\n", master->bus_num);
++      /* Initialize and start queue */
++      status = init_queue(drv_data);
++      if (status != 0) {
++              dev_err(&adev->dev, "probe - problem initializing queue\n");
++              goto err_init_queue;
 +      }
-+      if (!kp->mode) {        /* true if interrupt mode operation */
-+              /* Enable keypad interrupt generation logic in CPLD on ndk10 */
-+              nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS);
-+              nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() |
-+                                         GPIO_EN);
-+              nmdk_dbg("keypad interrupt CPLD logic enabled");
++      status = start_queue(drv_data);
++      if (status != 0) {
++              dev_err(&adev->dev, "probe - problem starting queue\n");
++              goto err_start_queue;
++      }
++      /*Initialize tasklet for DMA transfer*/
++      tasklet_init(&drv_data->spi_dma_tasklet, nomadik_spi_tasklet,
++                   (unsigned long)drv_data);
 +
-+              if (!kp->irq) {
-+                      nmdk_error("keypad_irq cannot get in kpinit");
-+                      err = -1;
-+                      goto kphwiniterr_pinconfig;
-+              }
-+              set_irq_type(kp->irq, SA_TRIGGER_FALLING);
-+              nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(kp->irq), &pin);
-+              if (!pin) {
-+                      /*check wrong configuration */
-+                      nmdk_error("H/w error...(check sw8 on board)");
-+                      goto kphwiniterr_itpin;
-+              }
++      /* Register with the SPI framework */
++      platform_set_drvdata(adev, drv_data);
++      status = spi_register_master(master);
++      if (status != 0) {
++              dev_err(&adev->dev, "probe - problem registering spi master\n");
++              goto err_spi_register;
 +      }
++      dev_dbg(dev, "probe succeded\n");
++      nmdk_dbg(" Bus Number = %d, IRQ Line = %d, Virtual Addr: %x\n", master->bus_num, irq, (u32)(drv_data->regs) );
 +      return 0;
++#endif
++      return status;
 +
-+      kphwiniterr_itpin:
-+      kphwiniterr_pinconfig:
-+      kphwiniterr_hwer:
-+      return -1;
-+}
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++      err_init_queue:
++      err_start_queue:
++      err_spi_register:
++      destroy_queue(drv_data);
++      err_no_irqres:
++      err_no_iores:
++      spi_master_put(master);
++      err_no_mem:
++#endif
++      if((flag_msp2) && (platform_info->id == MSP_2_CONTROLLER))
++              kfree(flag_msp2);
++      err_msp2:
++      if((flag_msp1) && (platform_info->id == MSP_1_CONTROLLER))
++              kfree(flag_msp1);
++      err_msp1:
++      if((flag_msp0) && (platform_info->id == MSP_0_CONTROLLER))
++              kfree(flag_msp0);
++      err_msp0:
++        err_no_pdata:
++      return status;
 +
-+/**
-+ * nomadik_kp_exit_key_hardware- keypad hardware exit function
-+ *
-+ * This function will be called by nomadik_keypad_exit function during module
-+ * exit, frees keypad interrupt if enabled
-+ */
-+int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
-+{
-+      nmdk_dbg_ftrace();
-+      return 0;
 +}
 +
-+/**
-+ * nomadik_kp_key_irqen- enables keypad interrupt
-+ *
-+ * enables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqen(struct keypad_t *kp)
++static int msp_remove(struct amba_device *adev)
 +{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS);
-+      return 0;
-+}
++      struct driver_data *drv_data = platform_get_drvdata(adev);
++      struct device *dev = &adev->dev;
++      struct nmdk_spi_master_cntlr *platform_info;
++      int irq;
++      int status = 0;
++      if (!drv_data)
++              return 0;
 +
-+/**
-+ * nomadik_kp_key_irqdis- disables keypad interrupt
-+ *
-+ * disables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqdis(struct keypad_t *kp)
-+{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_keypad(KSCAN_ALLROWS);
-+      return 0;
-+}
++      platform_info = dev->platform_data;
 +
-+/*
-+ * Initializes the key scan table (lookup table) as per pre-defined the scan
-+ * codes to be passed to upper layer with respective key codes
-+ */
-+static u8 kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
-+      {KEY_DOWN, KEY_END, KEY_KPASTERISK, KEY_0, KEY_COMMA},
-+      {KEY_RIGHT, KEY_F5, KEY_7, KEY_8, KEY_9},
-+      {KEY_ENTER, KEY_LEFT, KEY_4, KEY_5, KEY_6},
-+      {KEY_RIGHTMETA, KEY_F4, KEY_1, KEY_2, KEY_3},
-+      {KEY_LEFTMETA, KEY_UP, KEY_F1, KEY_F2, KEY_F3}
-+};
++#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE))
++      /* Remove the queue */
++      status = destroy_queue(drv_data);
++      if (status != 0) {
++              dev_err(&adev->dev, "queue remove failed (%d)\n", status);
++              return status;
++      }
++      drv_data->execute_cmd(drv_data, LOAD_DEFAULT_CONFIG);
 +
-+static struct keypad_device keypad_board = {
-+      .init = nomadik_kp_init_key_hardware,
-+      .exit = nomadik_kp_exit_key_hardware,
-+      .scan = nomadik_kp_key_scan,
-+      .irqen = nomadik_kp_key_irqen,
-+      .irqdis = nomadik_kp_key_irqdis,
-+      .kcode_tbl = (u8 *) kpd_lookup_tbl,
-+      .krow = 8,
-+      .kcol = 8,
-+};
++      irq = adev->irq[0];
++      if (irq >= 0)
++              free_irq(irq, drv_data);
 +
-+static struct resource keypad_resources[] = {
-+      [0] = {
-+             .start = IRQNO_GPIO(KEYPAD_IRQ),
-+             .end = IRQNO_GPIO(KEYPAD_IRQ),
-+             .flags = IORESOURCE_IRQ,
-+             },
-+};
++      /* Release map resources */
++      iounmap(drv_data->regs);
++      tasklet_disable(&drv_data->pump_transfers);
++      tasklet_kill(&drv_data->spi_dma_tasklet);
++      nomadik_gpio_altfuncdisable(platform_info->gpio_alt_func, platform_info->device_name);
 +
-+static struct platform_device keypad_device = {
-+      .name = "nmdk-kp",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &keypad_board,
-+              },
-+      .num_resources = ARRAY_SIZE(keypad_resources),
-+      .resource = keypad_resources,
-+};
++      /* Disconnect from the SPI framework */
++      spi_unregister_master(drv_data->master);
++      spi_master_put(drv_data->master);
 +
-+/*
-+ ***********************************************************************
-+ */
-+static struct platform_device *nmdk_platform_devices[] __initdata = {
-+      &smc91x_device,
-+      &keypad_device,
-+      &touchp_device,
-+#ifdef CONFIG_MTD
-+      &nomadik_nand_flash,
-+      &nomadik_nor_flash,
++      /* Prevent double remove */
++      platform_set_drvdata(adev, NULL);
++      dev_dbg(&adev->dev, "remove succeded\n");
 +#endif
-+};
++      if(platform_info->id == MSP_0_CONTROLLER) {
++              if(flag_msp0)
++                      kfree(flag_msp0);
++              else
++                      printk("MSP Error:why flag_msp0==NULL???");
++      }
++      if(platform_info->id == MSP_1_CONTROLLER) {
++              if(flag_msp1)
++                      kfree(flag_msp1);
++              else
++                      printk("MSP Error:why flag_msp1==NULL???");
++      }
++      if(platform_info->id == MSP_2_CONTROLLER) {
++              if(flag_msp2)
++                      kfree(flag_msp2);
++              else
++                      printk("MSP Error:why flag_msp2==NULL???");
++      }
 +
-+void add_nmdk_platform_devices(void)
-+{
-+      platform_add_devices(nmdk_platform_devices,
-+                           ARRAY_SIZE(nmdk_platform_devices));
-+      nomadik_epio_init();
-+      nomadik_platform_board_init();
-+      nomadik_fsmc_init();
-+      nomadik_pepperpot_board_init();
-+      nomadik_smc91x_irq_init();
++      return 0;
 +}
 +
++static struct amba_id msp_ids[] = {
++      {
++       .id = MSP_PER_ID,
++       .mask = MSP_PER_MASK,
++       },
++      {0, 0},
++};
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c       2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,1023 @@
-+/*
-+ *  linux/arch/arm/mach-nomadik/ndk15c02_devices.c
-+ *
-+ *  Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2, as
-+ * published by the Free Software Foundation.
-+ *
-+ *  NDK15C02 board specifc driver defination
-+ */
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/amba/bus.h>
-+#include <linux/spi/spi.h>
-+#include <linux/amba/kmi.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/setup.h>
-+#include <asm/param.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/time.h>
-+#include <asm/arch/i2c.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/kpd.h>
-+#include <asm/arch/touchp.h>
-+#include <asm/arch/fsmc.h>
-+#ifdef CONFIG_MTD
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/concat.h>
-+#include <asm/arch/nandflash.h>
-+#include <asm/mach/flash.h>
-+#endif
-+#include <asm/arch/debug.h>
-+
-+#define BOARD_NAME            CONFIG_NOMADIK_PLATFORM
-+#ifndef BOARD_DEBUG
-+#define BOARD_DEBUG 0
-+#endif
++static struct amba_driver msp_driver = {
++      .drv = {
++              .name = "MSP",
++              },
++      .id_table = msp_ids,
++      .probe = msp_probe,
++      .remove = msp_remove
++};
 +
-+#define NMDK_DEBUG    BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++EXPORT_SYMBOL(nomadik_msp_configure);
++EXPORT_SYMBOL(nomadik_msp_send_data);
++EXPORT_SYMBOL(nomadik_msp_receive_data);
++EXPORT_SYMBOL(nomadik_msp_transceive_data);
++EXPORT_SYMBOL(nomadik_msp_enable);
++EXPORT_SYMBOL(nomadik_msp_disable);
++EXPORT_SYMBOL(nomadik_msp_flush_input);
 +
-+/**
-+ * nomadik_clcd_board_enable - enables board specific clcd prameters
-+ *
-+ * Settings to enable backlight and pannel voltage regulator for NDK15
-+ */
-+void nomadik_clcd_enable(void *fbp)
++static int __init nomadik_msp_mod_init(void)
 +{
-+      /* not implimented for this board */
++      return amba_driver_register(&msp_driver);
 +}
 +
-+/**
-+ * nomadik_clcd_board_disable - disables board specific clcd prameters
-+ *
-+ * Settings to disable backlight and pannel voltage regulator for NDK10
-+ */
-+void nomadik_clcd_disable(void *fbp)
++static void __exit nomadik_msp_exit(void)
 +{
-+      /* not implimented for this board */
++      amba_driver_unregister(&msp_driver);
++      return;
 +}
++module_init(nomadik_msp_mod_init);
++module_exit(nomadik_msp_exit);
 +
-+//#ifdef CONFIG_MMC_NOMADIK
-+/*
-+ * Settings to configure MMC controller for NDK10
++MODULE_AUTHOR("STMicroelectronics Pvt Ltd");
++MODULE_DESCRIPTION("NOMADIK MSP driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/msp.h
+@@ -0,0 +1,383 @@
++/*linux/drivers/char/nomadik-msp.h
++ *
++ *  Driver for Nomadik STN8810 MSP device.  Note that this module MUST NOT
++ *  attempt to load before the i2c and gpio drivers are loaded.
++ *
++ *  Copyright 2006 STMicroelectronics Pvt. Ltd.
++ *
++ *  This program is free sofstware; 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.
++ *
 + */
-+int nomadik_mmc_configure(struct amba_device *dev)
-+{
-+      int ret;
-+      gpio_config mmc_pin;
-+      char x = val_volt;
-+
-+      mmc_pin.dev_name = dev->dev.bus_id;
-+      mmc_pin.mode = GPIO_MODE_SOFTWARE;
-+      mmc_pin.direction = GPIO_DIR_OUTPUT;
-+      mmc_pin.trig = GPIO_TRIG_DISABLE;
-+      mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
 +
-+      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
-+      if (ret) {
-+              nmdk_error("Error in setting GPIO_PIN_75");
-+              goto mmcconf_exit;
-+      }
-+      /* this enables power path from toureg to mmc */
-+      ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id);
-+      if (ret) {
-+              nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
-+              goto deallocate_pin_75;
-+      }
++#ifndef NMDK_MSP_HEADER
++#define NMDK_MSP_HEADER
 +
-+      ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
-+      if (ret) {
-+              nmdk_error("Error in writing value to touareg register");
-+              goto deallocate_pin_75;
-+      }
++struct msp_register
++{
++        u32 fifo;
++        u32 global_ctrl;
++        u32 tx_config;
++        u32 rx_config;
++        u32 srg_ctrl;
++        u32 status;
++        u32 dma_ctrl;
++        u32 reserved0;
++        u32 irq_mask;
++        u32 raw_irq_status;
++        u32 masked_irq_status;
++        u32 irq_clear;
++        u32 multichannel_ctrl;
++        u32 rx_compare_val;
++        u32 rx_compare_mask;
++        u32 reserved1;
++        u32 tx_enable_ch0;
++        u32 tx_enable_ch1;
++        u32 tx_enable_ch2;
++        u32 tx_enable_ch3;
++        u32 reserved2[4];
++        u32 rx_enable_ch0;
++        u32 rx_enable_ch1;
++        u32 rx_enable_ch2;
++        u32 rx_enable_ch3;
++        u32 reserved3[4];
++        u32 test_ctrl;
++        u32 integration_test_input;
++        u32 integration_test_output;
++        u32 test_data;
++};
 +
-+      ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
-+      if (ret) {
-+              nmdk_error("Error in gpio Altfunction enable");
-+              goto deallocate_pin_75;
-+      }
-+      return ret;
++struct msp_context {
++      u8  direction;
++      u8  mode;
++      u8  protocol;
++      int  frame_freq;
++      int  frame_size;
++      enum msp_data_size requested_data_size;
++      enum msp_data_size actual_data_size;
 +
-+      deallocate_pin_75:
-+      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
-+      mmcconf_exit:
-+      return ret;
++      u32 rx_channel_0_enable;
++      u32 rx_channel_1_enable;
++      u32 rx_channel_2_enable;
++      u32 rx_channel_3_enable;
++      u32 tx_channel_0_enable;
++      u32 tx_channel_1_enable;
++      u32 tx_channel_2_enable;
++      u32 tx_channel_3_enable;
++      u32 multichannel_ctrl_reg;
++      u32 rx_compare_mask_reg;
++      u32 irq_mask_reg;
 +
-+}
++      u8  compression_mode;
++      u8  expansion_mode;
++      u8  coprocessor_mode;
++      int msp_disable;
++};
 +
-+void nomadik_mmc_restore_default(struct amba_device *dev)
++ struct msp_mode_status
 +{
-+      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
-+      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
-+}
-+//#endif
++      int work_mode;
++      int phase_mode;
++      int stereo_mode;
++      volatile u16 *it_mono_data_flow;
++      volatile u32 *it_stereo_data_flow;
++      volatile u32 it_halfwords_count;
++      volatile u32 flow_error_count;
++} msp_mode_status;
 +
-+static int fsmc_platform_init(void)
++
++/* Single or dual phase mode */
++enum
 +{
-+      unsigned char __iomem *fsmc_base;
++      MSP_SINGLE_PHASE,
++      MSP_DUAL_PHASE
++};
 +
-+      nmdk_dbg_ftrace();
-+      /*Following Settings done for NAND flash protect off */
-+      fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
 +
-+      /* for NOR accesss */
-+      /* Initialize the fsmc bank 0 */
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
-+      /* Initialize the fsmc bank 1 used for ethernet controller */
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db;
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702;  /*old 00000702 */
++/* Transmit/Receive shifter status
++-----------------------------------*/
++enum
++{
++        MSP_SxHIFTER_IDLE   = 0,
++        MSP_SHIFTER_WORKING = 1
++};
 +
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
-+      /* Above Settings done for NAND flash protect off */
-+      return 0;
-+}
 +
-+static struct resource fsmc_resources[] = {
-+      [0] = {
-+             .start = NOMADIK_FSMC_BASE,
-+             .end = NOMADIK_FSMC_BASE + SZ_4K - 1,
-+             .flags = IORESOURCE_MEM,
-+             },
++/* Transmit/Receive FIFO status
++---------------------------------*/
++enum
++{
++      MSP_FIFO_FULL,
++      MSP_FIFO_PART_FILLED,
++      MSP_FIFO_EMPTY
 +};
 +
-+struct fsmc_platform_data fsmc_data = {
-+      .init = fsmc_platform_init,
-+};
 +
-+static struct platform_device fsmc_device = {
-+      .name = "NOMADIK-FSMC",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &fsmc_data,
-+              },
-+      .num_resources = ARRAY_SIZE(fsmc_resources),
-+      .resource = fsmc_resources,
++/* Frame length
++------------------*/
++enum
++{
++      MSP_FRAME_LENGTH_1              = 0,
++      MSP_FRAME_LENGTH_2              = 1,
++      MSP_FRAME_LENGTH_4              = 3,
++      MSP_FRAME_LENGTH_8              = 7,
++      MSP_FRAME_LENGTH_12             = 11,
++      MSP_FRAME_LENGTH_16             = 15,
++      MSP_FRAME_LENGTH_20             = 19,
++      MSP_FRAME_LENGTH_32             = 31,
++      MSP_FRAME_LENGTH_48             = 47,
++      MSP_FRAME_LENGTH_64             = 63
 +};
 +
-+#ifdef CONFIG_MTD
-+static struct resource nandflash_resources[] = {
-+      [0] = {
-+             .name = "cmem_address",
-+             .start = NAND_B0_CMEM_ADDR,
-+             .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [1] = {
-+             .name = "cmem_command",
-+             .start = NAND_B0_CMEM_CMD,
-+             .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [2] = {
-+             .name = "cmem_data",
-+             .start = NAND_B0_CMEM_DATA,
-+             .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
++/* Element length */
++enum
++{
++      MSP_ELEM_LENGTH_8               = 0,
++      MSP_ELEM_LENGTH_10              = 1,
++      MSP_ELEM_LENGTH_12              = 2,
++      MSP_ELEM_LENGTH_14              = 3,
++      MSP_ELEM_LENGTH_16              = 4,
++      MSP_ELEM_LENGTH_20              = 5,
++      MSP_ELEM_LENGTH_24              = 6,
++      MSP_ELEM_LENGTH_32              = 7
 +};
 +
-+#define NAND_STM_LP_OPTIONS \
-+              (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
-+
-+int nomadik_nandflash_exit(void)
-+{
-+      return 0;
 +
-+}
-+int nomadik_nandflash_init(void)
++/* Data delay (in bit clock cycles)
++---------------------------------------*/
++enum
 +{
-+      /* 
-+       * FSMC initialization 
-+       * 0x0000001e => PCR0
-+       * 0x000d0a00 => PMEM0
-+       * 0x00100a00 => PATT0
-+       */
-+
-+/*    pcr0.address_low        = 0;*/
-+      gpio_config nmdknand_pin_config;
-+      nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
-+      nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
-+      nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
-+      nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      nmdknand_pin_config.dev_name = "nand";
-+      /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */
-+      nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config);
-+      nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name);
-+      /*Following Settings done for NAND flash protect off */
-+      nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config);
-+      nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name);
-+      nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name);
++      MSP_DELAY_0                     = 0,
++      MSP_DELAY_1                     = 1,
++      MSP_DELAY_2                     = 2,
++      MSP_DELAY_3                     = 3
++};
 +
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
-+          DEFAULT_PCR0_VALUE;
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
-+          DEFAULT_PMEM0_VALUE;
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
-+          DEFAULT_PATT0_VALUE;
-+      return 0;
-+}
 +
-+const unsigned char lookup_t[256] = {
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
-+      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
++/* Configurations of clocks (transmit, receive or sample rate generator)
++-------------------------------------------------------------------------*/
++enum
++{
++      MSP_RISING_EDGE                 = 0,
++      MSP_FALLING_EDGE                = 1
 +};
 +
-+int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
-+                          u_char * ecc)
++/* Protocol dependant parameters list */
++struct msp_protocol_desc
 +{
-+      unsigned int sumCol = 0;
-+      unsigned int datum, temp;
-+      unsigned int glob_parity;
-+      const int ecc_n_bytes = 512;
-+      int i;
++        u32 phase_mode;
++        u32 frame_len_1;
++        u32 frame_len_2;
++        u32 element_len_1;
++        u32 element_len_2;
++        u32 data_delay;
++        u32 tx_clock_edge;
++        u32 rx_clock_edge;
++};
 +
-+      unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
-+      unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
-+          0, parit32_1 = 0, parit32_2 = 0;
-+      unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
-+          0, parit256_1 = 0, parit256_2 = 0;
-+      unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
-+          0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++#define RX_ENABLE_MASK         0x00000001
++#define RX_FIFO_ENABLE_MASK    0x00000002
++#define RX_FRAME_SYNC_MASK     0x00000004
++#define DIRECT_COMPANDING_MASK 0x00000008
++#define RX_SYNC_SEL_MASK       0x00000010
++#define RX_CLK_POL_MASK        0x00000020
++#define RX_CLK_SEL_MASK        0x00000040
++#define LOOPBACK_MASK          0x00000080
++#define TX_ENABLE_MASK         0x00000100
++#define TX_FIFO_ENABLE_MASK    0x00000200
++#define TX_FRAME_SYNC_MASK     0x00000400
++#define TX_SYNC_SEL_MASK       0x00001800
++#define TX_CLK_POL_MASK        0x00002000
++#define TX_CLK_SEL_MASK        0x00004000
++#define TX_EXTRA_DELAY_MASK    0x00008000
++#define SRG_ENABLE_MASK        0x00010000
++#define SRG_CLK_POL_MASK       0x00020000
++#define SRG_CLK_SEL_MASK       0x000C0000
++#define FRAME_GEN_EN_MASK      0x00100000
++#define SPI_CLK_MODE_MASK      0x00600000
++#define SPI_BURST_MODE_MASK    0x00800000
 +
-+      for (i = ecc_n_bytes - 1; i >= 0; --i) {
-+              datum = data[i];
-+              sumCol ^= datum;
-+              temp = lookup_t[datum];
++#define RXEN_BIT              0
++#define RFFEN_BIT             1
++#define RFSPOL_BIT            2
++#define DCM_BIT               3
++#define RFSSEL_BIT            4
++#define RCKPOL_BIT            5
++#define RCKSEL_BIT            6
++#define LBM_BIT               7
++#define TXEN_BIT              8
++#define TFFEN_BIT             9
++#define TFSPOL_BIT            10
++#define TFSSEL_BIT            11
++#define TCKPOL_BIT            13
++#define TCKSEL_BIT            14
++#define TXDDL_BIT             15
++#define SGEN_BIT              16
++#define SCKPOL_BIT            17
++#define SCKSEL_BIT            18
++#define FGEN_BIT              20
++#define SPICKM_BIT            21
 +
-+              if (i & 0x01)
-+                      parit8_1 ^= temp;
-+              if (i & 0x02)
-+                      parit16_1 ^= temp;
-+              if (i & 0x04)
-+                      parit32_1 ^= temp;
-+              if (i & 0x08)
-+                      parit64_1 ^= temp;
-+              if (i & 0x10)
-+                      parit128_1 ^= temp;
-+              if (i & 0x20)
-+                      parit256_1 ^= temp;
-+              if (i & 0x40)
-+                      parit512_1 ^= temp;
-+              if (i & 0x80)
-+                      parit1024_1 ^= temp;
-+              if (i & 0x100)
-+                      parit2048_1 ^= temp;
-+      }
++#define msp_rx_clkpol_bit(n)     ((n & 1) << RCKPOL_BIT)
++#define msp_tx_clkpol_bit(n)     ((n & 1) << TCKPOL_BIT)
++#define msp_spi_clk_mode_bits(n) ((n & 3) << SPICKM_BIT)
 +
-+      glob_parity = lookup_t[sumCol];
 +
-+      parit1_1 =
-+          ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
-+      parit1_2 =
-+          ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
-+      parit2_1 =
-+          ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+      parit2_2 =
-+          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
-+      parit4_1 =
-+          ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
-+      parit4_2 =
-+          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++/* Use this to clear the clock mode bits to non-spi */
++#define MSP_NON_SPI_CLK_MASK 0x00600000
 +
-+      parit8_2 = glob_parity ^ parit8_1;
-+      parit16_2 = glob_parity ^ parit16_1;
-+      parit32_2 = glob_parity ^ parit32_1;
-+      parit64_2 = glob_parity ^ parit64_1;
-+      parit128_2 = glob_parity ^ parit128_1;
-+      parit256_2 = glob_parity ^ parit256_1;
-+      parit512_2 = glob_parity ^ parit512_1;
-+      parit1024_2 = glob_parity ^ parit1024_1;
-+      parit2048_2 = glob_parity ^ parit2048_1;
++#define P1ELEN_BIT            0
++#define P1FLEN_BIT            3
++#define DTYP_BIT              10
++#define ENDN_BIT              12
++#define DDLY_BIT              13
++#define FSIG_BIT              15
++#define P2ELEN_BIT            16
++#define P2FLEN_BIT            19
++#define P2SM_BIT              26
++#define P2EN_BIT              27
 +
-+      /* Pack bits */
-+      ecc[0] =
-+          ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
-+            (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
-+                                                                      << 1) |
-+            parit8_2);
-+      ecc[1] =
-+          ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
-+            (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
-+            (parit128_1 << 1) | parit128_2);
-+      ecc[2] =
-+          ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
-+            (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
-+                                                                   << 1) |
-+            parit2048_2);
++#define msp_p1_elem_len_bits(n) (n & 0x00000007)
++#define msp_p2_elem_len_bits(n)  (((n) << P2ELEN_BIT) & 0x00070000)
++#define msp_p1_frame_len_bits(n) (((n) << P1FLEN_BIT) & 0x00000378)
++#define msp_p2_frame_len_bits(n) (((n) << P2FLEN_BIT) & 0x03780000)
++#define msp_data_delay_bits(n)   (((n) << DDLY_BIT) & 0x00003000)
++#define msp_data_type_bits(n)    (((n) << DTYP_BIT) & 0x00000600)
++#define msp_p2_start_mode_bit(n) (n << P2SM_BIT)
++#define msp_p2_enable_bit(n)     (n << P2EN_BIT)
 +
-+      return 0;
-+}
++/* Flag register
++--------------------*/
++#define RX_BUSY       0x00000001
++#define RX_FIFO_EMPTY 0x00000002
++#define RX_FIFO_FULL  0x00000004
++#define TX_BUSY       0x00000008
++#define TX_FIFO_EMPTY 0x00000010
++#define TX_FIFO_FULL  0x00000020
 +
-+static struct nand_ecclayout nand_oob = {
++#define RBUSY_BIT             0
++#define RFE_BIT                       1
++#define RFU_BIT                       2
++#define TBUSY_BIT             3
++#define TFE_BIT                       4
++#define TFU_BIT                       5
 +
-+      .eccbytes = 12,
++/* Multichannel control register
++---------------------------------*/
++#define RMCEN_BIT             0
++#define RMCSF_BIT             1
++#define RCMPM_BIT             3
++#define TMCEN_BIT             5
++#define TNCSF_BIT             6
 +
++/* Sample rate generator register
++------------------------------------*/
++#define SCKDIV_BIT            0
++#define FRWID_BIT             10
++#define FRPER_BIT             16
 +
++#define SCK_DIV_MASK 0x0000003FF
++#define frame_width_bits(n) (((n) << FRWID_BIT)  &0x0000FC00)
++#define frame_period_bits(n) (((n) << FRPER_BIT) &0x1FFF0000)
 +
-+      .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
-+      .oobavail = MTD_NANDECC_AUTOPLACE,
-+      .oobfree = {            
-+              { .offset = 8,
-+               .length = 8,
-+              },
-+              },
-+};
 +
-+static struct mtd_partition nandflash_main_partitions[] = {
++/* DMA controller register
++---------------------------*/
++#define RX_DMA_ENABLE 0x00000001
++#define TX_DMA_ENABLE 0x00000002
 +
-+      {.name = "X-Loader(NAND)",
-+       .offset = 0,
-+       .size = 2 * 0x000020000},      /*256 Kbytes */
-+      {.name = "MemInit(NAND)",
-+       .offset = 2 * 0x000020000,
-+       .size = 2 * 0x000020000},      /*128 KBytes */
-+      {.name = "BootLoader(NAND)",
-+       .offset = 4 * 0x000020000,
-+       .size = 16 * 0x00020000},      /*2Mbytes */
-+      {.name = "Kernel zImage(NAND)",
-+       .offset = 20 * 0x000020000,
-+       .size = 24 * 0x000020000},     /*3Mbytes */
-+      {.name = "Root Filesystem(NAND)",
-+       .offset = 44 * 0x000020000,
-+       .size = 176 * 0x000020000},    /*22 Mbytes */
-+      {.name = "User Filesystem(NAND)",
-+       .offset = 220 * 0x000020000,
-+       .size = 800 * 0x000020000},    /*100 Mbytes */
-+};
++#define RDMAE_BIT             0
++#define TDMAE_BIT             1
 +
-+uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++/*Interrupt Register
++-----------------------------------------*/
++#define RECEIVE_SERVICE_INT         0x00000001
++#define RECEIVE_OVERRUN_ERROR_INT   0x00000002
++#define RECEIVE_FRAME_SYNC_ERR_INT  0x00000004
++#define RECEIVE_FRAME_SYNC_INT      0x00000008
++#define TRANSMIT_SERVICE_INT        0x00000010
++#define TRANSMIT_UNDERRUN_ERR_INT   0x00000020
++#define TRANSMIT_FRAME_SYNC_ERR_INT 0x00000040
++#define TRANSMIT_FRAME_SYNC_INT     0x00000080
++#define ALL_INT                     0x000000ff
 +
-+struct nand_bbt_descr bbt_desc = {
-+      .options = 0,
-+      .offs = 0,
-+      .len = 2,
-+      .pattern = scan_ff_pattern
-+};
++/* Protocol configuration values
++* I2S: Single phase, 16 bits, 2 words per frame
++-----------------------------------------------*/
++#define I2S_PROTOCOL_DESC                     \
++{                                                                     \
++      MSP_SINGLE_PHASE,                               \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_ELEM_LENGTH_32,                             \
++      MSP_ELEM_LENGTH_32,                             \
++      MSP_DELAY_1,                                    \
++      MSP_FALLING_EDGE,                               \
++      MSP_FALLING_EDGE                        \
++}
 +
-+static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
-+                                  unsigned int ctrl)
-+{
-+      struct nomadik_nand_info *drvdata =
-+          container_of(mtd, struct nomadik_nand_info, mtd);
++/* Companded PCM: Single phase, 8 bits, 1 word per frame
++--------------------------------------------------------*/
++#define PCM_COMPAND_PROTOCOL_DESC     \
++{                                                                     \
++      MSP_SINGLE_PHASE,                               \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_ELEM_LENGTH_8,                              \
++      MSP_ELEM_LENGTH_8,                              \
++      MSP_DELAY_0,                                    \
++      MSP_RISING_EDGE,                                        \
++      MSP_FALLING_EDGE                                        \
++}
 +
-+      if (cmd == NAND_CMD_NONE)
-+              return;
++/* AC97: Double phase, 1 element of 16 bits during first phase,
++* 12 elements of 20 bits in second phase.
++--------------------------------------------------------------*/
++#define AC97_PROTOCOL_DESC                    \
++{                                                                     \
++      MSP_DUAL_PHASE,                                 \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_FRAME_LENGTH_12,                    \
++      MSP_ELEM_LENGTH_16,                             \
++      MSP_ELEM_LENGTH_20,                             \
++      MSP_DELAY_1,                                    \
++      MSP_RISING_EDGE,                                        \
++      MSP_FALLING_EDGE                                        \
++}
 +
-+      if (ctrl & NAND_NCE) {
-+              *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
-+                                           0x40)) |= 0x04;
-+      }
-+      if (ctrl & NAND_CLE) {
-+              writeb(cmd,drvdata->cmemc_va);
-+      }
-+      if (ctrl & NAND_ALE) {
-+              writeb(cmd,drvdata->cmema_va);
-+      }
++#define SPI_MASTER_PROTOCOL_DESC      \
++{                                                                     \
++      MSP_SINGLE_PHASE,                               \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_ELEM_LENGTH_8,                              \
++      MSP_ELEM_LENGTH_8,                              \
++      MSP_DELAY_1,                                    \
++      MSP_FALLING_EDGE,                               \
++      MSP_RISING_EDGE                         \
++}
++#define SPI_SLAVE_PROTOCOL_DESC               \
++{                                                                     \
++      MSP_SINGLE_PHASE,                               \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_FRAME_LENGTH_1,                             \
++      MSP_ELEM_LENGTH_8,                              \
++      MSP_ELEM_LENGTH_8,                              \
++      MSP_DELAY_1,                                    \
++      MSP_FALLING_EDGE,                               \
++      MSP_RISING_EDGE                         \
 +}
++#define FUNC_MSP0 GPIO_ALT_MSP_0
++#define FUNC_MSP1 GPIO_ALT_MSP_1
++#define FUNC_MSP2 GPIO_ALT_MSP_2
 +
-+static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
-+      .parts = nandflash_main_partitions,
-+      .num_parts = ARRAY_SIZE(nandflash_main_partitions),
-+      .lp_options = NAND_STM_LP_OPTIONS,
-+      .eccsize = 512,
-+      .eccsteps = 4,
-+      .badblockpos = 5,
-+      .init = nomadik_nandflash_init,
-+      .exit = nomadik_nandflash_exit,
-+      .nand_oob = &nand_oob,
-+      .bbt_desc = &bbt_desc,
-+      .compute_ecc = nmdknand_compute_ecc512,
-+      .hwcontrol = nmdknand_hwcontrol,
-+};
++#define MSP_FRAME_PERIOD_IN_MONO_MODE 256
++#define MSP_FRAME_PERIOD_IN_STEREO_MODE 32
++#define MSP_FRAME_WIDTH_IN_STEREO_MODE 16
 +
-+static struct platform_device nomadik_nand_flash = {
-+      .name = "NOMADIK-NAND",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &nomadik_nand_flash_data,
-+              },
-+      .num_resources = ARRAY_SIZE(nandflash_resources),
-+      .resource = nandflash_resources,
-+};
++#define MSP_COUNT 3
 +
-+static struct mtd_partition nmdkflash_main_partitions[] = {
-+      {.name = "BootLoader(NOR)",
-+       .size = 0x00040000,    /*256K */
-+       .offset = 0,},
-+      {.name = "zImage+initrd(NOR)",
-+       .size = 0x001C0000,    /*1.75MB */
-+       .offset = MTDPART_OFS_APPEND,},
-+      {.name = "Root Filesystem(NOR)",
-+       .size = 0x01200000,    /*18MB */
-+       .offset = MTDPART_OFS_APPEND,},
-+      {.name = "User Filesystem(NOR)",
-+       .size = 0x00800000,    /*8MB */
-+       .offset = MTDPART_OFS_APPEND,},
-+      {.name = "initrd(NOR)",
-+       .size = 0x00200000,    /*4MB */
-+       .offset = MTDPART_OFS_APPEND,}
-+};
++#endif
 +
-+static struct flash_platform_data nomadik_nor_flash_data = {
-+      .name = "nomadik_nor",
-+      .map_name = "cfi_probe",
-+      /*.width                = NMDK_FLASH_BUSWIDTH, */
-+      .parts = nmdkflash_main_partitions,
-+      .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
-+};
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/mtu.c
+@@ -0,0 +1,589 @@
++/*
++ * Multiple Timer Unit (MTU) driver.
++ *    Written by Vinayak Pane <vinayak.pane@st.com>
++ *
++ * Nomadik MTU driver.
++ *
++ *    This driver provides an interface for device drivers to utilize both MTUs.
++ *            which includes total 8 timers, Those can be registered against various purposes
++ *            within kernel.
++ *            It keeps track of used & unused timer units. It handles MTU interrupts
++ *            & their respective multiplexing.
++ *
++ * NOTE:
++ *                    This device is NOT registered with amba bus device -:
++ *  Even though this driver should be registered with AMBA bus devices,
++ *    we cant do this becasue of Amba driver initialised/probed sequence issue.
++ *    MTU is used as underlying part of system timer. The system timer
++ *    is initialised and used very early before the actual Amba devices
++ *    are initialised/probed. Therefore this probe function is not invoked
++ *    before the system timer is initialised!!
++ *    However we can catergories this driver in platform/system drivers.
++ */
 +
-+static struct resource norflash_resources[] = {
-+      [0] = {
-+             .name = "norflash-regs",
-+             .start = NMDK_FLASH_BASE,
-+             .end = (NMDK_FLASH_BASE + SZ_32M - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+};
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/device.h>
 +
-+static struct platform_device nomadik_nor_flash = {
-+      .name = "NOMADIK-NOR",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &nomadik_nor_flash_data,
-+              },
-+      .num_resources = ARRAY_SIZE(norflash_resources),
-+      .resource = norflash_resources,
-+};
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++#include <asm/arch/timex.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/mtu.h>
 +
++#ifdef DEBUG_MTU
++#define dbg_mtu(format, arg...)               printk(KERN_WARNING "" format "\n", ##arg)
++#else
++#define dbg_mtu(format, arg...)               do { } while (0)
 +#endif
 +
-+#undef NMDK_DEBUG     /*board*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
++static irqreturn_t(*mtu_irqs[MTU_MAX_TIMERS + 1]) (mtu_timer_t timer_id) = {
++NULL};
++unsigned char mtu_inuse = 0;
++static spinlock_t mtu_inuse_lock;
 +
++static spinlock_t mtu0_spinlock, mtu1_spinlock;
 +
-+#ifdef CONFIG_SMC91X
-+static void nomadik_smc91x_irq_init(void)
++              /* functions to read/write control registers */
++static inline unsigned long mtu_readl(unsigned int timer,
++                                    unsigned long ctrl_register)
 +{
-+      /* Reset ethernet controller */
-+      nomadik_epio_write_aux_gpo1(nomadik_epio_read_aux_gpo1() &
-+                                  (unsigned long)(~LAN_RST));
-+      /* Enabling ethernet interrupts */
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)(~GPIO106_LAN_IT));
-+      /*type need to be set in case of shared irq */
-+      set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING);
++      unsigned long value, r_address = MTU_CTRL_REG(timer, ctrl_register);
++      value = readl(r_address);
++      return value;
 +}
 +
-+static struct resource smc91x_resources[] = {
-+      [0] = {
-+             .name = "smc91x-regs",
-+             .start = (NOMADIK_ETH0_BASE + 0x300),
-+             .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
-+             .flags = IORESOURCE_MEM,
-+             },
-+      [1] = {
-+             .start = IRQNO_GPIO(SMC91111_IRQ),
-+             .end = IRQNO_GPIO(SMC91111_IRQ),
-+             .flags = IORESOURCE_IRQ,
-+             },
-+};
-+
-+static struct platform_device smc91x_device = {
-+      .name = "smc91x",
-+      .id = 0,
-+      .num_resources = ARRAY_SIZE(smc91x_resources),
-+      .resource = smc91x_resources,
-+};
-+#endif
-+
-+/*
-+ * touchpanel
-+ */
-+#ifdef CONFIG_TOUCHSCREEN_NOMADIK
-+#ifndef TOUCHP_DEBUG
-+#define TOUCHP_DEBUG 0                /* default debug messages are disabled */
-+#endif                                /*  */
-+
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#define NMDK_DEBUG    TOUCHP_DEBUG    /* enables/disables debug msgs */
-+#define NMDK_DEBUG_PFX  TPDRVNAME     /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++static inline void mtu_writel(unsigned int timer, long value,
++                            unsigned long ctrl_register)
++{
++      unsigned long w_address = MTU_CTRL_REG(timer, ctrl_register);
++      writel(value, w_address);
++}
 +
-+/**
-+ * nomadik_tp_ssp_board_init - board specific ssp data path setup
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine initializes the SSP for touchpanel operation
-+ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
-+ */
-+int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
++              /* functions to read/write interrupt registers */
++inline unsigned long mtu_intr_reg_readl(unsigned int timer,
++                                      unsigned long ctrl_register)
 +{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_ssp_conf(EXP_SSP);
-+      return (0);
++      unsigned long value, r_address = MTU_INTR_REG(timer, ctrl_register);
++      value = readl(r_address);
++      return value;
 +}
 +
-+/**
-+ * nomadik_tp_gpio_board_init - board specific gpio initialization
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine initializes the GPIO for touchpanel operation
-+ * RETURN: GPIO nmdk_error code
-+ * SSP is interfaced with ADS7843 through CPLD hence respective
-+ * interface need to be enabled for NDK10
-+ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
-+ * chip select, this bit allows the selection between the two
-+ * peripherals. setting this bit Touch screen selected
-+ */
-+gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
++static inline void mtu_intr_reg_writel(unsigned int timer, long value,
++                                     unsigned long ctrl_register)
 +{
-+      gpio_error status = GPIO_OK;
++      unsigned long w_address = MTU_INTR_REG(timer, ctrl_register);
++      writel(value, w_address);
++}
 +
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
++static
++void mtu_set_timer_mode(mtu_timer_t timer, mtu_timer_mode_t mode)
++{
++      unsigned long timer_cr = 0;
 +
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+      {
-+      gpio_config config_cspin;
-+      /* Set SPICSn_TCHSCR pin configuration */
-+      config_cspin.mode = GPIO_MODE_SOFTWARE;
-+      config_cspin.direction = GPIO_DIR_OUTPUT;
-+      config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
-+      config_cspin.dev_name = "Touchp";
-+      status = nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
-+      if (status) {
-+              nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
-+                         TOUCHP_CS0, status);
-+              goto err_TOUCHP_CS0;
-+      }
++      timer_cr = mtu_readl(timer, TyCR);      /* read original control register */
++      switch (mode) {
++      case MTU_PERIODIC:
++              timer_cr &= ~MTU_ONE_SHOT;      /* clear the one-shot mode */
++              timer_cr = timer_cr | MTU_PERIODIC;
++              break;
 +
-+      status = nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
-+      if (status) {
-+              nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
-+                         TOUCHP_CS1, status);
-+              goto err_TOUCHP_CS1;
-+      }
++      case MTU_FREE_RUN:
++              timer_cr = timer_cr & MTU_FREE_RUN;
++              break;
++      case MTU_ONE_SHOT:
++              timer_cr = timer_cr | MTU_ONE_SHOT;
++              break;
 +      }
-+#endif
-+      /* Set PENIRQ pin configuration */
-+      set_irq_type(p_adsContext->irq, SA_TRIGGER_FALLING);
++      mtu_writel(timer, timer_cr, TyCR);      /* write back CR */
++      dbg_mtu("MTU: timer_mode : after CR = %ld\n", timer_cr);
++}
 +
-+      return status;
++#define TyEN  0x0080
++static int mtu_enable_timer(mtu_timer_t timer)
++{
++      unsigned long timer_cr = 0;
++      if (timer > MTU_MAX_TIMERS)
++              return -1;
++      timer_cr = mtu_readl(timer, TyCR);
++      timer_cr |= TyEN;
++      mtu_writel(timer, timer_cr, TyCR);
++      dbg_mtu("MTU: After enable timer CR = %ld\n", timer_cr);
++      return 0;
++}
 +
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+      err_TOUCHP_CS1:
-+      nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
-+      err_TOUCHP_CS0:
-+      return status;
-+#endif
++static void mtu_disable_timer(mtu_timer_t timer)
++{
++      unsigned long timer_cr;
++      timer_cr = mtu_readl(timer, TyCR);
++      timer_cr &= ~(unsigned long)TyEN;
++      mtu_writel(timer, timer_cr, TyCR);
 +}
 +
-+/**
-+ * nomadik_tp_gpio_board_exit - board specific gpio exit
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine performs revers action of init
-+ */
-+gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
++#define TySZ  0x0002
++static int mtu_change_counter_size(mtu_timer_t timer)
 +{
-+      gpio_error status = GPIO_OK;
++      /* by default the timer counter is 16-bit only,
++         we can change its size to 32-bit here. */
 +
-+      nmdk_dbg_ftrace();
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+      status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
-+      status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
-+#endif
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
-+      return status;
++      unsigned long timer_cr = 0;
++      timer_cr = mtu_readl(timer, TyCR);
++      timer_cr |= TySZ;
++      mtu_writel(timer, timer_cr, TyCR);
++      dbg_mtu("MTU: after change_counter_size CR = %ld\n", timer_cr);
++      return 0;
 +}
 +
-+/**
-+ * nomadik_tp_pen_down - returns pen touch status
-+ */
-+t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
++#define DIVIDE_BY_ONE         0xfffffff3
++#define DIVIDE_BY_SIXTEEN     0x00000004
++#define DIVIDE_BY_256         0x00000008
++
++static int mtu_change_timer_prescaler(unsigned int timer,
++                                    mtu_prescale_t prescaler_factor)
 +{
-+      gpio_data pen_down;
++      unsigned long timer_prescaler = 0;
++      timer_prescaler = mtu_readl(timer, TyCR);
 +
-+      nmdk_dbg_ftrace();
-+      nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
-+      nmdk_dbg2("pen_down = 0x%d (pin%d)",
-+               pen_down, GPIO_PIN_FOR_IRQ(p_adsContext->irq));
-+      return ((t_bool) pen_down);
++      switch (prescaler_factor) {
++      case MTU_PRESCALE_BY_ONE:
++              timer_prescaler &= DIVIDE_BY_ONE;
++              break;
++      case MTU_PRESCALE_BY_SIXTEEN:
++              timer_prescaler &= DIVIDE_BY_ONE;       /* reset first */
++              timer_prescaler |= DIVIDE_BY_SIXTEEN;   /* set it to 01b now */
++              break;
++      case MTU_PRESCALE_BY_256:
++              timer_prescaler &= DIVIDE_BY_ONE;
++              timer_prescaler |= DIVIDE_BY_256;
++              break;
++      }
++      mtu_writel(timer, timer_prescaler, TyCR);
++      return 0;
 +}
-+
-+/**
-+ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
++unsigned long mtu_get_decrementing_counter_value(mtu_timer_t timer)
 +{
-+      nmdk_dbg_ftrace();
-+      enable_irq(p_adsContext->irq);
++      unsigned long decrementing_counter = 0;
++      decrementing_counter = mtu_readl(timer, TyVAL);
++      return decrementing_counter;
 +}
 +
-+/**
-+ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
-+ */
-+void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
++EXPORT_SYMBOL(mtu_get_decrementing_counter_value);
++
++static inline void mtu_load_counter(mtu_timer_t timer,
++                                  unsigned long timer_load_register)
 +{
-+      nmdk_dbg_ftrace();
-+      disable_irq(p_adsContext->irq);
++      mtu_writel(timer, timer_load_register, TyLR);
 +}
 +
-+/**
-+ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
-+ *
-+ * sets GPIOS to to provid inputs to CPLD to disable chip select
-+ */
-+void nomadik_tp_spi_cs_disable(void)
++inline void mtu_bg_load_counter(mtu_timer_t timer,
++                              unsigned long timer_load_register)
 +{
-+      nmdk_dbg_ftrace();
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+      nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
-+      nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
-+#endif
++      mtu_writel(timer, timer_load_register, TyBGLR);
 +}
 +
-+/**
-+ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
-+ *
-+ * sets GPIOS to to provid inputs to CPLD to enable chip select
-+ */
-+void nomadik_tp_spi_cs_enable(void)
++EXPORT_SYMBOL(mtu_bg_load_counter);
++
++/***************************************************************
++ *    functiion :     mtu0_timer_interrupt_handler
++ *    Description:
++ *                    Interrupt of MTU Unit 0 is handled.
++ *                    With the priority as MTU0_T0, MTU0_T1,
++ *                    MTU0_T2, MTU0_T3. And then the corrosponding
++ *                    timer unit's interrupt handler will be called.
++ *    Returns:
++ *                    IRQ_HANDLED - ret val from the sub-irq
++ *                    IRQ_HANDLED - if the corrosponding irq is not present.
++ ****************************************************************/
++
++static irqreturn_t mtu0_timer_interrupt_handler(int irq, void *dev_id)
 +{
-+      nmdk_dbg_ftrace();
-+#if defined TOUCHP_CS0 && defined TOUCHP_CS1
-+      nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
-+      nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
-+#endif
-+}
++      unsigned long status;
++      unsigned long icr_flag = 0;
++      mtu_timer_t timer = 0;
 +
-+static struct touchp_device touchp_board = {
-+      .ssp_init = nomadik_tp_ssp_board_init,
-+      .gpio_init = nomadik_tp_gpio_board_init,
-+      .gpio_exit = nomadik_tp_gpio_board_exit,
-+      .pdown = nomadik_tp_pen_down,
-+      .pirq_en = nomadik_tp_pen_down_irq_enable,
-+      .pirq_dis = nomadik_tp_pen_down_irq_disable,
-+      .cs_en = nomadik_tp_spi_cs_disable,
-+      .cs_dis = nomadik_tp_spi_cs_enable,
-+      .samples = 100, /*samples per second*/
-+      .pollsamples = 10, /*polling per second*/
-+};
++      spin_lock(&mtu0_spinlock);
++      status = mtu_intr_reg_readl(MTU0_T0, TxRIS);
++      timer = ffs(status);
++      if ( timer != 1)
++      {
++      icr_flag |= 1UL << (timer - 1);
++      mtu_intr_reg_writel(timer, icr_flag, TxICR);    /* clear ICR bit */
++      }
++      spin_unlock(&mtu0_spinlock);
 +
-+static struct resource touchp_resources[] = {
-+      [0] = {
-+             .start = IRQNO_GPIO(TOUCHP_IRQ),
-+             .end = IRQNO_GPIO(TOUCHP_IRQ),
-+             .flags = IORESOURCE_IRQ,
-+             },
-+};
++      if (likely(mtu_irqs[timer]))
++              return mtu_irqs[timer] (timer);
++      else {
++              dbg_mtu("MTU0:Interrupt on this timer[%d] is not handled.\n",
++                      timer);
++              return IRQ_HANDLED;
++      }
 +
-+static struct platform_device touchp_device = {
-+      .name = "nmdk-tp",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &touchp_board,
-+              },
-+      .num_resources = ARRAY_SIZE(touchp_resources),
-+      .resource = touchp_resources,
-+};
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#endif
++      return IRQ_HANDLED;
++}
 +
-+#ifdef CONFIG_KEYPAD_NOMADIK
-+#define KEYPAD_NAME           "KEYPAD"
-+#ifndef KEYPAD_DEBUG
-+#define KEYPAD_DEBUG 0
-+#endif
++static irqreturn_t mtu1_timer_interrupt_handler(int irq, void *dev_id)
++{
++      unsigned long status;
++      unsigned long icr_flag = 0;
++      mtu_timer_t timer = 0;
 +
-+#define NMDK_DEBUG    KEYPAD_DEBUG    /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  KEYPAD_NAME   /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++      spin_lock(&mtu1_spinlock);
++      status = mtu_intr_reg_readl(MTU1_T0, TxRIS);
++      /* which timer the interrupt is for */
++      timer = ffs(status);
++      icr_flag |= 1UL << (timer - 1);
++      timer = timer + 4;
++      mtu_intr_reg_writel(timer, icr_flag, TxICR);    /* clear ICR bit */
 +
-+/*key scan constants*/
-+#define KSCAN_ALLROWS   0x00FF
-+#define KSCAN_ALLCOLS   0xFF00
-+#define KSCAN_ROW0      0x0001
-+#define KSCAN_ROW1      0x0002
-+#define KSCAN_ROW2      0x0004
-+#define KSCAN_ROW3      0x0008
-+#define KSCAN_ROW4      0x0010
-+#define KSCAN_ROW5      0x0020
-+#define KSCAN_ROW6      0x0040
-+#define KSCAN_ROW7      0x0080
-+#define KSCAN_COL0      0x0100
-+#define KSCAN_COL1      0x0200
-+#define KSCAN_COL2      0x0400
-+#define KSCAN_COL3      0x0800
-+#define KSCAN_COL4      0x1000
-+#define KSCAN_COL5      0x2000
-+#define KSCAN_COL6      0x4000
-+#define KSCAN_COL7      0x8000
++      spin_unlock(&mtu1_spinlock);
++      /* call corrsponding Irq handler */
++      if (likely(mtu_irqs[timer]))
++              return mtu_irqs[timer] (timer);
++      else {
++              dbg_mtu("MTU1:Interrupt on this timer[%d] is not handled.\n",
++                      timer);
++              return IRQ_HANDLED;
++      }
 +
-+unsigned short const keychkval_set[] = {
-+      (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++      return IRQ_HANDLED;
++}
++
++struct irqaction mtu0_timer_irq = {
++      .name = "MTU0 Timer Tick",
++      .flags = SA_INTERRUPT | IRQF_TIMER,
++      .handler = mtu0_timer_interrupt_handler,
++      .dev_id = NULL,
 +};
 +
-+unsigned short const keychkval_read[] = {
-+      KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
-+      KSCAN_ROW6, KSCAN_ROW7,
++struct irqaction mtu1_timer_irq = {
++      .name = "MTU1 Timer Tick",
++      .flags = SA_INTERRUPT | IRQF_TIMER,
++      .handler = mtu1_timer_interrupt_handler,
++      .dev_id = NULL,
 +};
 +
-+/**
-+ * nomadik_kp_ghostkey_detect - ghost key detect function
-+ * @rowval: row in which ghost key to be detected
-+ *
-+ * when more than one key is pressed in the same row the keypad logic cannot
-+ * detect proper key press, the logic here detects multiple keypress on a
-+ * single row and returns error
-+ */
-+int nomadik_kp_ghostkey_detect(short rowval)
++static int mtu_irq_initialize(mtu_timer_t timer,
++                            irqreturn_t(*mtu_sub_irq) (mtu_timer_t timer_id))
 +{
-+      int row;
-+      int ghcnt = 0;
++      unsigned long icr_flag = 0, clean_icrs = 0;
++      unsigned long imsc = 0;
++      unsigned long flags;
 +
-+      for (row = 0; row < MAX_KPROW; row++) {
-+              if (0 == (rowval & keychkval_read[row])) {
-+                      /*keypr detected */
-+                      ghcnt++;
-+              }
-+              if (1 < ghcnt)
-+                      /*return error if more than one keys are pressed in a row */
-+                      return (-1);
-+      }
-+      return (0);
-+}
++      if (mtu_sub_irq == NULL)
++              return -1;
 +
-+/**
-+ * nomadik_kp_key_scan - keypad scan and report event function
-+ *
-+ * Scans through keypad hardware and updates the key status for key press
-+ * or key release event to upper layer
-+ */
-+int nomadik_kp_key_scan(struct keypad_t *kp)
-+{
-+      short val;
-+      u8 row, col;
-+      int keyp_cnt = 0;
-+      u8 *p_kcode;
++      spin_lock(&mtu_inuse_lock);
++      /*      make sure that unregistered timer interrupts are cleared
++         icr_flag = mtu_intr_reg_readl(timer, TxICR);
++         : returns Zero always.                                               */
++      if (timer > 4)
++              clean_icrs = mtu_inuse >> 4;
++      else
++              clean_icrs = mtu_inuse;
++      /* register the irq sub-handler */
++      mtu_irqs[timer] = mtu_sub_irq;
++      spin_unlock(&mtu_inuse_lock);
 +
-+      nmdk_dbg_ftrace();
-+      for (col = 0; col < MAX_KPCOL; col++) {
-+              p_kcode = kp->board->kcode_tbl + col;
-+              nomadik_epio_write_keypad(keychkval_set[col]);
-+              val = nomadik_epio_read_keypad();
-+              val &= KSCAN_ALLROWS;
-+              if (0 == nomadik_kp_ghostkey_detect(val)) {
-+                      for (row = 0; row < MAX_KPROW; row++) {
-+                              if (0 == (val & keychkval_read[row])) { /*keypr detected */
-+                                      keyp_cnt++;
-+                                      if (kp->key_state[row][col] ==
-+                                          KEYPAD_STATE_DEFAULT) {
-+                                              input_report_key(kp->inp_dev,
-+                                                               *p_kcode, 1);
-+                                              nmdk_dbg("P:%d ", *p_kcode);
-+                                              kp->key_state[row][col] =
-+                                                  KEYPAD_STATE_PRESSACK;
-+                                      }
-+                              } else {        /*key not pressed detected */
-+                                      if (kp->key_state[row][col] ==
-+                                          KEYPAD_STATE_PRESSACK) {
-+                                              input_report_key(kp->inp_dev,
-+                                                               *p_kcode, 0);
-+                                              nmdk_dbg("R:%d ", *p_kcode);
-+                                              kp->key_state[row][col] =
-+                                                  KEYPAD_STATE_DEFAULT;
-+                                      }
-+                              }
-+                              p_kcode += MAX_KPROW;
-+                      }
-+              } else
-+                      keyp_cnt += 0x100;      /* to flag ghost keypress detection */
-+      }
-+      /* pull down all rows to detect any keypress */
-+      nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
-+      return (keyp_cnt);
-+}
++      /* the INTR bits/registers will be affected here */
++      if (timer > 4)
++              spin_lock_irqsave(&mtu1_spinlock, flags);
++      else
++              spin_lock_irqsave(&mtu0_spinlock, flags);
 +
-+/**
-+ * nomadik_kp_init_key_hardware -  keypad hardware initialization
-+ *
-+ * Initializes the keypad hardware specific parameters.
-+ * This function will be called by nomadik_keypad_init function during init
-+ * Initialize keypad interrupt handler for interrupt mode operation if enabled
-+ * Initialize Keyscan matrix
-+ ****************************************************************************
-+ */
-+int nomadik_kp_init_key_hardware(struct keypad_t *kp)
-+{
-+      nmdk_dbg_ftrace();
-+      nomadik_epio_write_keypad(KSCAN_ALLCOLS);
-+      if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
-+              /*check wrong key */
-+              nmdk_error("Keypad H/w error....");
-+              return (-1);
-+      }
-+      if (!kp->mode) {        /* true if interrupt mode operation */
-+              /* pull down all rows to detect any keypress */
-+              nomadik_epio_write_keypad(KSCAN_ALLROWS);
-+              set_irq_type(kp->irq, SA_TRIGGER_FALLING);
-+              /*
-+               * TBD logic should be added to detect proper switch settings
-+               * on a board to detect valid interrupt
-+               */
-+      }
-+      return 0;
-+}
++      icr_flag = ~clean_icrs;
++      icr_flag |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
++      mtu_intr_reg_writel(timer, icr_flag, TxICR);
 +
-+/**
-+ * nomadik_kp_exit_key_hardware- keypad hardware exit function
-+ *
-+ * This function will be called by nomadik_keypad_exit function during module
-+ * exit, frees keypad interrupt if enabled
-+ */
-+int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
-+{
-+      nmdk_dbg_ftrace();
-+      /* pull up all columns so that interrupt will not be raised*/
-+      nomadik_epio_write_keypad(KSCAN_ALLCOLS |KSCAN_ALLCOLS);
-+      return 0;
-+}
++      /* enable interrupt */
++      imsc = mtu_intr_reg_readl(timer, TxIMSC);
++      imsc |= 1UL << (timer > 4 ? (timer - 5) : (timer - 1));
++      mtu_intr_reg_writel(timer, imsc, TxIMSC);
 +
-+/**
-+ * nomadik_kp_key_irqen- enables keypad interrupt
-+ *
-+ * enables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqen(struct keypad_t *kp)
-+{
-+      /*enable_irq(kp->irq);*/
++      if (timer > 4)
++              spin_unlock_irqrestore(&mtu1_spinlock, flags);
++      else
++              spin_unlock_irqrestore(&mtu0_spinlock, flags);
 +      return 0;
 +}
 +
-+/**
-+ * nomadik_kp_key_irqdis- disables keypad interrupt
-+ *
-+ * disables keypad interrupt through CPLD logic
-+ */
-+int nomadik_kp_key_irqdis(struct keypad_t *kp)
++int mtu_register_timer(struct mtu_struct *mtu)
 +{
-+      /*disable_irq(kp->irq);*/
-+      return 0;
-+}
++      u64 mtu_interval_ns;
++      mtu_prescale_t mtu_prescale;
++      if (mtu == NULL)
++              return -EINVAL;
++      if (mtu->timer > MTU_MAX_TIMERS)
++              return -EINVAL;
 +
-+/*
-+ * Initializes the key scan table (lookup table) as per pre-defined the scan
-+ * codes to be passed to upper layer with respective key codes
-+ */
-+u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
-+      {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
-+      {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
-+      {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT,
-+       KEY_HOME},
-+      {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U},
-+      {KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH,
-+       KEY_DELETE, KEY_END},
-+      {KEY_CAPSLOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J},
-+      {KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, KEY_DOT,
-+       KEY_COMMA, KEY_SLASH},
-+      {KEY_LEFTSHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M}
-+};
++#ifndef CONFIG_NOMADIK_MTU_SYSTEM_TICK
++      /* if the MTU0 IRQ is not set here, we cant use the timers:
++       * MTU0_T0, MTU0_T1, MTU0_T2 & MTU0_T3
++       */
++      if (mtu->timer <= 4) {
++              printk(KERN_WARNING
++                     "MTU: Can not register, since MTU0 support is absent.\n");
++              return -EINVAL;
++      }
++#endif
 +
-+static struct keypad_device keypad_board = {
-+      .init = nomadik_kp_init_key_hardware,
-+      .exit = nomadik_kp_exit_key_hardware,
-+      .scan = nomadik_kp_key_scan,
-+      .irqen = nomadik_kp_key_irqen,
-+      .irqdis = nomadik_kp_key_irqdis,
-+      .kcode_tbl = (u8 *) kpd_lookup_tbl,
-+      .krow = 8,
-+      .kcol = 8,
-+};
++      spin_lock(&mtu_inuse_lock);
++      if (mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) {
++              printk(KERN_WARNING
++                     "MTU: This timer unit is already in use.\n");
++              spin_unlock(&mtu_inuse_lock);
++              return -EBUSY;
++      } else {
++              mtu_inuse |= (unsigned char)0x1 << (mtu->timer - 1);
++      }
++      spin_unlock(&mtu_inuse_lock);
 +
-+static struct resource keypad_resources[] = {
-+      [0] = {
-+             .start = IRQNO_GPIO(KEYPAD_IRQ),
-+             .end = IRQNO_GPIO(KEYPAD_IRQ),
-+             .flags = IORESOURCE_IRQ,
-+             },
-+};
++      if (mtu->mtu_irq) {
++              mtu_irq_initialize(mtu->timer, mtu->mtu_irq);
++      } else {
++              printk(KERN_WARNING
++                     "MTU: Must specify the action handler for timer.\n");
++              return -EINVAL;
++      }
 +
-+static struct platform_device keypad_device = {
-+      .name = "nmdk-kp",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = &keypad_board,
-+              },
-+      .num_resources = ARRAY_SIZE(keypad_resources),
-+      .resource = keypad_resources,
-+};
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#endif
++      mtu_set_timer_mode(mtu->timer, mtu->mode);
++      mtu_interval_ns = ktime_to_ns(mtu->interval);
 +
-+#ifdef CONFIG_CPLD_I2C
-+#define EPIO_NAME             "EPIO"
-+#ifndef EPIO_DEBUG
-+#define EPIO_DEBUG 0
++      /* calculate the timer load register value from ktime(sec,nsec) format */
++#if BITS_PER_LONG != 64
++      /* XXX  the arithmatic part shall be replaced by ktime_ns-ops */
++      dbg_mtu("MTU: nano second interval passed is : %lld \n",
++              mtu_interval_ns);
++
++      if (mtu_interval_ns / USEC_PER_SEC < (0x6FA * MSEC_PER_SEC)) {
++              mtu_prescale = MTU_PRESCALE_BY_ONE;
++              mtu_interval_ns = mtu_interval_ns * 24 * MSEC_PER_SEC;
++              do_div(mtu_interval_ns, 10);
++      } else {
++              if (mtu_interval_ns / USEC_PER_SEC < (0xB2F * MSEC_PER_SEC)) {
++                      mtu_prescale = MTU_PRESCALE_BY_SIXTEEN;
++                      mtu_interval_ns = mtu_interval_ns * 15 * MSEC_PER_SEC;
++                      do_div(mtu_interval_ns, 100);
++              } else {
++                      mtu_prescale = MTU_PRESCALE_BY_256;
++                      mtu_interval_ns = mtu_interval_ns * 93 * MSEC_PER_SEC;
++                      do_div(mtu_interval_ns, 10000);
++              }
++      }
++
++      do_div(mtu_interval_ns, USEC_PER_SEC);
++
++      if (mtu_interval_ns >> 32) {
++              printk(KERN_WARNING
++                     "MTU: The interval specified is too big to fit in reload value.\n");
++              spin_lock(&mtu_inuse_lock);
++              mtu_irqs[mtu->timer] = NULL;
++              spin_unlock(&mtu_inuse_lock);
++              return -EINVAL;
++      }
++
++      dbg_mtu("MTU: setting the prescaler of timer to [%x]\n", mtu_prescale);
++      mtu_change_timer_prescaler(mtu->timer, mtu_prescale);
++
++      if (mtu_interval_ns >> 16) {
++              dbg_mtu("MTU: changing the counter size to 32 bits\n");
++              mtu_change_counter_size(mtu->timer);
++      }
++
++      dbg_mtu("MTU:Using %lld as calculated interval for timer\n",
++              mtu_interval_ns);
++      /* lets ignore the LSB part now, MTU supports 32bit counter regi only */
++      mtu_load_counter(mtu->timer, mtu_interval_ns);
++
++      /* XXX: if BG-load-register is passed we have to calculate the
++       * mtu_bg_interval_ns load value and then load it. */
++      if (mtu->bg_interval.tv64 == mtu->interval.tv64)        /* right now, this much is supported */
++              mtu_bg_load_counter(mtu->timer, mtu_interval_ns);
++
++      /* finally enable and start the timer */
++      mtu_enable_timer(mtu->timer);
++#else
++      printk(KERN_WARNING "MTU:Functionality is not implemented!\n");
 +#endif
 +
-+#define NMDK_DEBUG    EPIO_DEBUG      /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  EPIO_NAME     /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
-+ 
-+static void nomadik_epio_plat_init(void)
++      return 0;
++}
++
++EXPORT_SYMBOL(mtu_register_timer);
++
++int mtu_unregister_timer(struct mtu_struct *mtu)
 +{
-+      nmdk_dbg_ftrace();
-+      /* Initializing CPLD registers for initial values */
-+      nomadik_epio_write_cob_ctl(0x0030);     /* reset value */
-+      nomadik_epio_write_keypad(0xff00);      /* COL7:0 set to high Z */
-+      nomadik_epio_write_msp_conf(0x794);     /* reset value */
-+      nomadik_epio_write_uart_conf(0x0694);   /* UART1 enabled for rs232 port*/
-+      nomadik_epio_write_ssp_conf(0x0124);    /* reset value */
-+      nomadik_epio_write_aux_gpo1(0x2880);    /* reset value */
-+      nomadik_epio_write_aux_gpo2(0x018a);    /* reset value */
-+#ifdef CONFIG_SMC91X
-+      nomadik_smc91x_irq_init();
-+#endif
++      unsigned long icr_clear = 0, imsc;
++      unsigned long flags;
++      icr_clear |=
++          1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1));
++
++      spin_lock(&mtu_inuse_lock);
++
++      /* check if the caller has right to unregister this timer */
++      if (mtu->mtu_irq != mtu_irqs[mtu->timer]) {
++            unregister_failed:
++              spin_unlock(&mtu_inuse_lock);
++              return -EINVAL;
++      }
++
++      if ((mtu_inuse & ((unsigned char)0x1 << (mtu->timer - 1))) == 0) {
++              /* if the timer unit was not registered successfully */
++              goto unregister_failed;
++      } else
++              /* clear the inuse bit */
++              mtu_inuse &= ~((unsigned char)0x1 << (mtu->timer - 1));
++      spin_unlock(&mtu_inuse_lock);
++
++      if (mtu->timer > 4)
++              spin_lock_irqsave(&mtu1_spinlock, flags);
++      else
++              spin_lock_irqsave(&mtu0_spinlock, flags);
++
++      mtu_disable_timer(mtu->timer);
++
++      /* disable the interrupt */
++      imsc = mtu_intr_reg_readl(mtu->timer, TxIMSC);
++      imsc &=
++          ~(1UL << (mtu->timer > 4 ? (mtu->timer - 5) : (mtu->timer - 1)));
++      mtu_intr_reg_writel(mtu->timer, imsc, TxIMSC);
++
++      /* clear the interrupt of this timer */
++      mtu_intr_reg_writel(mtu->timer, icr_clear, TxICR);
++
++      mtu_load_counter(mtu->timer, 0);
++
++      spin_lock(&mtu_inuse_lock);
++      mtu_irqs[mtu->timer] = NULL;
++      spin_unlock(&mtu_inuse_lock);
++
++      if (mtu->timer > 4)
++              spin_unlock_irqrestore(&mtu1_spinlock, flags);
++      else
++              spin_unlock_irqrestore(&mtu0_spinlock, flags);
++
++      return 0;
 +}
 +
-+static struct platform_device epio_device = {
-+      .name = "NOMADIK-EPIO",
-+      .id = 0,
-+      .dev = {
-+              .platform_data = nomadik_epio_plat_init,
-+              },
-+};
-+#undef NMDK_DEBUG
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+#endif /*CONFIG_CPLD_I2C*/
++EXPORT_SYMBOL(mtu_unregister_timer);
 +
-+static struct platform_device *nmdk_platform_devices[] __initdata = {
-+      &fsmc_device,
-+#ifdef CONFIG_CPLD_I2C 
-+      &epio_device,
-+#endif
-+#ifdef CONFIG_KEYPAD_NOMADIK
-+      &keypad_device,
-+#endif
-+#ifdef CONFIG_SMC91X
-+      &smc91x_device,
-+#endif
-+#ifdef CONFIG_TOUCHSCREEN_NOMADIK
-+      &touchp_device,
-+#endif
-+#ifdef CONFIG_MTD
-+      &nomadik_nand_flash,
-+      &nomadik_nor_flash,
++static struct {
++      u32 tmr_value;
++      u32 tmr_control;
++      u32 tmr_bgload;
++}mtu_tmr_context[8];
++
++static u32 nomadik_mtu0_imsc[2];
++
++int nomadik_mtu_suspend(void)
++{
++      /* Use spin lock */
++      int inuse = mtu_inuse & ~1;
++      int tmr_no;
++
++      nomadik_mtu0_imsc[0] = mtu_intr_reg_readl(MTU0_T0, TxIMSC);
++      nomadik_mtu0_imsc[1] = mtu_intr_reg_readl(MTU1_T0, TxIMSC);
++      while(inuse)
++      {
++              tmr_no = ffs(inuse);
++              mtu_tmr_context[tmr_no-1].tmr_value = mtu_readl(tmr_no, TyVAL);
++              mtu_tmr_context[tmr_no-1].tmr_control = mtu_readl(tmr_no, TyCR);
++              mtu_tmr_context[tmr_no-1].tmr_bgload = mtu_readl(tmr_no, TyBGLR);
++              inuse = inuse & ~(1 << ( tmr_no - 1 ));
++      }
++      return 0;
++}
++
++int nomadik_mtu_resume(void)
++{
++      /* Use spin lock */
++      int inuse = mtu_inuse & ~1;
++      int tmr_no;
++
++      mtu_intr_reg_writel(MTU0_T0, nomadik_mtu0_imsc[0], TxIMSC);
++      mtu_intr_reg_writel(MTU1_T0, nomadik_mtu0_imsc[1], TxIMSC);
++      while(inuse)
++      {
++              tmr_no = ffs(inuse);
++              mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_value, TyLR);
++              mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_control, TyCR);
++              mtu_writel(tmr_no, mtu_tmr_context[tmr_no - 1].tmr_bgload, TyBGLR);
++              inuse = inuse & ~(1 << ( tmr_no - 1 ));
++      }
++      return 0;
++}
++
++
++int __init nomadik_mtu_init(void)
++{
++      unsigned long all_icr_clear = 0xf;
++      volatile unsigned long *psrc_cr =
++          (volatile unsigned long *)IO_ADDRESS(NOMADIK_SRC_BASE);
++      unsigned long src_cr;
++      src_cr = *psrc_cr;
++      src_cr |= 0x2AAA8000;
++      *psrc_cr = src_cr;
++
++      spin_lock_init(&mtu0_spinlock);
++      spin_lock_init(&mtu1_spinlock);
++
++      mtu_irqs[0] = NULL;
++      /* clear the interrupts */
++
++      mtu_intr_reg_writel(MTU1_T0, all_icr_clear, TxICR);
++
++      /*
++       * setup an interrupt for the Timer units
++       */
++#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
++      /* Cannt use if module! It might screw the system "timer_tick" */
++      mtu_intr_reg_writel(MTU0_T0, all_icr_clear, TxICR);
++
++      setup_irq(IRQ_MTU0, &mtu0_timer_irq);
++      printk(KERN_INFO "MTU: Registered MTU0 timer unit.\n");
++
++      setup_irq(IRQ_MTU1, &mtu1_timer_irq);
++      printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
++#else
++      request_irq(IRQ_MTU1, mtu1_timer_irq.handler, mtu1_timer_irq.flags,
++                  mtu1_timer_irq.name, NULL);
++      printk(KERN_INFO "MTU: Registered MTU1 timer unit.\n");
 +#endif
-+};
 +
-+void add_nmdk_platform_devices(void)
++      return 0;
++}
++
++void __exit nomadik_mtu_exit(void)
 +{
-+      platform_add_devices(nmdk_platform_devices,
-+                           ARRAY_SIZE(nmdk_platform_devices));
++      mtu_timer_t timer;
++      /* disabling the registered timers */
++      while (mtu_inuse) {
++              timer = ffs(mtu_inuse);
++              mtu_disable_timer(timer);
++              mtu_inuse &= ~((unsigned char)0x1 << timer);
++      }
++
++      free_irq(IRQ_MTU1, NULL);
++
++#if defined(CONFIG_MTU0) && defined(CONFIG_NOMADIK_MTU_SYSTEM_TICK)
++      free_irq(IRQ_MTU0, NULL);
++#endif
 +}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c  2008-09-17 13:23:32.000000000 +0530
-@@ -0,0 +1,1001 @@
++
++#ifndef CONFIG_MTU0
++module_init(nomadik_mtu_init);
++#endif
++module_exit(nomadik_mtu_exit);
++
++MODULE_LICENSE("Proprietary");
++MODULE_DESCRIPTION("Nomadik MTU Driver");
++MODULE_AUTHOR("ST Microelectronics");
++
++/* vim: set ts=4 noet sw=4 */
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_a1_Kconfig
+@@ -0,0 +1,28 @@
++if NOMADIK_NDK10_CUT_A1
++
++#target name configuration
++config NOMADIK_TARGET
++      string
++      default NDK10_Cut_A1
++
++# nomadik soc chip name configuration for this target
++config NOMADIK_SOC
++      string
++      default stn8810
++
++# nomadik platform name configuration for this target
++config NOMADIK_PLATFORM
++      string
++      default ndk10
++
++# EXTRA_CFLAGS configuration for this target
++config NOMADIK_TARGET_EXTRA_CFLAGS
++      string
++      default "-D__RELEASE -D__STN_8810=10 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++
++# Basic platform type configuration for this target (optional will be removed latter)
++config NOMADIK_NDK10
++      bool
++      default y
++
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b06_Kconfig
+@@ -0,0 +1,35 @@
++if NOMADIK_NDK10_CUT_B06
++
++comment "Nomadik chip used STRn8810B2S12HPB cut B (chip secure)"
++
++#target name configuration for this target
++config NOMADIK_TARGET
++      string
++      default NDK10_Cut_B06
++
++# nomadik soc chip name configuration for this target
++config NOMADIK_SOC
++      string
++      default stn8810
++
++# nomadik soc chip cut name configuration for this targe only
++config NOMADIK_STRn8810B2S12HPB
++      bool
++      default y
++
++# nomadik platform name configuration for this target
++config NOMADIK_PLATFORM
++      string
++      default ndk10
++
++# EXTRA_CFLAGS configuration for this target
++config NOMADIK_TARGET_EXTRA_CFLAGS
++      string
++      default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++
++# Basic platform type configuration for this target
++config NOMADIK_NDK10
++      bool
++      default y
++
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_cut_b0_Kconfig
+@@ -0,0 +1,35 @@
++if NOMADIK_NDK10_CUT_B0
++
++comment "Nomadik chip used STRn8810B2S12 cut B"
++
++#target name configuration for this target
++config NOMADIK_TARGET
++      string
++      default NDK10_Cut_B0
++
++# nomadik soc chip name configuration for this target
++config NOMADIK_SOC
++      string
++      default stn8810
++
++# nomadik soc chip cut name configuration for this targe only
++config NOMADIK_STRn8810B2S12
++      bool
++      default y
++
++# nomadik platform name configuration for this target
++config NOMADIK_PLATFORM
++      string
++      default ndk10
++
++# EXTRA_CFLAGS configuration for this target
++config NOMADIK_TARGET_EXTRA_CFLAGS
++      string
++      default "-D__RELEASE -D__STN_8810=20 -D__PLATFORM_MEVKFULL -D__UART_ELEMENTARY"
++
++# Basic platform type configuration for this target
++config NOMADIK_NDK10
++      bool
++      default y
++
++endif
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk10_devices.c
+@@ -0,0 +1,1225 @@
 +/*
-+ *  linux/arch/arm/mach-nomadik/ndk15_devices.c
-+ *
++ *  linux/arch/arm/mach-nomadik/ndk10_devices.c
 + *
-+ *  Copyright (C) STMicroelectronics
++ *  Copyright (C) 2000-2003 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 version 2, as
-+ * published by the Free Software Foundation.
++ * 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.
 + *
-+ *  NDK15B0x board specifc driver defination
++ * 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/types.h>
 +#include <linux/kernel.h>
@@ -16303,6 +16344,166 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +#endif
 +#include <asm/arch/debug.h>
 +
++/*
++ * epio
++ */
++#define EPIO_NAME             "EPIO"
++
++#ifndef EPIO_DEBUG
++#define EPIO_DEBUG 0
++#endif
++
++#define NMDK_DEBUG    EPIO_DEBUG      /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  EPIO_NAME     /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++static spinlock_t epio_cob_ctl_read = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_cob_ctl_write = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_kp_read = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_kp_write = SPIN_LOCK_UNLOCKED;
++
++static unsigned long epio_lgcl_addr_cob_ident_reg;
++static unsigned long epio_lgcl_addr_cob_ctl_reg;
++static unsigned long epio_lgcl_addr_kp_reg;
++static unsigned long epio_lgcl_addr_exp_ctrl_reg;
++static spinlock_t epio_exp_ctrl_read = SPIN_LOCK_UNLOCKED;
++static spinlock_t epio_exp_ctrl_write = SPIN_LOCK_UNLOCKED;
++
++/*
++ * nomadik_epio_read_cob_ident - reads COB_IDENT register of CPLD
++ *
++ * Reads the core bord version and CPLD version information stored in
++ * COB_IDENT register of CPLD on NDK10
++ */
++static short nomadik_epio_read_cob_ident(void)
++{
++      return ((short)
++              *((volatile unsigned short *)epio_lgcl_addr_cob_ident_reg));
++}
++
++/**
++ * nomadik_epio_read_cob_ctl - reads COB_CTL register of CPLD
++ *
++ * Reads the present value of the core-board-configuration register of CPLD
++ * on NDK10 board
++ */
++short nomadik_epio_read_cob_ctl(void)
++{
++      short i;
++
++      spin_lock(&epio_cob_ctl_read);
++      i = *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg);
++      spin_unlock(&epio_cob_ctl_read);
++      return (i);
++}
++
++/**
++ * nomadik_epio_write_cob_ctl - writes COB_CTL register of CPLD
++ * @expctrlval: value to be written
++ *
++ * Write the provided 16bit value into the core-board-configuration register
++ * of CPLD on NDK10 board
++ */
++void nomadik_epio_write_cob_ctl(unsigned short expctrlval)
++{
++      spin_lock(&epio_cob_ctl_write);
++      *((volatile unsigned short *)epio_lgcl_addr_cob_ctl_reg) = expctrlval;
++      spin_unlock(&epio_cob_ctl_write);
++}
++
++/**
++ * nomadik_epio_read_keypad - reads KEYPAD register of CPLD
++ *
++ * Reads the present value of the keypad assignment register of CPLD on NDK10
++ */
++short nomadik_epio_read_keypad(void)
++{
++      short i;
++
++      spin_lock(&epio_kp_read);
++      i = (0x07FF & *((volatile unsigned short *)epio_lgcl_addr_kp_reg));
++      spin_unlock(&epio_kp_read);
++      return (i);
++}
++
++/**
++ * nomadik_epio_write_keypad - writes KEYPAD register of CPLD
++ * @keypadval: value to be written
++ *
++ * Writes the provided value to the keypad assignment reg of CPLD on NDK10
++ */
++void nomadik_epio_write_keypad(unsigned short kpdval)
++{
++      unsigned short i;
++
++      spin_lock(&epio_kp_write);
++      i = *((volatile unsigned short *)epio_lgcl_addr_kp_reg);
++      i &= 0xF800;
++      i |= kpdval & 0x07ff;
++      *((volatile unsigned short *)epio_lgcl_addr_kp_reg) = i;
++      spin_unlock(&epio_kp_write);
++}
++
++/**
++ * nomadik_epio_read_exp_ctrl - reads exp ctrl register of CPLD
++ *
++ * Reads the 16bit value of the expansion-board-control register of CPLD on NDK10
++ */
++short nomadik_epio_read_exp_ctrl(void)
++{
++      short i = 0;
++      spin_lock(&epio_exp_ctrl_read);
++      i = *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg);
++      spin_unlock(&epio_exp_ctrl_read);
++      return (i);
++}
++
++/**
++ * nomadik_epio_write_exp_ctrl - writes exp ctrl register of CPLD
++ * @expctrlval: value to be written
++ *
++ * Writes the provided 16bit value into the expansion-board-control register
++ * of CPLD on NDK10
++ */
++void nomadik_epio_write_exp_ctrl(unsigned short expctrlval)
++{
++      spin_lock(&epio_exp_ctrl_write);
++      *((volatile unsigned short *)epio_lgcl_addr_exp_ctrl_reg) = expctrlval;
++      spin_unlock(&epio_exp_ctrl_write);
++}
++
++/**
++ * nomadik_epio_init - epio module init call.
++ */
++static int __init nomadik_epio_init(void)
++{
++      unsigned short i;
++
++      nmdk_dbg_ftrace();
++      epio_lgcl_addr_cob_ident_reg =
++          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x000, (unsigned long)2);
++      epio_lgcl_addr_cob_ctl_reg =
++          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x002, (unsigned long)2);
++      epio_lgcl_addr_kp_reg =
++          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x004, (unsigned long)2);
++      epio_lgcl_addr_exp_ctrl_reg =
++          (unsigned long)ioremap(NOMADIK_CPLD_BASE + 0x006, (unsigned long)2);
++
++      i = nomadik_epio_read_cob_ident();
++      nmdk_info("Core Board Revision %d.%d,  CPLD Code Revision %d.%d",
++                (i & COB_REV_BITS) >> COB_REV_BITS_POS,
++                (i & COB_REV_SUBBITS) >> COB_REV_SUBBITS_POS,
++                (i & CPLD_REV_BITS) >> CPLD_REV_BITS_POS,
++                (i & CPLD_REV_SUBBITS));
++      return 0;
++}
++#undef NMDK_DEBUG     /*epio*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++/*
++ * board init
++ */
 +#define BOARD_NAME            CONFIG_NOMADIK_PLATFORM
 +#ifndef BOARD_DEBUG
 +#define BOARD_DEBUG 0
@@ -16312,24 +16513,116 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
 +#define NMDK_DBG      KERN_ERR        /* message level */
 +
++void __init nomadik_pepperpot_board_init(void)
++{
++      int err;
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot |
++                                 CAM_RSTnot);
++      err = 0;
++      while (err < 0xffffff)
++              err++;
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000);
++      err = 0;
++      while (err < 0xffffff)
++              err++;
++}
++
++void __init nomadik_platform_board_init(void)
++{
++      unsigned char __iomem *gpio0_base;
++      unsigned char __iomem *gpio1_base;
++      unsigned char __iomem *cpld_base;
++      unsigned char __iomem *rgpo1_base;
++      unsigned char __iomem *pmu_base;
++      unsigned char __iomem *base;
++
++      gpio0_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO0_BASE);
++      gpio1_base = (unsigned char *)IO_ADDRESS(NOMADIK_GPIO1_BASE);
++
++      rgpo1_base = (unsigned char *)IO_ADDRESS(NOMADIK_CPLD_RGPO1_BASE);
++      cpld_base = ioremap(NOMADIK_CPLD_BASE, SZ_4K);
++      base = ioremap(0x36400000, SZ_4K);
++
++      /*
++       * Set Display control LCD*
++       * Set bit 26 of pmu->ctrl register to 0. CLCD/DIF selection
++       */
++      pmu_base = (unsigned char *)IO_ADDRESS(NOMADIK_PMU_BASE);
++      writel((0xFBBFFFFF & readl(pmu_base)), pmu_base);
++
++      /*
++       * Enabling alt func A for gpio0-gpio7 :UART0
++       */
++      writel(0xff, gpio0_base + 0x20);
++
++      /*
++       * Enabling alt func A for gpio51,52,56,57 :UART1
++       */
++      writel(0x3180000, gpio1_base + 0x20);
++
++      /*
++       * Enabling alt func B for gpio32-39
++       */
++      writel(0xff, gpio1_base + 0x24);
++
++      /*
++       * Change in cpld register on cob10
++       * UART1 trasnceiver enable, uart0 enable
++       */
++      writew((0x218 | (readw(cpld_base + 02) & ~(0x238))), (cpld_base + 02));
++
++      /*
++       *  CPLD setting for pepperport camera poweron
++       *
++       */
++      writew((0xc00 | readw(cpld_base + 02)), (cpld_base + 02));
++
++      /*
++       * Setting as copied from CMM file (backlite disabled)
++       */
++      writew(0xc000, base);
++      writew(0x900f, rgpo1_base);
++      writew(0x53ff, cpld_base + 6);
++      writew(0xdfff, rgpo1_base);
++      writew(0x8001, rgpo1_base);
++
++      writew(readw(cpld_base + 0x6) | 0x1000, cpld_base + 6);
++
++      /*
++       * Change in cpld uib register
++       * Enable uart0
++       */
++      writew((0x8000 | readw(rgpo1_base)), rgpo1_base);
++
++      iounmap(cpld_base);
++      iounmap(base);
++      printk("%s done\n", __FUNCTION__);
++}
++
 +/**
 + * nomadik_clcd_board_enable - enables board specific clcd prameters
 + *
-+ * Settings to enable backlight and pannel voltage regulator for NDK15
++ * Settings to enable backlight and pannel voltage regulator for NDK10
++ * bit 10 to set backlight on, bit 11 to set LCD power regulator on
 + */
 +void nomadik_clcd_enable(void *fbp)
 +{
-+      /* not implimented for this board */
++#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT)
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x0c00);
++#endif
 +}
 +
 +/**
 + * nomadik_clcd_board_disable - disables board specific clcd prameters
 + *
 + * Settings to disable backlight and pannel voltage regulator for NDK10
++ * bit 10 to reset backlight off, bit 11 to reset LCD power regulator off
 + */
 +void nomadik_clcd_disable(void *fbp)
 +{
-+      /* not implimented for this board */
++#if defined (CONFIG_FB_NOMADIK_QVGA_PORTRAIT)
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() & (~0x0c00));
++#endif
 +}
 +
 +/*
@@ -16341,7 +16634,9 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      gpio_config mmc_pin;
 +      char x = val_volt;
 +
-+      mmc_pin.dev_name = dev->dev.bus_id;
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() |
++                                  MASK_MMC_EPIO);
++      mmc_pin.dev_name = "mmc";
 +      mmc_pin.mode = GPIO_MODE_SOFTWARE;
 +      mmc_pin.direction = GPIO_DIR_OUTPUT;
 +      mmc_pin.trig = GPIO_TRIG_DISABLE;
@@ -16350,10 +16645,10 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
 +      if (ret) {
 +              nmdk_error("Error in setting GPIO_PIN_75");
-+              goto mmcconf_exit;
++              goto exit_last;
 +      }
 +      /* this enables power path from toureg to mmc */
-+      ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id);
++      ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, "mmc");
 +      if (ret) {
 +              nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
 +              goto deallocate_pin_75;
@@ -16365,7 +16660,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +              goto deallocate_pin_75;
 +      }
 +
-+      ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++      ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, "mmc");
 +      if (ret) {
 +              nmdk_error("Error in gpio Altfunction enable");
 +              goto deallocate_pin_75;
@@ -16373,18 +16668,64 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      return ret;
 +
 +      deallocate_pin_75:
-+      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
-+      mmcconf_exit:
++      nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc");
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
++                                  ~MASK_MMC_EPIO);
++      exit_last:
 +      return ret;
 +
 +}
 +
 +void nomadik_mmc_restore_default(struct amba_device *dev)
 +{
-+      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
-+      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
++      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, "mmc");
++      nomadik_gpio_resetpinconfig(GPIO_PIN_75, "mmc");
++
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
++                                  ~MASK_MMC_EPIO);
++}
++
++/*
++ * nomadik_fsmc_init - fsmc initialization on system start
++ */
++static __init void nomadik_fsmc_init(void)
++{
++      unsigned char __iomem *fsmc_base;
++
++      nmdk_dbg_ftrace();
++      /*Following Settings done for NAND flash protect off */
++      fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
++
++      /* for NOR accesss */
++      /* Initialize the fsmc bank 0 */
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
++      /* Initialize the fsmc bank 1 */
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db;
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702;
++
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
++      /* Above Settings done for NAND flash protect off */
++}
++
++int nomadik_pepperpot_init(void)
++{
++      int err;
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | CAM_SHDNnot |
++                                 CAM_RSTnot);
++      err = 0;
++      while (err < 0xffffff)
++              err++;
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() | 0x1000);
++      err = 0;
++      while (err < 0xffffff)
++              err++;
++
++      return 0;
 +}
 +
++EXPORT_SYMBOL(nomadik_pepperpot_init);
++
 +#ifdef CONFIG_MTD
 +
 +static struct resource nandflash_resources[] = {
@@ -16411,15 +16752,17 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +#define NAND_STM_LP_OPTIONS \
 +              (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
 +
-+static int nomadik_nandflash_exit(void)
++int nomadik_nandflash_exit(void)
 +{
++      if(nomadik_gpio_resetpinconfig(NAND_GPIO, "nand"))
++              return -1;
 +      return 0;
-+
 +}
-+static int nomadik_nandflash_init(void)
++
++void nomadik_nandflash_init(void)
 +{
-+      /* 
-+       * FSMC initialization 
++      /*
++       * FSMC initialization
 +       * 0x0000001e => PCR0
 +       * 0x000d0a00 => PMEM0
 +       * 0x00100a00 => PATT0
@@ -16427,29 +16770,17 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +
 +/*    pcr0.address_low        = 0;*/
 +      gpio_config nmdknand_pin_config;
++      nmdknand_pin_config.dev_name = "nand";
 +      nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
 +      nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
 +      nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
 +      nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      nmdknand_pin_config.dev_name = "nand";
-+      /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */
 +      if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config))
 +              return -1;
-+      if(nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name))
++      if(nomadik_gpio_writepin(NAND_GPIO, 1, "nand"))
 +              return -1;
 +
 +
-+      /*Following Settings done for NAND flash protect off */
-+      /* this was moved from board init to here */
-+      /* This pin Conflicts with touchpanel TOUCHP_CS0*/
-+      if(nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config))
-+              return -1;
-+      if(nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name))
-+              return -1;
-+      if(nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name ))
-+              return -1;
-+      
-+
 +      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
 +          DEFAULT_PCR0_VALUE;
 +      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
@@ -16478,8 +16809,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
 +};
 +
-+int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
-+                          u_char * ecc)
++int nmdknand_compute_ecc512(struct mtd_info *mtd, unsigned char *data,
++                          unsigned char ecc[3])
 +{
 +      unsigned int sumCol = 0;
 +      unsigned int datum, temp;
@@ -16565,25 +16896,17 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +}
 +
 +static struct nand_ecclayout nand_oob = {
-+      .eccbytes = 12,
-+      .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
++      .eccbytes = 6,
++      .eccpos = {2, 3, 4, 5, 6, 7},
 +      .oobavail = MTD_NANDECC_AUTOPLACE,
-+      .oobfree = {            
++      .oobfree = {
 +              { .offset = 8,
 +               .length = 8,
 +              },
-+              { .offset = 24,
-+               .length = 8,
-+              },
-+              { .offset = 40,
-+               .length = 8,
-+              },
-+              { .offset = 56,
-+               .length = 8,
-+              },
 +              },
 +};
 +
++#ifdef CONFIG_NOMADIK_NDK10_CUT_B06
 +static struct mtd_partition nandflash_main_partitions[] = {
 +
 +      {.name = "X-Loader(NAND)",
@@ -16605,6 +16928,29 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +       .offset = 220 * 0x000020000,
 +       .size = 800 * 0x000020000},    /*100 Mbytes */
 +};
++#else
++static const struct mtd_partition nandflash_main_partitions[] = {
++      {.name = "X-Loader(NAND)",
++       .offset = 0,
++       .size = 4 * 0x00004000},
++      {.name = "MemInit(NAND)",
++       .offset = 4 * 0x00004000,
++       .size = 1 * 0x00004000},
++      {.name = "BootLoader(NAND)",
++       .offset = 5 * 0x00004000,
++       .size = 16 * 0x0004000},
++      {.name = "Kernel zImage(NAND)",
++       .offset = 21 * 0x00004000,
++       .size = 3 * 0x00100000},
++      {.name = "Root Filesystem(NAND)",
++       .offset = 0x354000,
++       .size = 0x0a00000},
++      {.name = "User Filesystem(NAND)",
++       .offset = 0xd54000,
++       .size = 0x12aC000},
++};
++
++#endif
 +
 +static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 +
@@ -16641,8 +16987,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      .num_parts = ARRAY_SIZE(nandflash_main_partitions),
 +      .lp_options = NAND_STM_LP_OPTIONS,
 +      .eccsize = 512,
-+      .eccsteps = 4,
-+      .badblockpos = 5,
++      .eccsteps = 1,
++      .badblockpos = 1,
 +      .init = nomadik_nandflash_init,
 +      .exit = nomadik_nandflash_exit,
 +      .nand_oob = &nand_oob,
@@ -16665,7 +17011,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      {.name = "BootLoader(NOR)",
 +       .size = 0x00040000,    /*256K */
 +       .offset = 0,},
-+      {.name = "zImage+initrd(NOR)",
++      {.name = "Kernel zImage(NOR)",
 +       .size = 0x001C0000,    /*1.75MB */
 +       .offset = MTDPART_OFS_APPEND,},
 +      {.name = "Root Filesystem(NOR)",
@@ -16682,7 +17028,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +static struct flash_platform_data nomadik_nor_flash_data = {
 +      .name = "nomadik_nor",
 +      .map_name = "cfi_probe",
-+      /*.width                = NMDK_FLASH_BUSWIDTH, */
++      //.width                = NMDK_FLASH_BUSWIDTH,
 +      .parts = nmdkflash_main_partitions,
 +      .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
 +};
@@ -16691,6 +17037,12 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      [0] = {
 +             .name = "norflash-regs",
 +             .start = NMDK_FLASH_BASE,
++             .end = (NMDK_FLASH_BASE + SZ_16M - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [1] = {
++             .name = "norflash-regs",
++             .start = NMDK_FLASH_BASE + SZ_16M,
 +             .end = (NMDK_FLASH_BASE + SZ_32M - 1),
 +             .flags = IORESOURCE_MEM,
 +             },
@@ -16708,8 +17060,29 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +
 +#endif
 +
++static void nomadik_smc91x_irq_init(void)
++{
++      int err;
++      gpio_config smx91x_clkpin;
++
++      smx91x_clkpin.dev_name = "smc91x";
++      smx91x_clkpin.mode = GPIO_ALTF_A;
++      err = nomadik_gpio_setpinconfig(GPIO_PIN_55, &smx91x_clkpin);
++      if (err) {
++              nmdk_error("Error in configuring pin%d for clkout", GPIO_PIN_55);
++      }
++
++      /* disable NOR flash write protection */
++      /* CHECK if this clashes with NOR and NAND settings of FSMC */
++      *((volatile unsigned short *)(NOMADIK_CPLD_RGPO1_VA)) |=
++          ETH_DAUGHTER_CARD_RESET;
++
++      set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING);
++}
++
 +static struct resource smc91x_resources[] = {
 +      [0] = {
++
 +             .name = "smc91x-regs",
 +             .start = (NOMADIK_ETH0_BASE + 0x300),
 +             .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
@@ -16745,84 +17118,38 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +
 +/**
 + * nomadik_tp_ssp_board_init - board specific ssp data path setup
-+ * @p_adsContext: device data structure pointer
 + *
 + * This routine initializes the SSP for touchpanel operation
-+ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
++ * SSP is interfaced with ADS7843 through CPLD hence respective
++ * interface need to be enabled for NDK10
++ * make bit COB_CTL(MSP2_SSP_SWAP) low to connect STn8810 SSP to EXP SSP
++ * make bit COB_CTL(SSP_EN) high to enable SSP on STn8810 side
 + */
 +int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
 +{
 +      nmdk_dbg_ftrace();
-+      nomadik_epio_write_ssp_conf(EXP_SSP);
++      nomadik_epio_write_cob_ctl((nomadik_epio_read_cob_ctl() &
++                                  (~MSP2_SSP_SWAP)) | SSP_EN);
 +      return (0);
 +}
 +
 +/**
 + * nomadik_tp_gpio_board_init - board specific gpio initialization
-+ * @p_adsContext: device data structure pointer
++ * @mode: mode of operation (polling[0] or interrupt[<0]
 + *
 + * This routine initializes the GPIO for touchpanel operation
 + * RETURN: GPIO nmdk_error code
-+ * SSP is interfaced with ADS7843 through CPLD hence respective
-+ * interface need to be enabled for NDK10
-+ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
-+ * chip select, this bit allows the selection between the two
-+ * peripherals. setting this bit Touch screen selected
 + */
 +gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
 +{
 +      gpio_error status = GPIO_OK;
-+      gpio_config config_cspin;
-+      gpio_data touchp_cs1;
 +      nmdk_dbg_ftrace();
 +
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
-+
-+      /* Set SPICSn_TCHSCR pin configuration */
-+      config_cspin.mode = GPIO_MODE_SOFTWARE;
-+      config_cspin.direction = GPIO_DIR_OUTPUT;
-+      config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
-+      config_cspin.dev_name = "Touchp";
-+      /*
-+       * TOUCHP_CS1 need to be high always to select ad7843 cs properly
-+       * this pin will be set high by nand_init(NAND_PROT_OFF)
-+       * if this pin is not high and set it high 
-+       */
-+      status |= nomadik_gpio_readpin(TOUCHP_CS1, &touchp_cs1);
-+      if (!touchp_cs1) { 
-+              status |= nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
-+              status |= nomadik_gpio_writepin(TOUCHP_CS1, 1, config_cspin.dev_name);
-+              status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, config_cspin.dev_name);
-+      }
-+      status |= nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
-+      if (status) {
-+              nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
-+                         TOUCHP_CS0, status);
-+              return (status);
-+      }
 +      /* Set PENIRQ pin configuration */
 +      set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING);
-+      return status;
-+}
-+
-+/**
-+ * nomadik_tp_gpio_board_exit - board specific gpio exit
-+ * @p_adsContext: device data structure pointer
-+ *
-+ * This routine performs revers action of init
-+ */
-+gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
-+{
-+      gpio_error status = GPIO_OK;
++      /* Enable GPIOs through CPLD for access/interrupts on ndk10 */
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | GPIO_EN);
 +
-+      nmdk_dbg_ftrace();
-+      /* Enable CPLD logic for access/interrupts on ndk15 in case of int mode */
-+      if (!p_adsContext->mode) {
-+              nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
-+                                      (u16)~TSIT_MSK);
-+      }
-+      status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
-+      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
 +      return status;
 +}
 +
@@ -16832,10 +17159,10 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
 +{
 +      gpio_data pen_down;
++
 +      nmdk_dbg_ftrace();
-+      pen_down = nomadik_epio_read_aux_gpi1();
-+      pen_down &= TCHSCR_PENIRQ;
-+      nmdk_dbg2("pen_down = 0x%d", pen_down);
++      nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
++      nmdk_dbg2("%s(): pen_down = 0x%d", __FUNCTION__, pen_down);
 +      return ((t_bool) pen_down);
 +}
 +
@@ -16845,7 +17172,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
 +{
 +      nmdk_dbg_ftrace();
-+      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | TSIT_MSK);
++//    enable_irq(p_adsContext->irq);
 +}
 +
 +/**
@@ -16854,42 +17181,42 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
 +{
 +      nmdk_dbg_ftrace();
-+      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
-+                                 (unsigned short)(~TSIT_MSK));
++//    disable_irq(p_adsContext->irq);
 +}
 +
 +/**
 + * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
 + *
-+ * sets GPIOS to to provid inputs to CPLD to disable chip select
++ * set TOUCHP_SSP_CS pin high to disable SSP chip select for ads7843
 + */
 +void nomadik_tp_spi_cs_disable(void)
 +{
 +      nmdk_dbg_ftrace();
-+      nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() |
++                                  TOUCHP_SSP_CS);
 +}
 +
 +/**
 + * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
 + *
-+ * sets GPIOS to to provid inputs to CPLD to enable chip select
++ * set TOUCHP_SSP_CS pin low to enable SSP chip select for ads7843
 + */
 +void nomadik_tp_spi_cs_enable(void)
 +{
 +      nmdk_dbg_ftrace();
-+      nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
++      nomadik_epio_write_exp_ctrl(nomadik_epio_read_exp_ctrl() &
++                                  (~TOUCHP_SSP_CS));
 +}
 +
 +static struct touchp_device touchp_board = {
 +      .ssp_init = nomadik_tp_ssp_board_init,
 +      .gpio_init = nomadik_tp_gpio_board_init,
-+      .gpio_exit = nomadik_tp_gpio_board_exit,
 +      .pdown = nomadik_tp_pen_down,
 +      .pirq_en = nomadik_tp_pen_down_irq_enable,
 +      .pirq_dis = nomadik_tp_pen_down_irq_disable,
 +      .cs_en = nomadik_tp_spi_cs_disable,
 +      .cs_dis = nomadik_tp_spi_cs_enable,
-+      .samples = 20, /*samples per second*/
++      .samples = 100, /*samples per second*/
 +      .pollsamples = 10, /*polling per second*/
 +};
 +
@@ -16911,7 +17238,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      .resource = touchp_resources,
 +};
 +
++/*
++ ***********************************************************************
++ */
 +#define KEYPAD_NAME           "KEYPAD"
++
 +#ifndef KEYPAD_DEBUG
 +#define KEYPAD_DEBUG 0
 +#endif
@@ -16924,39 +17255,30 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +#define NMDK_DBG      KERN_ERR        /* message level */
 +
 +/*key scan constants*/
-+#define KSCAN_ALLROWS   0x00FF
-+#define KSCAN_ALLCOLS   0xFF00
++#define KSCAN_ALLROWS   0x001F
++#define KSCAN_ALLCOLS   0x07E0
 +#define KSCAN_ROW0      0x0001
 +#define KSCAN_ROW1      0x0002
 +#define KSCAN_ROW2      0x0004
 +#define KSCAN_ROW3      0x0008
 +#define KSCAN_ROW4      0x0010
-+#define KSCAN_ROW5      0x0020
-+#define KSCAN_ROW6      0x0040
-+#define KSCAN_ROW7      0x0080
-+#define KSCAN_COL0      0x0100
-+#define KSCAN_COL1      0x0200
-+#define KSCAN_COL2      0x0400
-+#define KSCAN_COL3      0x0800
-+#define KSCAN_COL4      0x1000
-+#define KSCAN_COL5      0x2000
-+#define KSCAN_COL6      0x4000
-+#define KSCAN_COL7      0x8000
++#define KSCAN_COL0      0x0020
++#define KSCAN_COL1      0x0040
++#define KSCAN_COL2      0x0080
++#define KSCAN_COL3      0x0100
++#define KSCAN_COL4      0x0200
++#define KSCAN_AUX     0x0400  /* this line needs to set to get keypad intr */
 +
 +unsigned short const keychkval_set[] = {
 +      (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
 +      (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
 +      (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
 +      (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
-+      (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS
 +};
 +
 +unsigned short const keychkval_read[] = {
-+      KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
-+      KSCAN_ROW6, KSCAN_ROW7,
++      KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4
 +};
 +
 +/**
@@ -16977,8 +17299,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +                      /*keypr detected */
 +                      ghcnt++;
 +              }
++              /* return error if more than one keys are pressed in a row */
 +              if (1 < ghcnt)
-+                      /*return error if more than one keys are pressed in a row */
 +                      return (-1);
 +      }
 +      return (0);
@@ -16995,7 +17317,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      short val;
 +      u8 row, col;
 +      int keyp_cnt = 0;
-+      u8 *p_kcode;
++      u8 *p_kcode;;
 +
 +      nmdk_dbg_ftrace();
 +      for (col = 0; col < MAX_KPCOL; col++) {
@@ -17005,7 +17327,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +              val &= KSCAN_ALLROWS;
 +              if (0 == nomadik_kp_ghostkey_detect(val)) {
 +                      for (row = 0; row < MAX_KPROW; row++) {
-+                              if (0 == (val & keychkval_read[row])) { /*keypr detected */
++                              if (0 == (val & keychkval_read[row])) {
++                                      /*keypr detected */
 +                                      keyp_cnt++;
 +                                      if (kp->key_state[row][col] ==
 +                                          KEYPAD_STATE_DEFAULT) {
@@ -17015,7 +17338,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +                                              kp->key_state[row][col] =
 +                                                  KEYPAD_STATE_PRESSACK;
 +                                      }
-+                              } else {        /*key not pressed detected */
++                              } else {
++                                      /*key not pressed detected */
 +                                      if (kp->key_state[row][col] ==
 +                                          KEYPAD_STATE_PRESSACK) {
 +                                              input_report_key(kp->inp_dev,
@@ -17031,7 +17355,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +                      keyp_cnt += 0x100;      /* to flag ghost keypress detection */
 +      }
 +      /* pull down all rows to detect any keypress */
-+      nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
++      nomadik_epio_write_keypad(KSCAN_ALLROWS);
 +      return (keyp_cnt);
 +}
 +
@@ -17046,26 +17370,43 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 + */
 +int nomadik_kp_init_key_hardware(struct keypad_t *kp)
 +{
++      int err;
++      gpio_data pin;
++
 +      nmdk_dbg_ftrace();
-+      nomadik_epio_write_keypad(KSCAN_ALLCOLS);
-+      if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
++      nomadik_epio_write_keypad(KSCAN_ALLROWS | KSCAN_ALLCOLS);
++      nomadik_epio_read_keypad();
++      if ((KSCAN_ALLROWS | KSCAN_ALLCOLS) != nomadik_epio_read_keypad()) {
 +              /*check wrong key */
-+              nmdk_error("Keypad H/w error....");
-+              return (-1);
++              nmdk_error("H/w error....");
++              goto kphwiniterr_hwer;
 +      }
 +      if (!kp->mode) {        /* true if interrupt mode operation */
-+              /* pull down all rows to detect any keypress */
-+              nomadik_epio_write_keypad(0x00);
-+              /* enable keypad interrupt through CPLD logic */
-+              nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() |
-+                                         KEYP_MSK);
-+              set_irq_type(kp->irq, SA_TRIGGER_RISING);
-+              /*
-+               * TBD logic should be added to detect proper switch settings
-+               * on a board to detect valid interrupt
-+               */
++              /* Enable keypad interrupt generation logic in CPLD on ndk10 */
++              nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS);
++              nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() |
++                                         GPIO_EN);
++              nmdk_dbg("keypad interrupt CPLD logic enabled");
++
++              if (!kp->irq) {
++                      nmdk_error("keypad_irq cannot get in kpinit");
++                      err = -1;
++                      goto kphwiniterr_pinconfig;
++              }
++              set_irq_type(kp->irq, SA_TRIGGER_FALLING);
++              nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(kp->irq), &pin);
++              if (!pin) {
++                      /*check wrong configuration */
++                      nmdk_error("H/w error...(check sw8 on board)");
++                      goto kphwiniterr_itpin;
++              }
 +      }
 +      return 0;
++
++      kphwiniterr_itpin:
++      kphwiniterr_pinconfig:
++      kphwiniterr_hwer:
++      return -1;
 +}
 +
 +/**
@@ -17087,7 +17428,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 + */
 +int nomadik_kp_key_irqen(struct keypad_t *kp)
 +{
-+      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | KEYP_MSK);
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_keypad(KSCAN_AUX | KSCAN_ALLROWS);
 +      return 0;
 +}
 +
@@ -17098,8 +17440,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 + */
 +int nomadik_kp_key_irqdis(struct keypad_t *kp)
 +{
-+      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
-+                                 (unsigned short)(~KEYP_MSK));
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_keypad(KSCAN_ALLROWS);
 +      return 0;
 +}
 +
@@ -17107,9 +17449,929 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 + * Initializes the key scan table (lookup table) as per pre-defined the scan
 + * codes to be passed to upper layer with respective key codes
 + */
-+u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
-+      {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
-+      {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
++static u8 kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
++      {KEY_DOWN, KEY_END, KEY_KPASTERISK, KEY_0, KEY_COMMA},
++      {KEY_RIGHT, KEY_F5, KEY_7, KEY_8, KEY_9},
++      {KEY_ENTER, KEY_LEFT, KEY_4, KEY_5, KEY_6},
++      {KEY_RIGHTMETA, KEY_F4, KEY_1, KEY_2, KEY_3},
++      {KEY_LEFTMETA, KEY_UP, KEY_F1, KEY_F2, KEY_F3}
++};
++
++static struct keypad_device keypad_board = {
++      .init = nomadik_kp_init_key_hardware,
++      .exit = nomadik_kp_exit_key_hardware,
++      .scan = nomadik_kp_key_scan,
++      .irqen = nomadik_kp_key_irqen,
++      .irqdis = nomadik_kp_key_irqdis,
++      .kcode_tbl = (u8 *) kpd_lookup_tbl,
++      .krow = 8,
++      .kcol = 8,
++};
++
++static struct resource keypad_resources[] = {
++      [0] = {
++             .start = IRQNO_GPIO(KEYPAD_IRQ),
++             .end = IRQNO_GPIO(KEYPAD_IRQ),
++             .flags = IORESOURCE_IRQ,
++             },
++};
++
++static struct platform_device keypad_device = {
++      .name = "nmdk-kp",
++      .id = 0,
++      .dev = {
++              .platform_data = &keypad_board,
++              },
++      .num_resources = ARRAY_SIZE(keypad_resources),
++      .resource = keypad_resources,
++};
++
++/*
++ ***********************************************************************
++ */
++static struct platform_device *nmdk_platform_devices[] __initdata = {
++      &smc91x_device,
++      &keypad_device,
++      &touchp_device,
++#ifdef CONFIG_MTD
++      &nomadik_nand_flash,
++      &nomadik_nor_flash,
++#endif
++};
++
++void add_nmdk_platform_devices(void)
++{
++      platform_add_devices(nmdk_platform_devices,
++                           ARRAY_SIZE(nmdk_platform_devices));
++      nomadik_epio_init();
++      nomadik_platform_board_init();
++      nomadik_fsmc_init();
++      nomadik_pepperpot_board_init();
++      nomadik_smc91x_irq_init();
++}
++
++
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c
+@@ -0,0 +1,1001 @@
++/*
++ *  linux/arch/arm/mach-nomadik/ndk15_devices.c
++ *
++ *
++ *  Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
++ *
++ *  NDK15B0x board specifc driver defination
++ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/amba/bus.h>
++#include <linux/spi/spi.h>
++#include <linux/amba/kmi.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/param.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/kpd.h>
++#include <asm/arch/touchp.h>
++#include <asm/arch/fsmc.h>
++#ifdef CONFIG_MTD
++#include <linux/mtd/nand.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/concat.h>
++#include <asm/arch/nandflash.h>
++#include <asm/mach/flash.h>
++#endif
++#include <asm/arch/debug.h>
++
++#define BOARD_NAME            CONFIG_NOMADIK_PLATFORM
++#ifndef BOARD_DEBUG
++#define BOARD_DEBUG 0
++#endif
++
++#define NMDK_DEBUG    BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++/**
++ * nomadik_clcd_board_enable - enables board specific clcd prameters
++ *
++ * Settings to enable backlight and pannel voltage regulator for NDK15
++ */
++void nomadik_clcd_enable(void *fbp)
++{
++      /* not implimented for this board */
++}
++
++/**
++ * nomadik_clcd_board_disable - disables board specific clcd prameters
++ *
++ * Settings to disable backlight and pannel voltage regulator for NDK10
++ */
++void nomadik_clcd_disable(void *fbp)
++{
++      /* not implimented for this board */
++}
++
++/*
++ * Settings to configure MMC controller for NDK10
++ */
++int nomadik_mmc_configure(struct amba_device *dev)
++{
++      int ret;
++      gpio_config mmc_pin;
++      char x = val_volt;
++
++      mmc_pin.dev_name = dev->dev.bus_id;
++      mmc_pin.mode = GPIO_MODE_SOFTWARE;
++      mmc_pin.direction = GPIO_DIR_OUTPUT;
++      mmc_pin.trig = GPIO_TRIG_DISABLE;
++      mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
++
++      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++      if (ret) {
++              nmdk_error("Error in setting GPIO_PIN_75");
++              goto mmcconf_exit;
++      }
++      /* this enables power path from toureg to mmc */
++      ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id);
++      if (ret) {
++              nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
++              goto deallocate_pin_75;
++      }
++
++      ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
++      if (ret) {
++              nmdk_error("Error in writing value to touareg register");
++              goto deallocate_pin_75;
++      }
++
++      ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++      if (ret) {
++              nmdk_error("Error in gpio Altfunction enable");
++              goto deallocate_pin_75;
++      }
++      return ret;
++
++      deallocate_pin_75:
++      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
++      mmcconf_exit:
++      return ret;
++
++}
++
++void nomadik_mmc_restore_default(struct amba_device *dev)
++{
++      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
++}
++
++#ifdef CONFIG_MTD
++
++static struct resource nandflash_resources[] = {
++      [0] = {
++             .name = "cmem_address",
++             .start = NAND_B0_CMEM_ADDR,
++             .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [1] = {
++             .name = "cmem_command",
++             .start = NAND_B0_CMEM_CMD,
++             .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [2] = {
++             .name = "cmem_data",
++             .start = NAND_B0_CMEM_DATA,
++             .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
++             .flags = IORESOURCE_MEM,
++             },
++};
++
++#define NAND_STM_LP_OPTIONS \
++              (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
++
++static int nomadik_nandflash_exit(void)
++{
++      return 0;
++
++}
++static int nomadik_nandflash_init(void)
++{
++      /*
++       * FSMC initialization
++       * 0x0000001e => PCR0
++       * 0x000d0a00 => PMEM0
++       * 0x00100a00 => PATT0
++       */
++
++/*    pcr0.address_low        = 0;*/
++      gpio_config nmdknand_pin_config;
++      nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
++      nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
++      nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
++      nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
++      nmdknand_pin_config.dev_name = "nand";
++      /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */
++      if(nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config))
++              return -1;
++      if(nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name))
++              return -1;
++
++
++      /*Following Settings done for NAND flash protect off */
++      /* this was moved from board init to here */
++      /* This pin Conflicts with touchpanel TOUCHP_CS0*/
++      if(nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config))
++              return -1;
++      if(nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name))
++              return -1;
++      if(nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name ))
++              return -1;
++
++
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
++          DEFAULT_PCR0_VALUE;
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
++          DEFAULT_PMEM0_VALUE;
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
++          DEFAULT_PATT0_VALUE;
++      return 0;
++}
++
++static const unsigned char lookup_t[256] = {
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
++};
++
++int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
++                          u_char * ecc)
++{
++      unsigned int sumCol = 0;
++      unsigned int datum, temp;
++      unsigned int glob_parity;
++      const int ecc_n_bytes = 512;
++      int i;
++
++      unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
++      unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
++          0, parit32_1 = 0, parit32_2 = 0;
++      unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
++          0, parit256_1 = 0, parit256_2 = 0;
++      unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
++          0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++
++      for (i = ecc_n_bytes - 1; i >= 0; --i) {
++              datum = data[i];
++              sumCol ^= datum;
++              temp = lookup_t[datum];
++
++              if (i & 0x01)
++                      parit8_1 ^= temp;
++              if (i & 0x02)
++                      parit16_1 ^= temp;
++              if (i & 0x04)
++                      parit32_1 ^= temp;
++              if (i & 0x08)
++                      parit64_1 ^= temp;
++              if (i & 0x10)
++                      parit128_1 ^= temp;
++              if (i & 0x20)
++                      parit256_1 ^= temp;
++              if (i & 0x40)
++                      parit512_1 ^= temp;
++              if (i & 0x80)
++                      parit1024_1 ^= temp;
++              if (i & 0x100)
++                      parit2048_1 ^= temp;
++      }
++
++      glob_parity = lookup_t[sumCol];
++
++      parit1_1 =
++          ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
++      parit1_2 =
++          ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
++      parit2_1 =
++          ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++      parit2_2 =
++          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
++      parit4_1 =
++          ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++      parit4_2 =
++          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++
++      parit8_2 = glob_parity ^ parit8_1;
++      parit16_2 = glob_parity ^ parit16_1;
++      parit32_2 = glob_parity ^ parit32_1;
++      parit64_2 = glob_parity ^ parit64_1;
++      parit128_2 = glob_parity ^ parit128_1;
++      parit256_2 = glob_parity ^ parit256_1;
++      parit512_2 = glob_parity ^ parit512_1;
++      parit1024_2 = glob_parity ^ parit1024_1;
++      parit2048_2 = glob_parity ^ parit2048_1;
++
++      /* Pack bits */
++      ecc[0] =
++          ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
++            (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
++                                                                      << 1) |
++            parit8_2);
++      ecc[1] =
++          ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
++            (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
++            (parit128_1 << 1) | parit128_2);
++      ecc[2] =
++          ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
++            (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
++                                                                   << 1) |
++            parit2048_2);
++
++      return 0;
++}
++
++static struct nand_ecclayout nand_oob = {
++      .eccbytes = 12,
++      .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
++      .oobavail = MTD_NANDECC_AUTOPLACE,
++      .oobfree = {
++              { .offset = 8,
++               .length = 8,
++              },
++              { .offset = 24,
++               .length = 8,
++              },
++              { .offset = 40,
++               .length = 8,
++              },
++              { .offset = 56,
++               .length = 8,
++              },
++              },
++};
++
++static struct mtd_partition nandflash_main_partitions[] = {
++
++      {.name = "X-Loader(NAND)",
++       .offset = 0,
++       .size = 2 * 0x000020000},      /*256 Kbytes */
++      {.name = "MemInit(NAND)",
++       .offset = 2 * 0x000020000,
++       .size = 2 * 0x000020000},      /*128 KBytes */
++      {.name = "BootLoader(NAND)",
++       .offset = 4 * 0x000020000,
++       .size = 16 * 0x00020000},      /*2Mbytes */
++      {.name = "Kernel zImage(NAND)",
++       .offset = 20 * 0x000020000,
++       .size = 24 * 0x000020000},     /*3Mbytes */
++      {.name = "Root Filesystem(NAND)",
++       .offset = 44 * 0x000020000,
++       .size = 176 * 0x000020000},    /*22 Mbytes */
++      {.name = "User Filesystem(NAND)",
++       .offset = 220 * 0x000020000,
++       .size = 800 * 0x000020000},    /*100 Mbytes */
++};
++
++static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++
++static struct nand_bbt_descr bbt_desc = {
++      .options = 0,
++      .offs = 0,
++      .len = 2,
++      .pattern = scan_ff_pattern
++};
++
++static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
++                                  unsigned int ctrl)
++{
++      struct nomadik_nand_info *drvdata =
++          container_of(mtd, struct nomadik_nand_info, mtd);
++
++      if (cmd == NAND_CMD_NONE)
++              return;
++
++      if (ctrl & NAND_NCE) {
++              *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
++                                           0x40)) |= 0x04;
++      }
++      if (ctrl & NAND_CLE) {
++              writeb(cmd,drvdata->cmemc_va);
++      }
++      if (ctrl & NAND_ALE) {
++              writeb(cmd,drvdata->cmema_va);
++      }
++}
++
++static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
++      .parts = nandflash_main_partitions,
++      .num_parts = ARRAY_SIZE(nandflash_main_partitions),
++      .lp_options = NAND_STM_LP_OPTIONS,
++      .eccsize = 512,
++      .eccsteps = 4,
++      .badblockpos = 5,
++      .init = nomadik_nandflash_init,
++      .exit = nomadik_nandflash_exit,
++      .nand_oob = &nand_oob,
++      .bbt_desc = &bbt_desc,
++      .compute_ecc = nmdknand_compute_ecc512,
++      .hwcontrol = nmdknand_hwcontrol,
++};
++
++static struct platform_device nomadik_nand_flash = {
++      .name = "NOMADIK-NAND",
++      .id = 0,
++      .dev = {
++              .platform_data = &nomadik_nand_flash_data,
++              },
++      .num_resources = ARRAY_SIZE(nandflash_resources),
++      .resource = nandflash_resources,
++};
++
++static struct mtd_partition nmdkflash_main_partitions[] = {
++      {.name = "BootLoader(NOR)",
++       .size = 0x00040000,    /*256K */
++       .offset = 0,},
++      {.name = "zImage+initrd(NOR)",
++       .size = 0x001C0000,    /*1.75MB */
++       .offset = MTDPART_OFS_APPEND,},
++      {.name = "Root Filesystem(NOR)",
++       .size = 0x01200000,    /*18MB */
++       .offset = MTDPART_OFS_APPEND,},
++      {.name = "User Filesystem(NOR)",
++       .size = 0x00800000,    /*8MB */
++       .offset = MTDPART_OFS_APPEND,},
++      {.name = "initrd(NOR)",
++       .size = 0x00200000,    /*4MB */
++       .offset = MTDPART_OFS_APPEND,}
++};
++
++static struct flash_platform_data nomadik_nor_flash_data = {
++      .name = "nomadik_nor",
++      .map_name = "cfi_probe",
++      /*.width                = NMDK_FLASH_BUSWIDTH, */
++      .parts = nmdkflash_main_partitions,
++      .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
++};
++
++static struct resource norflash_resources[] = {
++      [0] = {
++             .name = "norflash-regs",
++             .start = NMDK_FLASH_BASE,
++             .end = (NMDK_FLASH_BASE + SZ_32M - 1),
++             .flags = IORESOURCE_MEM,
++             },
++};
++
++static struct platform_device nomadik_nor_flash = {
++      .name = "NOMADIK-NOR",
++      .id = 0,
++      .dev = {
++              .platform_data = &nomadik_nor_flash_data,
++              },
++      .num_resources = ARRAY_SIZE(norflash_resources),
++      .resource = norflash_resources,
++};
++
++#endif
++
++static struct resource smc91x_resources[] = {
++      [0] = {
++             .name = "smc91x-regs",
++             .start = (NOMADIK_ETH0_BASE + 0x300),
++             .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [1] = {
++             .start = IRQNO_GPIO(SMC91111_IRQ),
++             .end = IRQNO_GPIO(SMC91111_IRQ),
++             .flags = IORESOURCE_IRQ,
++             },
++};
++
++static struct platform_device smc91x_device = {
++      .name = "smc91x",
++      .id = 0,
++      .num_resources = ARRAY_SIZE(smc91x_resources),
++      .resource = smc91x_resources,
++};
++
++/*
++ * touchpanel
++ */
++#ifndef TOUCHP_DEBUG
++#define TOUCHP_DEBUG 0                /* default debug messages are disabled */
++#endif                                /*  */
++
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#define NMDK_DEBUG    TOUCHP_DEBUG    /* enables/disables debug msgs */
++#define NMDK_DEBUG_PFX  TPDRVNAME     /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++/**
++ * nomadik_tp_ssp_board_init - board specific ssp data path setup
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the SSP for touchpanel operation
++ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
++ */
++int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
++{
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_ssp_conf(EXP_SSP);
++      return (0);
++}
++
++/**
++ * nomadik_tp_gpio_board_init - board specific gpio initialization
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the GPIO for touchpanel operation
++ * RETURN: GPIO nmdk_error code
++ * SSP is interfaced with ADS7843 through CPLD hence respective
++ * interface need to be enabled for NDK10
++ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
++ * chip select, this bit allows the selection between the two
++ * peripherals. setting this bit Touch screen selected
++ */
++gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
++{
++      gpio_error status = GPIO_OK;
++      gpio_config config_cspin;
++      gpio_data touchp_cs1;
++      nmdk_dbg_ftrace();
++
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
++
++      /* Set SPICSn_TCHSCR pin configuration */
++      config_cspin.mode = GPIO_MODE_SOFTWARE;
++      config_cspin.direction = GPIO_DIR_OUTPUT;
++      config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
++      config_cspin.dev_name = "Touchp";
++      /*
++       * TOUCHP_CS1 need to be high always to select ad7843 cs properly
++       * this pin will be set high by nand_init(NAND_PROT_OFF)
++       * if this pin is not high and set it high
++       */
++      status |= nomadik_gpio_readpin(TOUCHP_CS1, &touchp_cs1);
++      if (!touchp_cs1) {
++              status |= nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
++              status |= nomadik_gpio_writepin(TOUCHP_CS1, 1, config_cspin.dev_name);
++              status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, config_cspin.dev_name);
++      }
++      status |= nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
++      if (status) {
++              nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
++                         TOUCHP_CS0, status);
++              return (status);
++      }
++      /* Set PENIRQ pin configuration */
++      set_irq_type(p_adsContext->irq, SA_TRIGGER_RISING);
++      return status;
++}
++
++/**
++ * nomadik_tp_gpio_board_exit - board specific gpio exit
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine performs revers action of init
++ */
++gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
++{
++      gpio_error status = GPIO_OK;
++
++      nmdk_dbg_ftrace();
++      /* Enable CPLD logic for access/interrupts on ndk15 in case of int mode */
++      if (!p_adsContext->mode) {
++              nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
++                                      (u16)~TSIT_MSK);
++      }
++      status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
++      return status;
++}
++
++/**
++ * nomadik_tp_pen_down - returns pen touch status
++ */
++t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
++{
++      gpio_data pen_down;
++      nmdk_dbg_ftrace();
++      pen_down = nomadik_epio_read_aux_gpi1();
++      pen_down &= TCHSCR_PENIRQ;
++      nmdk_dbg2("pen_down = 0x%d", pen_down);
++      return ((t_bool) pen_down);
++}
++
++/**
++ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
++{
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | TSIT_MSK);
++}
++
++/**
++ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
++{
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
++                                 (unsigned short)(~TSIT_MSK));
++}
++
++/**
++ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to disable chip select
++ */
++void nomadik_tp_spi_cs_disable(void)
++{
++      nmdk_dbg_ftrace();
++      nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
++}
++
++/**
++ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to enable chip select
++ */
++void nomadik_tp_spi_cs_enable(void)
++{
++      nmdk_dbg_ftrace();
++      nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
++}
++
++static struct touchp_device touchp_board = {
++      .ssp_init = nomadik_tp_ssp_board_init,
++      .gpio_init = nomadik_tp_gpio_board_init,
++      .gpio_exit = nomadik_tp_gpio_board_exit,
++      .pdown = nomadik_tp_pen_down,
++      .pirq_en = nomadik_tp_pen_down_irq_enable,
++      .pirq_dis = nomadik_tp_pen_down_irq_disable,
++      .cs_en = nomadik_tp_spi_cs_disable,
++      .cs_dis = nomadik_tp_spi_cs_enable,
++      .samples = 20, /*samples per second*/
++      .pollsamples = 10, /*polling per second*/
++};
++
++static struct resource touchp_resources[] = {
++      [0] = {
++             .start = IRQNO_GPIO(TOUCHP_IRQ),
++             .end = IRQNO_GPIO(TOUCHP_IRQ),
++             .flags = IORESOURCE_IRQ,
++             },
++};
++
++static struct platform_device touchp_device = {
++      .name = "nmdk-tp",
++      .id = 0,
++      .dev = {
++              .platform_data = &touchp_board,
++              },
++      .num_resources = ARRAY_SIZE(touchp_resources),
++      .resource = touchp_resources,
++};
++
++#define KEYPAD_NAME           "KEYPAD"
++#ifndef KEYPAD_DEBUG
++#define KEYPAD_DEBUG 0
++#endif
++
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#define NMDK_DEBUG    KEYPAD_DEBUG    /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  KEYPAD_NAME   /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++/*key scan constants*/
++#define KSCAN_ALLROWS   0x00FF
++#define KSCAN_ALLCOLS   0xFF00
++#define KSCAN_ROW0      0x0001
++#define KSCAN_ROW1      0x0002
++#define KSCAN_ROW2      0x0004
++#define KSCAN_ROW3      0x0008
++#define KSCAN_ROW4      0x0010
++#define KSCAN_ROW5      0x0020
++#define KSCAN_ROW6      0x0040
++#define KSCAN_ROW7      0x0080
++#define KSCAN_COL0      0x0100
++#define KSCAN_COL1      0x0200
++#define KSCAN_COL2      0x0400
++#define KSCAN_COL3      0x0800
++#define KSCAN_COL4      0x1000
++#define KSCAN_COL5      0x2000
++#define KSCAN_COL6      0x4000
++#define KSCAN_COL7      0x8000
++
++unsigned short const keychkval_set[] = {
++      (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++};
++
++unsigned short const keychkval_read[] = {
++      KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
++      KSCAN_ROW6, KSCAN_ROW7,
++};
++
++/**
++ * nomadik_kp_ghostkey_detect - ghost key detect function
++ * @rowval: row in which ghost key to be detected
++ *
++ * when more than one key is pressed in the same row the keypad logic cannot
++ * detect proper key press, the logic here detects multiple keypress on a
++ * single row and returns error
++ */
++int nomadik_kp_ghostkey_detect(short rowval)
++{
++      int row;
++      int ghcnt = 0;
++
++      for (row = 0; row < MAX_KPROW; row++) {
++              if (0 == (rowval & keychkval_read[row])) {
++                      /*keypr detected */
++                      ghcnt++;
++              }
++              if (1 < ghcnt)
++                      /*return error if more than one keys are pressed in a row */
++                      return (-1);
++      }
++      return (0);
++}
++
++/**
++ * nomadik_kp_key_scan - keypad scan and report event function
++ *
++ * Scans through keypad hardware and updates the key status for key press
++ * or key release event to upper layer
++ */
++int nomadik_kp_key_scan(struct keypad_t *kp)
++{
++      short val;
++      u8 row, col;
++      int keyp_cnt = 0;
++      u8 *p_kcode;
++
++      nmdk_dbg_ftrace();
++      for (col = 0; col < MAX_KPCOL; col++) {
++              p_kcode = kp->board->kcode_tbl + col;
++              nomadik_epio_write_keypad(keychkval_set[col]);
++              val = nomadik_epio_read_keypad();
++              val &= KSCAN_ALLROWS;
++              if (0 == nomadik_kp_ghostkey_detect(val)) {
++                      for (row = 0; row < MAX_KPROW; row++) {
++                              if (0 == (val & keychkval_read[row])) { /*keypr detected */
++                                      keyp_cnt++;
++                                      if (kp->key_state[row][col] ==
++                                          KEYPAD_STATE_DEFAULT) {
++                                              input_report_key(kp->inp_dev,
++                                                               *p_kcode, 1);
++                                              nmdk_dbg("P:%d ", *p_kcode);
++                                              kp->key_state[row][col] =
++                                                  KEYPAD_STATE_PRESSACK;
++                                      }
++                              } else {        /*key not pressed detected */
++                                      if (kp->key_state[row][col] ==
++                                          KEYPAD_STATE_PRESSACK) {
++                                              input_report_key(kp->inp_dev,
++                                                               *p_kcode, 0);
++                                              nmdk_dbg("R:%d ", *p_kcode);
++                                              kp->key_state[row][col] =
++                                                  KEYPAD_STATE_DEFAULT;
++                                      }
++                              }
++                              p_kcode += MAX_KPROW;
++                      }
++              } else
++                      keyp_cnt += 0x100;      /* to flag ghost keypress detection */
++      }
++      /* pull down all rows to detect any keypress */
++      nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
++      return (keyp_cnt);
++}
++
++/**
++ * nomadik_kp_init_key_hardware -  keypad hardware initialization
++ *
++ * Initializes the keypad hardware specific parameters.
++ * This function will be called by nomadik_keypad_init function during init
++ * Initialize keypad interrupt handler for interrupt mode operation if enabled
++ * Initialize Keyscan matrix
++ ****************************************************************************
++ */
++int nomadik_kp_init_key_hardware(struct keypad_t *kp)
++{
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_keypad(KSCAN_ALLCOLS);
++      if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
++              /*check wrong key */
++              nmdk_error("Keypad H/w error....");
++              return (-1);
++      }
++      if (!kp->mode) {        /* true if interrupt mode operation */
++              /* pull down all rows to detect any keypress */
++              nomadik_epio_write_keypad(0x00);
++              /* enable keypad interrupt through CPLD logic */
++              nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() |
++                                         KEYP_MSK);
++              set_irq_type(kp->irq, SA_TRIGGER_RISING);
++              /*
++               * TBD logic should be added to detect proper switch settings
++               * on a board to detect valid interrupt
++               */
++      }
++      return 0;
++}
++
++/**
++ * nomadik_kp_exit_key_hardware- keypad hardware exit function
++ *
++ * This function will be called by nomadik_keypad_exit function during module
++ * exit, frees keypad interrupt if enabled
++ */
++int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
++{
++      nmdk_dbg_ftrace();
++      return 0;
++}
++
++/**
++ * nomadik_kp_key_irqen- enables keypad interrupt
++ *
++ * enables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqen(struct keypad_t *kp)
++{
++      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() | KEYP_MSK);
++      return 0;
++}
++
++/**
++ * nomadik_kp_key_irqdis- disables keypad interrupt
++ *
++ * disables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqdis(struct keypad_t *kp)
++{
++      nomadik_epio_write_it_mngt(nomadik_epio_read_it_mngt() &
++                                 (unsigned short)(~KEYP_MSK));
++      return 0;
++}
++
++/*
++ * Initializes the key scan table (lookup table) as per pre-defined the scan
++ * codes to be passed to upper layer with respective key codes
++ */
++u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
++      {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
++      {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
 +      {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT,
 +       KEY_HOME},
 +      {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U},
@@ -17193,7 +18455,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      .resource = fsmc_resources,
 +};
 +
-+#ifdef CONFIG_CPLD_I2C 
++#ifdef CONFIG_CPLD_I2C
 +static void nomadik_smc91x_irq_init(void)
 +{
 +      nmdk_dbg_ftrace();
@@ -17234,7 +18496,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +
 +static struct platform_device *nmdk_platform_devices[] __initdata = {
 +      &fsmc_device,
-+#ifdef CONFIG_CPLD_I2C 
++#ifdef CONFIG_CPLD_I2C
 +      &epio_device,
 +#endif
 +      &keypad_device,
@@ -17253,9 +18515,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6
 +      device_init_wakeup(&keypad_device.dev, 1);
 +      device_init_wakeup(&touchp_device.dev, 1);
 +}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig  2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig
 @@ -0,0 +1,37 @@
 +if NOMADIK_NDK15_REV2_B_03
 +
@@ -17264,14 +18525,14 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig ../new/l
 +
 +#target name configuration for this target
 +config NOMADIK_TARGET
-+      string 
++      string
 +      default NDK15_Rev2_B_03
 +
 +# nomadik cpld identification name for this target
 +config NOMADIK_CPLD_V2010
 +      bool
 +      default y
-+ 
++
 +# nomadik soc chip name configuration for this targe
 +config NOMADIK_SOC
 +      string
@@ -17294,9 +18555,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_03_Kconfig ../new/l
 +      default y
 +
 +endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig  2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig
 @@ -0,0 +1,37 @@
 +if NOMADIK_NDK15_REV2_B_05
 +
@@ -17305,14 +18565,14 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig ../new/l
 +
 +#target name configuration for this target
 +config NOMADIK_TARGET
-+      string 
++      string
 +      default NDK15_Rev2_B_05
 +
 +# nomadik cpld identification name for this target
 +config NOMADIK_CPLD_V2010
 +      bool
 +      default y
-+  
++
 +# nomadik soc chip name configuration for this targe
 +config NOMADIK_SOC
 +      string
@@ -17335,9 +18595,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_05_Kconfig ../new/l
 +      default y
 +
 +endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig  2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig
 @@ -0,0 +1,42 @@
 +if NOMADIK_NDK15_REV2_B_06
 +
@@ -17346,14 +18605,14 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig ../new/l
 +
 +#target name configuration for this target
 +config NOMADIK_TARGET
-+      string 
++      string
 +      default NDK15_Rev2_B_06
 +
 +# nomadik cpld identification name for this target
 +config NOMADIK_CPLD_V2010
 +      bool
 +      default y
-+  
++
 +# nomadik soc chip name configuration for this targe
 +config NOMADIK_SOC
 +      string
@@ -17381,9 +18640,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev2_b_06_Kconfig ../new/l
 +      default y
 +
 +endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig  2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig
 @@ -0,0 +1,42 @@
 +if NOMADIK_NDK15_REV3_C_02
 +
@@ -17392,14 +18650,14 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig ../new/l
 +
 +#target name configuration for this target
 +config NOMADIK_TARGET
-+      string 
++      string
 +      default NDK15_Rev3_C_02
 +
 +# nomadik cpld identification name for this target
 +config NOMADIK_CPLD_V3012
 +      bool
 +      default y
-+ 
++
 +# nomadik soc chip name configuration for this target
 +config NOMADIK_SOC
 +      string
@@ -17427,12 +18685,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_rev3_c_02_Kconfig ../new/l
 +      default y
 +
 +endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c  2008-09-17 13:23:32.000000000 +0530
-@@ -0,0 +1,1009 @@
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ndk15c02_devices.c
+@@ -0,0 +1,1023 @@
 +/*
-+ *  linux/arch/arm/mach-nomadik/nhk15_devices.c
++ *  linux/arch/arm/mach-nomadik/ndk15c02_devices.c
 + *
 + *  Copyright (C) STMicroelectronics
 + *
@@ -17440,7 +18697,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 + * it under the terms of the GNU General Public License version 2, as
 + * published by the Free Software Foundation.
 + *
-+ *  NHK15 board specifc driver definition
++ *  NDK15C02 board specifc driver defination
 + */
 +#include <linux/types.h>
 +#include <linux/kernel.h>
@@ -17480,11 +18737,6 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +#include <asm/mach/flash.h>
 +#endif
 +#include <asm/arch/debug.h>
-+#include <asm/arch/pexp.h>
-+#include <asm/arch/touchp2003.h>
-+
-+#define DEBUG_KP(x) printk x
-+#define DEBUG_TS(x) printk x
 +
 +#define BOARD_NAME            CONFIG_NOMADIK_PLATFORM
 +#ifndef BOARD_DEBUG
@@ -17495,12 +18747,6 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
 +#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+#define INT_USBOTG      23 
-+#define  NOMADIK_USB_BASE 0x10170000 
-+#ifdef CONFIG_SMC91X
-+static void nomadik_smc91x_irq_init(void);
-+#endif
-+
 +/**
 + * nomadik_clcd_board_enable - enables board specific clcd prameters
 + *
@@ -17521,35 +18767,60 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      /* not implimented for this board */
 +}
 +
++//#ifdef CONFIG_MMC_NOMADIK
 +/*
 + * Settings to configure MMC controller for NDK10
 + */
 +int nomadik_mmc_configure(struct amba_device *dev)
 +{
-+      /* not implimented for this board */
 +      int ret;
++      gpio_config mmc_pin;
 +      char x = val_volt;
-+       ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
-+        if (ret) {
-+                nmdk_error("Error in writing value to touareg register");
 +
-+        }
++      mmc_pin.dev_name = dev->dev.bus_id;
++      mmc_pin.mode = GPIO_MODE_SOFTWARE;
++      mmc_pin.direction = GPIO_DIR_OUTPUT;
++      mmc_pin.trig = GPIO_TRIG_DISABLE;
++      mmc_pin.debounce = GPIO_DEBOUNCE_DISABLE;
 +
-+        ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
-+        if (ret) {
-+                nmdk_error("Error in gpio Altfunction enable");
++      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++      if (ret) {
++              nmdk_error("Error in setting GPIO_PIN_75");
++              goto mmcconf_exit;
++      }
++      /* this enables power path from toureg to mmc */
++      ret = nomadik_gpio_writepin(GPIO_PIN_75, GPIO_DATA_HIGH, dev->dev.bus_id);
++      if (ret) {
++              nmdk_error("Error in setting GPIO_PIN_75 value to HIGH");
++              goto deallocate_pin_75;
++      }
 +
-+        }
-+        return ret;
++      ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
++      if (ret) {
++              nmdk_error("Error in writing value to touareg register");
++              goto deallocate_pin_75;
++      }
++
++      ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++      if (ret) {
++              nmdk_error("Error in gpio Altfunction enable");
++              goto deallocate_pin_75;
++      }
++      return ret;
++
++      deallocate_pin_75:
++      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
++      mmcconf_exit:
++      return ret;
 +
-+      return 0;
 +}
 +
 +void nomadik_mmc_restore_default(struct amba_device *dev)
 +{
-+      /* not implimented for this board */
 +      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++      nomadik_gpio_resetpinconfig(GPIO_PIN_75, dev->dev.bus_id);
 +}
++//#endif
 +
 +static int fsmc_platform_init(void)
 +{
@@ -17564,8 +18835,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
 +      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
 +      /* Initialize the fsmc bank 1 used for ethernet controller */
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x305B;
-+      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x033F33;    /*old 00000702 */
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x10db;
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x00000702;  /*old 00000702 */
 +
 +      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
 +      /* Above Settings done for NAND flash protect off */
@@ -17595,7 +18866,6 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +};
 +
 +#ifdef CONFIG_MTD
-+#ifdef CONFIG_MTD_NAND
 +static struct resource nandflash_resources[] = {
 +      [0] = {
 +             .name = "cmem_address",
@@ -17617,9 +18887,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +             },
 +};
 +
-+/*NHK15 is 8-bit NAND*/
 +#define NAND_STM_LP_OPTIONS \
-+              ( NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING | NAND_NO_READRDY | NAND_NO_AUTOINCR)
++              (NAND_BUSWIDTH_16 | NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING)
 +
 +int nomadik_nandflash_exit(void)
 +{
@@ -17628,20 +18897,34 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +}
 +int nomadik_nandflash_init(void)
 +{
-+#if 1 
 +      /*
 +       * FSMC initialization
-+       * 0x0000000e => PCR0
++       * 0x0000001e => PCR0
 +       * 0x000d0a00 => PMEM0
 +       * 0x00100a00 => PATT0
 +       */
++
++/*    pcr0.address_low        = 0;*/
++      gpio_config nmdknand_pin_config;
++      nmdknand_pin_config.mode = GPIO_MODE_SOFTWARE;
++      nmdknand_pin_config.direction = GPIO_DIR_OUTPUT;
++      nmdknand_pin_config.trig = GPIO_TRIG_DISABLE;
++      nmdknand_pin_config.debounce = GPIO_DEBOUNCE_UNCHANGED;
++      nmdknand_pin_config.dev_name = "nand";
++      /*nomadik_gpio_allocatepin(NAND_GPIO, &nand_handle);ppw */
++      nomadik_gpio_setpinconfig(NAND_GPIO, &nmdknand_pin_config);
++      nomadik_gpio_writepin(NAND_GPIO, 1, nmdknand_pin_config.dev_name);
++      /*Following Settings done for NAND flash protect off */
++      nomadik_gpio_setpinconfig(NAND_FLASH_PROTOFF, &nmdknand_pin_config);
++      nomadik_gpio_writepin(NAND_FLASH_PROTOFF, 1, nmdknand_pin_config.dev_name);
++      nomadik_gpio_resetpinconfig(NAND_FLASH_PROTOFF, nmdknand_pin_config.dev_name);
++
 +      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
-+              0x0000000E;             /* NHK15 is  8-bit NAND */
++          DEFAULT_PCR0_VALUE;
 +      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
 +          DEFAULT_PMEM0_VALUE;
 +      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
 +          DEFAULT_PATT0_VALUE;
-+#endif
 +      return 0;
 +}
 +
@@ -17751,24 +19034,20 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +}
 +
 +static struct nand_ecclayout nand_oob = {
++
 +      .eccbytes = 12,
-+      .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
-+      .oobavail = MTD_NANDECC_AUTOPLACE,
-+      .oobfree = {            
++
++
++
++      .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
++      .oobavail = MTD_NANDECC_AUTOPLACE,
++      .oobfree = {
 +              { .offset = 8,
 +               .length = 8,
 +              },
-+              { .offset = 24,
-+               .length = 8,
-+              },
-+              { .offset = 40,
-+               .length = 8,
-+              },
-+              { .offset = 56,
-+               .length = 8,
-+              },
 +              },
 +};
++
 +static struct mtd_partition nandflash_main_partitions[] = {
 +
 +      {.name = "X-Loader(NAND)",
@@ -17827,8 +19106,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      .lp_options = NAND_STM_LP_OPTIONS,
 +      .eccsize = 512,
 +      .eccsteps = 4,
-+      /*.badblockpos = 5,*/
-+      .badblockpos = 6,
++      .badblockpos = 5,
 +      .init = nomadik_nandflash_init,
 +      .exit = nomadik_nandflash_exit,
 +      .nand_oob = &nand_oob,
@@ -17846,153 +19124,69 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      .num_resources = ARRAY_SIZE(nandflash_resources),
 +      .resource = nandflash_resources,
 +};
-+#endif //CONFIG_MTD_NAND
-+
-+#ifdef CONFIG_MTD_ONENAND
-+static int nomadik_1nand_init(void)
-+{     int ret=0;
-+      int fsmc_err=1;
-+      int board=8820;
-+      
-+      /*Set the reset signal to high*/
-+      ret = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_9,STMPE2401_PRIMARY_FUNCTION);
-+        if (ret != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE1 %d as  primary function\n",EGPIO_PIN_9);
-+        ret = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_9,STMPE2401_GPIO_OUT);
-+        if (ret != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_9);
-+        ret = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_9, 1);
-+      
-+      /*Configure other GPIO pins to ALT FUNC A*/
-+        ret = nomadik_gpio_altfuncenable(GPIO_ALT_ONENAND, "onenand");
-+      if (ret)
-+      {       nmdk_error("Could not set oneNAND GPIO alternate function correctly\n");
-+              printk("\n>ERROR to config GPIO %d", ret);
-+              return -1;
-+      }
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = DEFAULT_BCR0_VALUE;
-+      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = DEFAULT_BTR0_VALUE;
-+       return 0;
-+}
-+
-+void nomadik_1nand_exit(void)
-+{     int ret=0;
-+      ret=nomadik_gpio_altfuncdisable(GPIO_ALT_ONENAND, "onenand");
-+      if(!ret)
-+      return;
-+      else
-+      {       printk("Could not Disable ST ONENAND GPIO alternate function \n");
-+      }
-+}
 +
++static struct mtd_partition nmdkflash_main_partitions[] = {
++      {.name = "BootLoader(NOR)",
++       .size = 0x00040000,    /*256K */
++       .offset = 0,},
++      {.name = "zImage+initrd(NOR)",
++       .size = 0x001C0000,    /*1.75MB */
++       .offset = MTDPART_OFS_APPEND,},
++      {.name = "Root Filesystem(NOR)",
++       .size = 0x01200000,    /*18MB */
++       .offset = MTDPART_OFS_APPEND,},
++      {.name = "User Filesystem(NOR)",
++       .size = 0x00800000,    /*8MB */
++       .offset = MTDPART_OFS_APPEND,},
++      {.name = "initrd(NOR)",
++       .size = 0x00200000,    /*4MB */
++       .offset = MTDPART_OFS_APPEND,}
++};
 +
++static struct flash_platform_data nomadik_nor_flash_data = {
++      .name = "nomadik_nor",
++      .map_name = "cfi_probe",
++      /*.width                = NMDK_FLASH_BUSWIDTH, */
++      .parts = nmdkflash_main_partitions,
++      .nr_parts = ARRAY_SIZE(nmdkflash_main_partitions),
++};
 +
-+static struct resource nomadik_1nand_resource[] = {
++static struct resource norflash_resources[] = {
 +      [0] = {
-+             .start = NOMADIK_1NAND_BASE,
-+             .end = NOMADIK_1NAND_BASE + SZ_128K - 1,
++             .name = "norflash-regs",
++             .start = NMDK_FLASH_BASE,
++             .end = (NMDK_FLASH_BASE + SZ_32M - 1),
 +             .flags = IORESOURCE_MEM,
 +             },
 +};
-+static struct mtd_partition onenandflash_main_partitions[] = {
-+      {.name = "X-Loader(ONENAND)",
-+       .offset = 0,
-+       .size = 2 * 0x000020000},      /*256 Kbytes */
-+      {.name = "MemInit(ONENAND)",
-+       .offset = 2 * 0x000020000,
-+       .size = 2 * 0x000020000},      /*256 KBytes */
-+      {.name = "BootLoader(ONENAND)",
-+       .offset = 4 * 0x000020000,
-+       .size = 16 * 0x00020000},      /*2Mbytes */
-+      {.name = "Kernel zImage(ONENAND)",
-+       .offset = 20 * 0x000020000,
-+       .size = 32 * 0x000020000},     /*4Mbytes */
-+      {.name = "Root Filesystem(ONENAND)",
-+       .offset = 52 * 0x000020000,
-+       .size = 176 * 0x000020000},    /*22 Mbytes */
-+      {.name = "User Filesystem(ONENAND)",
-+       .offset = 228 * 0x000020000,
-+       .size =  1820 * 0x000020000},  /*227.5 Mbytes */
-+};
-+
-+static struct flash_platform_data nomadik_1nand_flash_data={
-+      .init=nomadik_1nand_init,
-+      .exit=nomadik_1nand_exit,
-+      .name="onenand",
-+      .parts=onenandflash_main_partitions,
-+      .nr_parts=ARRAY_SIZE(onenandflash_main_partitions),
-+};
 +
-+static struct platform_device nomadik_1nand_flash = {
-+      .name = "onenand",
++static struct platform_device nomadik_nor_flash = {
++      .name = "NOMADIK-NOR",
 +      .id = 0,
 +      .dev = {
-+              .bus_id = "1nand",
-+              .platform_data = &nomadik_1nand_flash_data,
++              .platform_data = &nomadik_nor_flash_data,
 +              },
-+      .num_resources = ARRAY_SIZE(nomadik_1nand_resource),
-+      .resource = nomadik_1nand_resource,
++      .num_resources = ARRAY_SIZE(norflash_resources),
++      .resource = norflash_resources,
 +};
-+#endif //CONFIG_MTD_ONENAND
++
 +#endif
 +
 +#undef NMDK_DEBUG     /*board*/
 +#undef NMDK_DEBUG_PFX
 +#undef NMDK_DBG
 +
-+static void nomadik_st2590_init(void)
-+{
-+      t_STMPE2401_error err;
 +
-+      nomadik_gpio_altfuncenable(GPIO_ALT_UART_0_MODEM, "BT");
-+      nomadik_gpio_altfuncenable(GPIO_ALT_MSP_2, "BT");
-+        /*reset the bt controller which is conected thro port expander 0*/
-+        err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_16,STMPE2401_PRIMARY_FUNCTION);
-+        if (err != STMPE2401_OK)
-+        {
-+                printk("Couldn't set STMPE%d %d as primary function\n",STMPE0,EGPIO_PIN_16);
-+        }
-+        err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_16,STMPE2401_GPIO_OUT );
-+        if (err != STMPE2401_OK)
-+        {
-+               printk("Couldn't set STMPE0 EGPIO:%d in Output direction\n", EGPIO_PIN_16);
-+        }
-+        err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,0);
-+        if (err != STMPE2401_OK)
-+        {
-+               printk("Couldn't set STMPE0 GPIO16\n");
-+        }
-+        msleep(100);
-+        err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,1);
-+        if (err != STMPE2401_OK)
-+        {
-+               printk("Couldn't set STMPE0 GPIO16\n");
-+        }
-+        printk("BT Reset Applied !!\n");
-+}
 +#ifdef CONFIG_SMC91X
 +static void nomadik_smc91x_irq_init(void)
 +{
-+      t_STMPE2401_error err;
-+        
-+      nomadik_gpio_altfuncenable(GPIO_ALT_ETHERNET, "ETH");
-+        /*reset the ethernet controller which is conected thro port expander 1*/
-+        err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_10,STMPE2401_PRIMARY_FUNCTION);
-+        if (err != STMPE2401_OK)
-+        {
-+                printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_10);
-+        }
-+        err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_10,STMPE2401_GPIO_OUT );
-+        if (err != STMPE2401_OK)
-+        {
-+               printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_10);
-+        }
-+        err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_10,0);
-+        if (err != STMPE2401_OK)
-+        {
-+               printk("Couldn't set STMPE GPIO10\n");
-+        }
-+        mdelay(200);
++      /* Reset ethernet controller */
++      nomadik_epio_write_aux_gpo1(nomadik_epio_read_aux_gpo1() &
++                                  (unsigned long)(~LAN_RST));
++      /* Enabling ethernet interrupts */
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)(~GPIO106_LAN_IT));
++      /*type need to be set in case of shared irq */
++      set_irq_type(IRQNO_GPIO(SMC91111_IRQ), SA_TRIGGER_RISING);
 +}
 +
 +static struct resource smc91x_resources[] = {
@@ -18017,332 +19211,367 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +};
 +#endif
 +
-+#define NMDK_DEBUG    BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++/*
++ * touchpanel
++ */
++#ifdef CONFIG_TOUCHSCREEN_NOMADIK
++#ifndef TOUCHP_DEBUG
++#define TOUCHP_DEBUG 0                /* default debug messages are disabled */
++#endif                                /*  */
 +
-+#ifdef CONFIG_STMPE_NOMADIK
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#define NMDK_DEBUG    TOUCHP_DEBUG    /* enables/disables debug msgs */
++#define NMDK_DEBUG_PFX  TPDRVNAME     /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+/*initialize the pins which are connected thro stmpe devices
-+ *This is not stmpe platform init function - FIXME
++/**
++ * nomadik_tp_ssp_board_init - board specific ssp data path setup
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the SSP for touchpanel operation
++ * Selects the SSP source for the EXP_SSP and SPI3V interfaces
 + */
-+static int nomadik_stmpe_plat_init(void)
++int nomadik_tp_ssp_board_init(struct t_adsContext *p_adsContext)
 +{
-+      int err,ret;
-+
-+       /* Access the STMPE2401, and make the signal EXP1_GPIO8 as high
-+         * for NAND flash write protet off
-+         */
-+        err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_8,STMPE2401_PRIMARY_FUNCTION);
-+        if (err != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE1 %d as  primary function\n",EGPIO_PIN_8);
-+        err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_8,STMPE2401_GPIO_OUT);
-+        if (err != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_8);
-+        err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_8, 1);
-+        if (err != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE GPIO8\n");
-+
-+      /*reset the WVGA display which is conected thro port expander 1*/
-+      err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION);
-+        if (err != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_5);
-+        err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT );
-+        if (err != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_5);
-+        err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1);
-+        if (err != STMPE2401_OK)
-+                nmdk_error("Couldn't set STMPE GPIO5\n");
-+
-+#ifdef CONFIG_SMC91X
-+      nomadik_smc91x_irq_init();
-+        udelay(1000);           /*1ms*/
-+#endif
-+      nomadik_st2590_init();
-+      
-+      return 0;
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_ssp_conf(EXP_SSP);
++      return (0);
 +}
 +
-+/*not yet implemented*/
-+int nomadik_stmpe_plat_exit(void)
++/**
++ * nomadik_tp_gpio_board_init - board specific gpio initialization
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine initializes the GPIO for touchpanel operation
++ * RETURN: GPIO nmdk_error code
++ * SSP is interfaced with ADS7843 through CPLD hence respective
++ * interface need to be enabled for NDK10
++ * BIOS/TCHSCR: BIOS EEPROM and Touch Screen have the same SPI
++ * chip select, this bit allows the selection between the two
++ * peripherals. setting this bit Touch screen selected
++ */
++gpio_error nomadik_tp_gpio_board_init(struct t_adsContext * p_adsContext)
 +{
-+      return 0;
-+}
++      gpio_error status = GPIO_OK;
 +
-+static struct resource stmpe_resources[] = {
-+        [0] = {
-+               .name = "STMPE",
-+               .start = IRQNO_GPIO(76),
-+               .end  = IRQNO_GPIO(76),
-+               .flags = IORESOURCE_IRQ,
-+               },
-+      [1] = {
-+               .name = "STMPE",
-+               .start = IRQNO_GPIO(78),
-+               .end  = IRQNO_GPIO(78),
-+               .flags = IORESOURCE_IRQ,
-+               },
-+};
-+static struct resource nomadik_udc_resources[] = {
-+        [0] = {
-+                .name   = "udc-mem",
-+                .start  = IO_ADDRESS(NOMADIK_USB_BASE),
-+                .end    = (IO_ADDRESS(NOMADIK_USB_BASE) + SZ_1M -1),
-+                .flags  =  IORESOURCE_MEM,
-+        },
++      nmdk_dbg_ftrace();
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() | BIOS_TCHSCR);
 +
-+        [1] = {
-+                .name   = "udc-irq",
-+                .start  = INT_USBOTG,
-+                .end    = INT_USBOTG,
-+                .flags  = IORESOURCE_IRQ,
-+        },
-+};
-+static struct platform_device nomadik_udc_device = {
-+        .name = "NOMADIK USBDEV",
-+        .id = 0,
-+        .num_resources = ARRAY_SIZE(nomadik_udc_resources),
-+        .resource = nomadik_udc_resources,
-+};
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++      {
++      gpio_config config_cspin;
++      /* Set SPICSn_TCHSCR pin configuration */
++      config_cspin.mode = GPIO_MODE_SOFTWARE;
++      config_cspin.direction = GPIO_DIR_OUTPUT;
++      config_cspin.debounce = GPIO_DEBOUNCE_DISABLE;
++      config_cspin.dev_name = "Touchp";
++      status = nomadik_gpio_setpinconfig(TOUCHP_CS0, &config_cspin);
++      if (status) {
++              nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
++                         TOUCHP_CS0, status);
++              goto err_TOUCHP_CS0;
++      }
 +
-+static struct nomadik_stmpe_platform_data nomadik_stmpe_data = {
-+      .init = nomadik_stmpe_plat_init,
-+      .exit = nomadik_stmpe_plat_exit,
-+};
++      status = nomadik_gpio_setpinconfig(TOUCHP_CS1, &config_cspin);
++      if (status) {
++              nmdk_error("GPIO %d configuration failure (nmdk_error:%d)",
++                         TOUCHP_CS1, status);
++              goto err_TOUCHP_CS1;
++      }
++      }
++#endif
++      /* Set PENIRQ pin configuration */
++      set_irq_type(p_adsContext->irq, SA_TRIGGER_FALLING);
 +
-+static struct platform_device nomadik_stmpe_device = {
-+      .name = "NOMADIK-STMPE",
-+      .id = 0,
-+      .dev = {
-+                .platform_data = &nomadik_stmpe_data,
-+                },
-+      .num_resources = ARRAY_SIZE(stmpe_resources),
-+      .resource = stmpe_resources,
-+};
++      return status;
 +
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++      err_TOUCHP_CS1:
++      nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
++      err_TOUCHP_CS0:
++      return status;
 +#endif
++}
 +
-+#undef NMDK_DEBUG     /*board*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+
-+/*
-+ * touchpanel
++/**
++ * nomadik_tp_gpio_board_exit - board specific gpio exit
++ * @p_adsContext: device data structure pointer
++ *
++ * This routine performs revers action of init
 + */
-+
-+static int nomadik_tsc2003_init_irq (void (*callback)(void* parameter), void * p)
++gpio_error nomadik_tp_gpio_board_exit(struct t_adsContext * p_adsContext)
 +{
-+      t_STMPE2401_error err;
-+      DEBUG_TS(("nomadik_tsc2003_init_irq\n"));
-+      err = STMPE2401_SetGpioAltFunction( STMPE1 , EGPIO_PIN_6 , STMPE2401_PRIMARY_FUNCTION );
-+      err |= STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_6,STMPE2401_GPIO_IN );
-+      err |= STMPE2401_SetGpioPull(STMPE1,EGPIO_PIN_6,STMPE2401_FLOATING );
-+      
-+      err = STMPE2401_Install_Callback(STMPE1, STMPE2401_GPIO_IRQ(6), callback,(void*)p);
-+      if (err != STMPE2401_OK)        {
-+              printk("Couldn't setup touch screen callback\n");
-+      }
-+      err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_FALL_EDGE);
-+      if (err != STMPE2401_OK)        {
-+              printk("Couldn't set touch screen edge detection\n");
-+      }
-+      err = STMPE2401_ClearGpioEdgeStatus(STMPE1,(0x1<<EGPIO_PIN_6));
-+      if (err != STMPE2401_OK)        {
-+              printk("Couldn't clear touch screen edge status \n");
-+      }       
-+      /*err = STMPE2401_InterruptAbilitation(STMPE1, STMPE2401_ENABLE_INTERRUPT );
-+      if (err != STMPE2401_OK)        {
-+              printk("Couldn't enable touch screen callback\n");
-+      }*/
-+      return (err != STMPE2401_OK);
++      gpio_error status = GPIO_OK;
++
++      nmdk_dbg_ftrace();
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++      status |= nomadik_gpio_resetpinconfig(TOUCHP_CS0, "Touchp");
++      status |= nomadik_gpio_resetpinconfig(TOUCHP_CS1, "Touchp");
++#endif
++      nomadik_epio_write_cob_ctl(nomadik_epio_read_cob_ctl() & (u16)~BIOS_TCHSCR);
++      return status;
 +}
 +
-+static int nomadik_tsc2003_exit_irq(void)
++/**
++ * nomadik_tp_pen_down - returns pen touch status
++ */
++t_bool nomadik_tp_pen_down(struct t_adsContext * p_adsContext)
 +{
-+      t_STMPE2401_error err;
-+      DEBUG_TS(("nomadik_tsc2003_exit_irq\n"));
-+      err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
-+      err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_NO_EDGE);
-+      return (err != STMPE2401_OK);
++      gpio_data pen_down;
++
++      nmdk_dbg_ftrace();
++      nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(p_adsContext->irq), &pen_down);
++      nmdk_dbg2("pen_down = 0x%d (pin%d)",
++               pen_down, GPIO_PIN_FOR_IRQ(p_adsContext->irq));
++      return ((t_bool) pen_down);
 +}
 +
-+static int nomadik_tsc2003_irqen(void)
++/**
++ * nomadik_tp_pen_down_irq_enable - enables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_enable(struct t_adsContext *p_adsContext)
 +{
-+      t_STMPE2401_error err;
-+      //DEBUG_TS(("nomadik_tsc2003_irqen\n"));
-+      err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_ENABLE_INTERRUPT );
-+      return (err != STMPE2401_OK);
++      nmdk_dbg_ftrace();
++      enable_irq(p_adsContext->irq);
 +}
 +
-+static int nomadik_tsc2003_irqdis(void)
++/**
++ * nomadik_tp_pen_down_irq_disable - disables pen interrupt
++ */
++void nomadik_tp_pen_down_irq_disable(struct t_adsContext *p_adsContext)
 +{
-+      t_STMPE2401_error err;
-+      //DEBUG_TS(("nomadik_tsc2003_irqdis\n"));
-+      err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
-+      return (err != STMPE2401_OK);
++      nmdk_dbg_ftrace();
++      disable_irq(p_adsContext->irq);
 +}
 +
-+static int nomadik_tsc2003_irq_ack(void)
++/**
++ * nomadik_tp_spi_cs_disable - disables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to disable chip select
++ */
++void nomadik_tp_spi_cs_disable(void)
 +{
-+      u16 irqSource = 0x100;
-+      u32 irqGpioSource = 0x40;
-+      t_STMPE2401_error err;
-+      //DEBUG_TS(("nomadik_tsc2003_irq_ack\n"));
-+      err = STMPE2401_Acknowledge(STMPE1,irqSource,irqGpioSource);
-+      return (err != STMPE2401_OK);
++      nmdk_dbg_ftrace();
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++      nomadik_gpio_writepin(TOUCHP_CS0, 1, "Touchp");
++      nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
++#endif
 +}
 +
-+static int nomadik_tsc2003_read_pin_val(u8   * Value)
++/**
++ * nomadik_tp_spi_cs_enaable - enables the chip select for ads7843
++ *
++ * sets GPIOS to to provid inputs to CPLD to enable chip select
++ */
++void nomadik_tp_spi_cs_enable(void)
 +{
-+      t_STMPE2401_error   err;
-+      
-+      err = STMPE2401_GetGpioVal(STMPE1 , EGPIO_PIN_6, Value);
-+      return (err != STMPE2401_OK);
++      nmdk_dbg_ftrace();
++#if defined TOUCHP_CS0 && defined TOUCHP_CS1
++      nomadik_gpio_writepin(TOUCHP_CS0, 0, "Touchp");
++      nomadik_gpio_writepin(TOUCHP_CS1, 1, "Touchp");
++#endif
 +}
-+static struct touchp_tsc2003_device touchp_tsc2003_board = {
-+      .irq_init = nomadik_tsc2003_init_irq,
-+      .irq_exit = nomadik_tsc2003_exit_irq,
-+      .pirq_en  = nomadik_tsc2003_irqen,
-+      .pirq_dis = nomadik_tsc2003_irqdis,
-+      .pirq_ack = nomadik_tsc2003_irq_ack,
-+      .pirq_read_val = nomadik_tsc2003_read_pin_val,
++
++static struct touchp_device touchp_board = {
++      .ssp_init = nomadik_tp_ssp_board_init,
++      .gpio_init = nomadik_tp_gpio_board_init,
++      .gpio_exit = nomadik_tp_gpio_board_exit,
++      .pdown = nomadik_tp_pen_down,
++      .pirq_en = nomadik_tp_pen_down_irq_enable,
++      .pirq_dis = nomadik_tp_pen_down_irq_disable,
++      .cs_en = nomadik_tp_spi_cs_disable,
++      .cs_dis = nomadik_tp_spi_cs_enable,
++      .samples = 100, /*samples per second*/
++      .pollsamples = 10, /*polling per second*/
 +};
 +
-+static struct platform_device touchp_tsc2003_device = {
-+      //.name = "nmdk-tp",
-+      .name = "tsc2003",
++static struct resource touchp_resources[] = {
++      [0] = {
++             .start = IRQNO_GPIO(TOUCHP_IRQ),
++             .end = IRQNO_GPIO(TOUCHP_IRQ),
++             .flags = IORESOURCE_IRQ,
++             },
++};
++
++static struct platform_device touchp_device = {
++      .name = "nmdk-tp",
 +      .id = 0,
 +      .dev = {
-+              .platform_data = &touchp_tsc2003_board,
++              .platform_data = &touchp_board,
 +              },
-+      .num_resources = 0,
-+      .resource = NULL,
++      .num_resources = ARRAY_SIZE(touchp_resources),
++      .resource = touchp_resources,
 +};
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#endif
 +
-+/*
-+ * keypad
-+ */
++#ifdef CONFIG_KEYPAD_NOMADIK
++#define KEYPAD_NAME           "KEYPAD"
++#ifndef KEYPAD_DEBUG
++#define KEYPAD_DEBUG 0
++#endif
 +
-+#define NMDK_DEBUG      BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  BOARD_NAME      /* msg header represents this module */
-+#define NMDK_DBG        KERN_ERR        /* message level */
++#define NMDK_DEBUG    KEYPAD_DEBUG    /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  KEYPAD_NAME   /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+static void kp_callback (void * parameter)
++/*key scan constants*/
++#define KSCAN_ALLROWS   0x00FF
++#define KSCAN_ALLCOLS   0xFF00
++#define KSCAN_ROW0      0x0001
++#define KSCAN_ROW1      0x0002
++#define KSCAN_ROW2      0x0004
++#define KSCAN_ROW3      0x0008
++#define KSCAN_ROW4      0x0010
++#define KSCAN_ROW5      0x0020
++#define KSCAN_ROW6      0x0040
++#define KSCAN_ROW7      0x0080
++#define KSCAN_COL0      0x0100
++#define KSCAN_COL1      0x0200
++#define KSCAN_COL2      0x0400
++#define KSCAN_COL3      0x0800
++#define KSCAN_COL4      0x1000
++#define KSCAN_COL5      0x2000
++#define KSCAN_COL6      0x4000
++#define KSCAN_COL7      0x8000
++
++unsigned short const keychkval_set[] = {
++      (unsigned short)~KSCAN_COL0 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL1 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL2 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL3 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL4 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL5 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL6 | KSCAN_ALLROWS,
++      (unsigned short)~KSCAN_COL7 | KSCAN_ALLROWS,
++};
++
++unsigned short const keychkval_read[] = {
++      KSCAN_ROW0, KSCAN_ROW1, KSCAN_ROW2, KSCAN_ROW3, KSCAN_ROW4, KSCAN_ROW5,
++      KSCAN_ROW6, KSCAN_ROW7,
++};
++
++/**
++ * nomadik_kp_ghostkey_detect - ghost key detect function
++ * @rowval: row in which ghost key to be detected
++ *
++ * when more than one key is pressed in the same row the keypad logic cannot
++ * detect proper key press, the logic here detects multiple keypress on a
++ * single row and returns error
++ */
++int nomadik_kp_ghostkey_detect(short rowval)
 +{
-+    t_STMPE2401_error err;
-+    t_STMPE2401_key_status keys;
-+    struct keypad_t * kp = (struct keypad_t *)parameter;
-+    u8 kcode,i;
++      int row;
++      int ghcnt = 0;
 +
-+    /*DEBUG_KP(("kp_callback\n"));*/
-+    err = STMPE2401_Keypressed(STMPE0, &keys);
-+    if(keys.buttonPressed)
-+    {
-+        for(i=0;i<keys.buttonPressed;i++)
-+        {
-+            kcode = kp->board->kcode_tbl[(keys.button[i]&0x3)*4 + ((keys.button[i]>>3)&0x3)];
-+            input_report_key(kp->inp_dev,kcode, 1);
-+        }
-+    }
-+    if(keys.buttonReleased)
-+    {
-+        for(i=0;i<keys.buttonReleased;i++)
-+        {
-+            kcode = kp->board->kcode_tbl[(keys.released[i]&0x3)*4 + ((keys.released[i]>>3)&0x3)];
-+            input_report_key(kp->inp_dev,kcode, 0);
-+        }
-+    }
++      for (row = 0; row < MAX_KPROW; row++) {
++              if (0 == (rowval & keychkval_read[row])) {
++                      /*keypr detected */
++                      ghcnt++;
++              }
++              if (1 < ghcnt)
++                      /*return error if more than one keys are pressed in a row */
++                      return (-1);
++      }
++      return (0);
 +}
 +
 +/**
-+ * nomadik_kp_init_key_hardware -  keypad hardware initialization
++ * nomadik_kp_key_scan - keypad scan and report event function
 + *
-+ ****************************************************************************
++ * Scans through keypad hardware and updates the key status for key press
++ * or key release event to upper layer
 + */
-+int nomadik_kp_init_key_hardware(struct keypad_t *kp)
++int nomadik_kp_key_scan(struct keypad_t *kp)
 +{
-+      t_STMPE2401_error err;
-+      t_STMPE2401_key_config kpconfig;
++      short val;
++      u8 row, col;
++      int keyp_cnt = 0;
++      u8 *p_kcode;
 +
-+      DEBUG_KP(("nomadik_kp_init_key_hardware\n"));
 +      nmdk_dbg_ftrace();
-+      /*setup Columns GPIOs (inputs)*/
-+      kpconfig.columns  = 0xF;                //4 columns
-+      kpconfig.rows     = 0xF;                //4 rows
-+      kpconfig.nCycles  = 8;                  //number of cycles for key data updating
-+      kpconfig.debounce = 64;                 //de-bounce time 64 ms
-+      kpconfig.scan     = STMPE2401_SCAN_OFF;
-+      err =  STMPE2401_Keypad_init(STMPE0, kpconfig);
-+      if (err != STMPE2401_OK)
-+      {
-+              printk("Couldn't setup keypad configuration\n");
-+      }
-+      if (!kp->mode)
-+      {       /* true if interrupt mode operation */
-+              DEBUG_KP(("\tsetting up keypad interrupt stuff\n"));
-+              err = STMPE2401_Install_Callback(STMPE0, STMPE2401_KEYPAD_IRQ,kp_callback,(void*)kp);
-+              if (err != STMPE2401_OK)
-+              {
-+                      printk("Couldn't setup keypad callback\n");
-+              }
-+              err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
-+              if (err != STMPE2401_OK)
-+              {
-+                      printk("Couldn't abilitate the keypad source interrupt\n");
-+              }
-+              /*err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_ENABLE_INTERRUPT );
-+              if (err != STMPE2401_OK)
-+              {
-+                      printk("Couldn't enable the keypad source interrupt\n");
-+              }*/
-+      }
-+      err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_ON);
-+      if (err != STMPE2401_OK)
-+      {
-+              printk("Couldn't enable keypad scan\n");
++      for (col = 0; col < MAX_KPCOL; col++) {
++              p_kcode = kp->board->kcode_tbl + col;
++              nomadik_epio_write_keypad(keychkval_set[col]);
++              val = nomadik_epio_read_keypad();
++              val &= KSCAN_ALLROWS;
++              if (0 == nomadik_kp_ghostkey_detect(val)) {
++                      for (row = 0; row < MAX_KPROW; row++) {
++                              if (0 == (val & keychkval_read[row])) { /*keypr detected */
++                                      keyp_cnt++;
++                                      if (kp->key_state[row][col] ==
++                                          KEYPAD_STATE_DEFAULT) {
++                                              input_report_key(kp->inp_dev,
++                                                               *p_kcode, 1);
++                                              nmdk_dbg("P:%d ", *p_kcode);
++                                              kp->key_state[row][col] =
++                                                  KEYPAD_STATE_PRESSACK;
++                                      }
++                              } else {        /*key not pressed detected */
++                                      if (kp->key_state[row][col] ==
++                                          KEYPAD_STATE_PRESSACK) {
++                                              input_report_key(kp->inp_dev,
++                                                               *p_kcode, 0);
++                                              nmdk_dbg("R:%d ", *p_kcode);
++                                              kp->key_state[row][col] =
++                                                  KEYPAD_STATE_DEFAULT;
++                                      }
++                              }
++                              p_kcode += MAX_KPROW;
++                      }
++              } else
++                      keyp_cnt += 0x100;      /* to flag ghost keypress detection */
 +      }
-+      return 0;
++      /* pull down all rows to detect any keypress */
++      nomadik_epio_write_keypad(KSCAN_ALLCOLS & KSCAN_ALLROWS);
++      return (keyp_cnt);
 +}
 +
 +/**
-+ * nomadik_kp_exit_key_hardware- keypad hardware exit function
++ * nomadik_kp_init_key_hardware -  keypad hardware initialization
 + *
++ * Initializes the keypad hardware specific parameters.
++ * This function will be called by nomadik_keypad_init function during init
++ * Initialize keypad interrupt handler for interrupt mode operation if enabled
++ * Initialize Keyscan matrix
++ ****************************************************************************
 + */
-+int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
++int nomadik_kp_init_key_hardware(struct keypad_t *kp)
 +{
-+      t_STMPE2401_error err;
-+
-+      DEBUG_KP(("nomadik_kp_exit_key_hardware\n"));
-+      err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_OFF);
-+      if (err != STMPE2401_OK)
-+      {
-+              printk("Couldn't enable keypad scan\n");
-+      }
-+      if (!kp->mode)
-+      {       /* true if interrupt mode operation */
-+              err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_DISABLE_INTERRUPT );
-+              if (err != STMPE2401_OK)
-+              {
-+                      printk("Couldn't disable keypad callback\n");
-+              }
-+              err = STMPE2401_Remove_Callback(STMPE0, STMPE2401_KEYPAD_IRQ);
-+              if (err != STMPE2401_OK)
-+              {
-+                      printk("Couldn't remove keypad callback\n");
-+              }
-+      }
 +      nmdk_dbg_ftrace();
++      nomadik_epio_write_keypad(KSCAN_ALLCOLS);
++      if ((KSCAN_ALLCOLS | KSCAN_ALLROWS) != (u16) nomadik_epio_read_keypad()) {
++              /*check wrong key */
++              nmdk_error("Keypad H/w error....");
++              return (-1);
++      }
++      if (!kp->mode) {        /* true if interrupt mode operation */
++              /* pull down all rows to detect any keypress */
++              nomadik_epio_write_keypad(KSCAN_ALLROWS);
++              set_irq_type(kp->irq, SA_TRIGGER_FALLING);
++              /*
++               * TBD logic should be added to detect proper switch settings
++               * on a board to detect valid interrupt
++               */
++      }
 +      return 0;
 +}
 +
 +/**
-+ * nomadik_kp_key_scan - keypad scan and report event function
++ * nomadik_kp_exit_key_hardware- keypad hardware exit function
 + *
++ * This function will be called by nomadik_keypad_exit function during module
++ * exit, frees keypad interrupt if enabled
 + */
-+int nomadik_kp_key_scan(struct keypad_t *kp)
++int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
 +{
-+      DEBUG_KP(("nomadik_kp_key_scan\n"));
-+      kp_callback ((void *) kp);
++      nmdk_dbg_ftrace();
++      /* pull up all columns so that interrupt will not be raised*/
++      nomadik_epio_write_keypad(KSCAN_ALLCOLS |KSCAN_ALLCOLS);
 +      return 0;
 +}
 +
@@ -18353,10 +19582,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 + */
 +int nomadik_kp_key_irqen(struct keypad_t *kp)
 +{
-+      t_STMPE2401_error err;
-+      DEBUG_KP(("nomadik_kp_key_irqen\n"));
-+      err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
-+      return (err != STMPE2401_OK);
++      /*enable_irq(kp->irq);*/
++      return 0;
 +}
 +
 +/**
@@ -18366,21 +19593,26 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 + */
 +int nomadik_kp_key_irqdis(struct keypad_t *kp)
 +{
-+      t_STMPE2401_error err;
-+      DEBUG_KP(("nomadik_kp_key_irqdis\n"));
-+      err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_DISABLE_INTERRUPT );
-+      return (err != STMPE2401_OK);
++      /*disable_irq(kp->irq);*/
++      return 0;
 +}
 +
 +/*
 + * Initializes the key scan table (lookup table) as per pre-defined the scan
 + * codes to be passed to upper layer with respective key codes
 + */
-+u8 const kpd_lookup_tbl[4*4] = {
-+      KEY_RESERVED, KEY_RESERVED, KEY_VOLUMEDOWN, KEY_VOLUMEUP,
-+      KEY_F1, KEY_F8, KEY_F3, KEY_F4,
-+      KEY_F5, KEY_F6, KEY_F7, KEY_ENTER,
-+      KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN
++u8 const kpd_lookup_tbl[MAX_KPROW][MAX_KPROW] = {
++      {KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_SPACE},
++      {KEY_GRAVE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7},
++      {KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_INSERT,
++       KEY_HOME},
++      {KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U},
++      {KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH,
++       KEY_DELETE, KEY_END},
++      {KEY_CAPSLOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J},
++      {KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, KEY_DOT,
++       KEY_COMMA, KEY_SLASH},
++      {KEY_LEFTSHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M}
 +};
 +
 +static struct keypad_device keypad_board = {
@@ -18390,19 +19622,17 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      .irqen = nomadik_kp_key_irqen,
 +      .irqdis = nomadik_kp_key_irqdis,
 +      .kcode_tbl = (u8 *) kpd_lookup_tbl,
-+      .krow = 4,
-+      .kcol = 4,
++      .krow = 8,
++      .kcol = 8,
 +};
 +
-+#undef NMDK_DEBUG     /*board*/
-+#undef NMDK_DEBUG_PFX
-+#undef NMDK_DBG
-+
-+
-+/*static struct resource keypad_resources[] = {
++static struct resource keypad_resources[] = {
 +      [0] = {
++             .start = IRQNO_GPIO(KEYPAD_IRQ),
++             .end = IRQNO_GPIO(KEYPAD_IRQ),
++             .flags = IORESOURCE_IRQ,
 +             },
-+};*/
++};
 +
 +static struct platform_device keypad_device = {
 +      .name = "nmdk-kp",
@@ -18410,29 +19640,70 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      .dev = {
 +              .platform_data = &keypad_board,
 +              },
-+      .num_resources = 0,
-+      .resource = NULL,
++      .num_resources = ARRAY_SIZE(keypad_resources),
++      .resource = keypad_resources,
++};
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#endif
++
++#ifdef CONFIG_CPLD_I2C
++#define EPIO_NAME             "EPIO"
++#ifndef EPIO_DEBUG
++#define EPIO_DEBUG 0
++#endif
++
++#define NMDK_DEBUG    EPIO_DEBUG      /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  EPIO_NAME     /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++static void nomadik_epio_plat_init(void)
++{
++      nmdk_dbg_ftrace();
++      /* Initializing CPLD registers for initial values */
++      nomadik_epio_write_cob_ctl(0x0030);     /* reset value */
++      nomadik_epio_write_keypad(0xff00);      /* COL7:0 set to high Z */
++      nomadik_epio_write_msp_conf(0x794);     /* reset value */
++      nomadik_epio_write_uart_conf(0x0694);   /* UART1 enabled for rs232 port*/
++      nomadik_epio_write_ssp_conf(0x0124);    /* reset value */
++      nomadik_epio_write_aux_gpo1(0x2880);    /* reset value */
++      nomadik_epio_write_aux_gpo2(0x018a);    /* reset value */
++#ifdef CONFIG_SMC91X
++      nomadik_smc91x_irq_init();
++#endif
++}
++
++static struct platform_device epio_device = {
++      .name = "NOMADIK-EPIO",
++      .id = 0,
++      .dev = {
++              .platform_data = nomadik_epio_plat_init,
++              },
 +};
++#undef NMDK_DEBUG
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++#endif /*CONFIG_CPLD_I2C*/
 +
 +static struct platform_device *nmdk_platform_devices[] __initdata = {
 +      &fsmc_device,
-+      &nomadik_udc_device, 
-+#ifdef CONFIG_MTD
-+#ifdef CONFIG_MTD_NAND
-+      &nomadik_nand_flash,
-+#endif
-+#ifdef CONFIG_MTD_ONENAND
-+      &nomadik_1nand_flash,
++#ifdef CONFIG_CPLD_I2C
++      &epio_device,
 +#endif
++#ifdef CONFIG_KEYPAD_NOMADIK
++      &keypad_device,
 +#endif
 +#ifdef CONFIG_SMC91X
 +      &smc91x_device,
 +#endif
-+#ifdef CONFIG_STMPE_NOMADIK
-+      &nomadik_stmpe_device,
++#ifdef CONFIG_TOUCHSCREEN_NOMADIK
++      &touchp_device,
++#endif
++#ifdef CONFIG_MTD
++      &nomadik_nand_flash,
++      &nomadik_nor_flash,
 +#endif
-+      &keypad_device,
-+      &touchp_tsc2003_device,
 +};
 +
 +void add_nmdk_platform_devices(void)
@@ -18440,9 +19711,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6
 +      platform_add_devices(nmdk_platform_devices,
 +                           ARRAY_SIZE(nmdk_platform_devices));
 +}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig
---- linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig
 @@ -0,0 +1,36 @@
 +if NOMADIK_NHK15
 +
@@ -18450,7 +19720,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig ../new/linux-2.6.2
 +
 +#target name configuration for this target
 +config NOMADIK_TARGET
-+      string 
++      string
 +      default NHK15
 +
 +# nomadik soc chip name configuration for this target
@@ -18480,101 +19750,1112 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_Kconfig ../new/linux-2.6.2
 +      default y
 +
 +endif
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arch/arm/mach-nomadik/normal.S
---- linux-2.6.20/arch/arm/mach-nomadik/normal.S        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/normal.S 2008-07-28 15:20:42.000000000 +0530
-@@ -0,0 +1,199 @@
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c
+@@ -0,0 +1,1009 @@
 +/*
-+ * arch/arm/mach-nomadik/normal.S
++ *  linux/arch/arm/mach-nomadik/nhk15_devices.c
 + *
-+ * Copyright 2007, STMicroelectronics
++ *  Copyright (C) STMicroelectronics
 + *
 + * 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
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
 + *
++ *  NHK15 board specifc driver definition
 + */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/amba/bus.h>
++#include <linux/spi/spi.h>
++#include <linux/amba/kmi.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/param.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/kpd.h>
++#include <asm/arch/touchp.h>
++#include <asm/arch/fsmc.h>
++#ifdef CONFIG_MTD
++#include <linux/mtd/nand.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/concat.h>
++#include <asm/arch/nandflash.h>
++#include <asm/mach/flash.h>
++#endif
++#include <asm/arch/debug.h>
++#include <asm/arch/pexp.h>
++#include <asm/arch/touchp2003.h>
 +
-+#define NORMAL_DEBUG 0
-+#define mpmc_base                     0xF0110000
-+#define src_base                      0xf01e0000
-+#define pmu_base                      0xf01e9000
-+#define uart_base                     0xcc85e000
-+
++#define DEBUG_KP(x) printk x
++#define DEBUG_TS(x) printk x
 +
++#define BOARD_NAME            CONFIG_NOMADIK_PLATFORM
++#ifndef BOARD_DEBUG
++#define BOARD_DEBUG 0
++#endif
 +
++#define NMDK_DEBUG    BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
 +
-+.align 5
-+.globl nomadik_normal_mode
++#define INT_USBOTG      23
++#define  NOMADIK_USB_BASE 0x10170000
++#ifdef CONFIG_SMC91X
++static void nomadik_smc91x_irq_init(void);
++#endif
 +
-+nomadik_normal_mode:
++/**
++ * nomadik_clcd_board_enable - enables board specific clcd prameters
++ *
++ * Settings to enable backlight and pannel voltage regulator for NDK15
++ */
++void nomadik_clcd_enable(void *fbp)
++{
++      /* not implimented for this board */
++}
 +
++/**
++ * nomadik_clcd_board_disable - disables board specific clcd prameters
++ *
++ * Settings to disable backlight and pannel voltage regulator for NDK10
++ */
++void nomadik_clcd_disable(void *fbp)
++{
++      /* not implimented for this board */
++}
 +
-+      stmfd sp!,{r0-r12,lr}
++/*
++ * Settings to configure MMC controller for NDK10
++ */
++int nomadik_mmc_configure(struct amba_device *dev)
++{
++      /* not implimented for this board */
++      int ret;
++      char x = val_volt;
++       ret = nomadik_i2c_write_register(I2C_TOUAREG_CLIENT, &x, 0x11, 1);
++        if (ret) {
++                nmdk_error("Error in writing value to touareg register");
 +
-+      ldr r10,=mpmc_base
-+      ldr r11,=src_base       
-+      ldr r12,=pmu_base
-+      ldr r9,=uart_base
++        }
 +
++        ret = nomadik_gpio_altfuncenable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++        if (ret) {
++                nmdk_error("Error in gpio Altfunction enable");
 +
-+      ldr r2, [r11]
-+      
-+#if NORMAL_DEBUG 
-+      mov r0, #97
-+      str r0, [r9]
-+#endif
++        }
++        return ret;
 +
-+      /*  Prefetch certain instructions in the cache.  */
-+    adr r4, cache_prefetch_start
-+      adr r5, cache_prefetch_end
-+      mvn r1,#0x1F
-+      ands r4,r1,r4
-+pfetch:
-+      mcr p15, 0, r4, c7, c13,1
-+      cmp r4,r5
-+      addls r4, r4, #0x20
-+      bls pfetch
++      return 0;
++}
 +
-+.align 5
-+              
-+cache_prefetch_start:
-+      ldr r10, =mpmc_base
++void nomadik_mmc_restore_default(struct amba_device *dev)
++{
++      /* not implimented for this board */
++      nomadik_gpio_altfuncdisable(GPIO_ALT_SD_CARD, dev->dev.bus_id);
++}
 +
-+poll_status:
-+      /* Check sdram is not busy */
-+      ldr r1,[r10, #0x4]
-+      ands r1,r1,#0x1
-+      cmp r1,#0
-+      bne poll_status
++static int fsmc_platform_init(void)
++{
++      unsigned char __iomem *fsmc_base;
 +
-+      /* Put SDRAM in self-refresh mode*/     
-+      ldr r1,[r10, #0x20]
-+      bic r1,r1,#0x1
-+      orr r1,r1,#0x04
-+      str r1,[r10, #0x20]
++      nmdk_dbg_ftrace();
++      /*Following Settings done for NAND flash protect off */
++      fsmc_base = (unsigned char *)IO_ADDRESS(NOMADIK_FSMC_BASE);
 +
++      /* for NOR accesss */
++      /* Initialize the fsmc bank 0 */
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = 0x10db;
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = 0x03333333;
++      /* Initialize the fsmc bank 1 used for ethernet controller */
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR1)) = 0x305B;
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BTR1)) = 0x033F33;    /*old 00000702 */
 +
-+      /*Wait for SDRAM to go in self-refresh*/
-+wait_self_refresh:
-+      ldr r1,[r10,#0x4]
-+      and r1,r1,#0x4
-+      cmp r1,#0x0
-+      beq wait_self_refresh
++      *((volatile u32 *)(NOMADIK_FSMC_VA + FSMC_BCR0)) |= 0x80;
++      /* Above Settings done for NAND flash protect off */
++      return 0;
++}
 +
-+      /**
-+       * Stop the DLL, leave SDMC on
-+       Moving 0xff9 into sdmc control register for stopping and adding dll 
++static struct resource fsmc_resources[] = {
++      [0] = {
++             .start = NOMADIK_FSMC_BASE,
++             .end = NOMADIK_FSMC_BASE + SZ_4K - 1,
++             .flags = IORESOURCE_MEM,
++             },
++};
++
++struct fsmc_platform_data fsmc_data = {
++      .init = fsmc_platform_init,
++};
++
++static struct platform_device fsmc_device = {
++      .name = "NOMADIK-FSMC",
++      .id = 0,
++      .dev = {
++              .platform_data = &fsmc_data,
++              },
++      .num_resources = ARRAY_SIZE(fsmc_resources),
++      .resource = fsmc_resources,
++};
++
++#ifdef CONFIG_MTD
++#ifdef CONFIG_MTD_NAND
++static struct resource nandflash_resources[] = {
++      [0] = {
++             .name = "cmem_address",
++             .start = NAND_B0_CMEM_ADDR,
++             .end = (NAND_B0_CMEM_ADDR + SZ_1K - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [1] = {
++             .name = "cmem_command",
++             .start = NAND_B0_CMEM_CMD,
++             .end = (NAND_B0_CMEM_CMD + SZ_1K - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [2] = {
++             .name = "cmem_data",
++             .start = NAND_B0_CMEM_DATA,
++             .end = (NAND_B0_CMEM_DATA + SZ_1K - 1),
++             .flags = IORESOURCE_MEM,
++             },
++};
++
++/*NHK15 is 8-bit NAND*/
++#define NAND_STM_LP_OPTIONS \
++              ( NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING | NAND_NO_READRDY | NAND_NO_AUTOINCR)
++
++int nomadik_nandflash_exit(void)
++{
++      return 0;
++
++}
++int nomadik_nandflash_init(void)
++{
++#if 1
++      /*
++       * FSMC initialization
++       * 0x0000000e => PCR0
++       * 0x000d0a00 => PMEM0
++       * 0x00100a00 => PATT0
++       */
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PCR0)) =
++              0x0000000E;             /* NHK15 is  8-bit NAND */
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PMEM0)) =
++          DEFAULT_PMEM0_VALUE;
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_PATT0)) =
++          DEFAULT_PATT0_VALUE;
++#endif
++      return 0;
++}
++
++const unsigned char lookup_t[256] = {
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
++      0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
++};
++
++int nmdknand_compute_ecc512(struct mtd_info *mtd, const u_char * data,
++                          u_char * ecc)
++{
++      unsigned int sumCol = 0;
++      unsigned int datum, temp;
++      unsigned int glob_parity;
++      const int ecc_n_bytes = 512;
++      int i;
++
++      unsigned int parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
++      unsigned int parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 =
++          0, parit32_1 = 0, parit32_2 = 0;
++      unsigned int parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 =
++          0, parit256_1 = 0, parit256_2 = 0;
++      unsigned int parit512_1 = 0, parit512_2 = 0, parit1024_1 =
++          0, parit1024_2 = 0, parit2048_1 = 0, parit2048_2 = 0;
++
++      for (i = ecc_n_bytes - 1; i >= 0; --i) {
++              datum = data[i];
++              sumCol ^= datum;
++              temp = lookup_t[datum];
++
++              if (i & 0x01)
++                      parit8_1 ^= temp;
++              if (i & 0x02)
++                      parit16_1 ^= temp;
++              if (i & 0x04)
++                      parit32_1 ^= temp;
++              if (i & 0x08)
++                      parit64_1 ^= temp;
++              if (i & 0x10)
++                      parit128_1 ^= temp;
++              if (i & 0x20)
++                      parit256_1 ^= temp;
++              if (i & 0x40)
++                      parit512_1 ^= temp;
++              if (i & 0x80)
++                      parit1024_1 ^= temp;
++              if (i & 0x100)
++                      parit2048_1 ^= temp;
++      }
++
++      glob_parity = lookup_t[sumCol];
++
++      parit1_1 =
++          ((sumCol >> 1) ^ (sumCol >> 3) ^ (sumCol >> 5) ^ (sumCol >> 7)) & 1;
++      parit1_2 =
++          ((sumCol >> 0) ^ (sumCol >> 2) ^ (sumCol >> 4) ^ (sumCol >> 6)) & 1;
++      parit2_1 =
++          ((sumCol >> 2) ^ (sumCol >> 3) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++      parit2_2 =
++          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 4) ^ (sumCol >> 5)) & 1;
++      parit4_1 =
++          ((sumCol >> 4) ^ (sumCol >> 5) ^ (sumCol >> 6) ^ (sumCol >> 7)) & 1;
++      parit4_2 =
++          ((sumCol >> 0) ^ (sumCol >> 1) ^ (sumCol >> 2) ^ (sumCol >> 3)) & 1;
++
++      parit8_2 = glob_parity ^ parit8_1;
++      parit16_2 = glob_parity ^ parit16_1;
++      parit32_2 = glob_parity ^ parit32_1;
++      parit64_2 = glob_parity ^ parit64_1;
++      parit128_2 = glob_parity ^ parit128_1;
++      parit256_2 = glob_parity ^ parit256_1;
++      parit512_2 = glob_parity ^ parit512_1;
++      parit1024_2 = glob_parity ^ parit1024_1;
++      parit2048_2 = glob_parity ^ parit2048_1;
++
++      /* Pack bits */
++      ecc[0] =
++          ~((parit64_1 << 7) | (parit64_2 << 6) | (parit32_1 << 5) |
++            (parit32_2 << 4) | (parit16_1 << 3) | (parit16_2 << 2) | (parit8_1
++                                                                      << 1) |
++            parit8_2);
++      ecc[1] =
++          ~((parit1024_1 << 7) | (parit1024_2 << 6) | (parit512_1 << 5) |
++            (parit512_2 << 4) | (parit256_1 << 3) | (parit256_2 << 2) |
++            (parit128_1 << 1) | parit128_2);
++      ecc[2] =
++          ~((parit4_1 << 7) | (parit4_2 << 6) | (parit2_1 << 5) |
++            (parit2_2 << 4) | (parit1_1 << 3) | (parit1_2 << 2) | (parit2048_1
++                                                                   << 1) |
++            parit2048_2);
++
++      return 0;
++}
++
++static struct nand_ecclayout nand_oob = {
++      .eccbytes = 12,
++      .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
++      .oobavail = MTD_NANDECC_AUTOPLACE,
++      .oobfree = {
++              { .offset = 8,
++               .length = 8,
++              },
++              { .offset = 24,
++               .length = 8,
++              },
++              { .offset = 40,
++               .length = 8,
++              },
++              { .offset = 56,
++               .length = 8,
++              },
++              },
++};
++static struct mtd_partition nandflash_main_partitions[] = {
++
++      {.name = "X-Loader(NAND)",
++       .offset = 0,
++       .size = 2 * 0x000020000},      /*256 Kbytes */
++      {.name = "MemInit(NAND)",
++       .offset = 2 * 0x000020000,
++       .size = 2 * 0x000020000},      /*128 KBytes */
++      {.name = "BootLoader(NAND)",
++       .offset = 4 * 0x000020000,
++       .size = 16 * 0x00020000},      /*2Mbytes */
++      {.name = "Kernel zImage(NAND)",
++       .offset = 20 * 0x000020000,
++       .size = 24 * 0x000020000},     /*3Mbytes */
++      {.name = "Root Filesystem(NAND)",
++       .offset = 44 * 0x000020000,
++       .size = 176 * 0x000020000},    /*22 Mbytes */
++      {.name = "User Filesystem(NAND)",
++       .offset = 220 * 0x000020000,
++       .size = 800 * 0x000020000},    /*100 Mbytes */
++};
++
++uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++
++struct nand_bbt_descr bbt_desc = {
++      .options = 0,
++      .offs = 0,
++      .len = 2,
++      .pattern = scan_ff_pattern
++};
++
++static void nmdknand_hwcontrol(struct mtd_info *mtd, int cmd,
++                                  unsigned int ctrl)
++{
++      struct nomadik_nand_info *drvdata =
++          container_of(mtd, struct nomadik_nand_info, mtd);
++
++      if (cmd == NAND_CMD_NONE)
++              return;
++
++      if (ctrl & NAND_NCE) {
++              *((volatile unsigned long *)(IO_ADDRESS(NOMADIK_FSMC_BASE) +
++                                           0x40)) |= 0x04;
++      }
++      if (ctrl & NAND_CLE) {
++              writeb(cmd,drvdata->cmemc_va);
++      }
++      if (ctrl & NAND_ALE) {
++              writeb(cmd,drvdata->cmema_va);
++      }
++}
++
++static struct nomadik_nand_platform_data nomadik_nand_flash_data = {
++      .parts = nandflash_main_partitions,
++      .num_parts = ARRAY_SIZE(nandflash_main_partitions),
++      .lp_options = NAND_STM_LP_OPTIONS,
++      .eccsize = 512,
++      .eccsteps = 4,
++      /*.badblockpos = 5,*/
++      .badblockpos = 6,
++      .init = nomadik_nandflash_init,
++      .exit = nomadik_nandflash_exit,
++      .nand_oob = &nand_oob,
++      .bbt_desc = &bbt_desc,
++      .compute_ecc = nmdknand_compute_ecc512,
++      .hwcontrol = nmdknand_hwcontrol,
++};
++
++static struct platform_device nomadik_nand_flash = {
++      .name = "NOMADIK-NAND",
++      .id = 0,
++      .dev = {
++              .platform_data = &nomadik_nand_flash_data,
++              },
++      .num_resources = ARRAY_SIZE(nandflash_resources),
++      .resource = nandflash_resources,
++};
++#endif //CONFIG_MTD_NAND
++
++#ifdef CONFIG_MTD_ONENAND
++static int nomadik_1nand_init(void)
++{     int ret=0;
++      int fsmc_err=1;
++      int board=8820;
++
++      /*Set the reset signal to high*/
++      ret = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_9,STMPE2401_PRIMARY_FUNCTION);
++        if (ret != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE1 %d as  primary function\n",EGPIO_PIN_9);
++        ret = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_9,STMPE2401_GPIO_OUT);
++        if (ret != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_9);
++        ret = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_9, 1);
++
++      /*Configure other GPIO pins to ALT FUNC A*/
++        ret = nomadik_gpio_altfuncenable(GPIO_ALT_ONENAND, "onenand");
++      if (ret)
++      {       nmdk_error("Could not set oneNAND GPIO alternate function correctly\n");
++              printk("\n>ERROR to config GPIO %d", ret);
++              return -1;
++      }
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BCR0)) = DEFAULT_BCR0_VALUE;
++      *((volatile unsigned long *)(NOMADIK_FSMC_VA + FSMC_BTR0)) = DEFAULT_BTR0_VALUE;
++       return 0;
++}
++
++void nomadik_1nand_exit(void)
++{     int ret=0;
++      ret=nomadik_gpio_altfuncdisable(GPIO_ALT_ONENAND, "onenand");
++      if(!ret)
++      return;
++      else
++      {       printk("Could not Disable ST ONENAND GPIO alternate function \n");
++      }
++}
++
++
++
++static struct resource nomadik_1nand_resource[] = {
++      [0] = {
++             .start = NOMADIK_1NAND_BASE,
++             .end = NOMADIK_1NAND_BASE + SZ_128K - 1,
++             .flags = IORESOURCE_MEM,
++             },
++};
++static struct mtd_partition onenandflash_main_partitions[] = {
++      {.name = "X-Loader(ONENAND)",
++       .offset = 0,
++       .size = 2 * 0x000020000},      /*256 Kbytes */
++      {.name = "MemInit(ONENAND)",
++       .offset = 2 * 0x000020000,
++       .size = 2 * 0x000020000},      /*256 KBytes */
++      {.name = "BootLoader(ONENAND)",
++       .offset = 4 * 0x000020000,
++       .size = 16 * 0x00020000},      /*2Mbytes */
++      {.name = "Kernel zImage(ONENAND)",
++       .offset = 20 * 0x000020000,
++       .size = 32 * 0x000020000},     /*4Mbytes */
++      {.name = "Root Filesystem(ONENAND)",
++       .offset = 52 * 0x000020000,
++       .size = 176 * 0x000020000},    /*22 Mbytes */
++      {.name = "User Filesystem(ONENAND)",
++       .offset = 228 * 0x000020000,
++       .size =  1820 * 0x000020000},  /*227.5 Mbytes */
++};
++
++static struct flash_platform_data nomadik_1nand_flash_data={
++      .init=nomadik_1nand_init,
++      .exit=nomadik_1nand_exit,
++      .name="onenand",
++      .parts=onenandflash_main_partitions,
++      .nr_parts=ARRAY_SIZE(onenandflash_main_partitions),
++};
++
++static struct platform_device nomadik_1nand_flash = {
++      .name = "onenand",
++      .id = 0,
++      .dev = {
++              .bus_id = "1nand",
++              .platform_data = &nomadik_1nand_flash_data,
++              },
++      .num_resources = ARRAY_SIZE(nomadik_1nand_resource),
++      .resource = nomadik_1nand_resource,
++};
++#endif //CONFIG_MTD_ONENAND
++#endif
++
++#undef NMDK_DEBUG     /*board*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++static void nomadik_st2590_init(void)
++{
++      t_STMPE2401_error err;
++
++      nomadik_gpio_altfuncenable(GPIO_ALT_UART_0_MODEM, "BT");
++      nomadik_gpio_altfuncenable(GPIO_ALT_MSP_2, "BT");
++        /*reset the bt controller which is conected thro port expander 0*/
++        err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_16,STMPE2401_PRIMARY_FUNCTION);
++        if (err != STMPE2401_OK)
++        {
++                printk("Couldn't set STMPE%d %d as primary function\n",STMPE0,EGPIO_PIN_16);
++        }
++        err = STMPE2401_SetGpioDir( STMPE0,EGPIO_PIN_16,STMPE2401_GPIO_OUT );
++        if (err != STMPE2401_OK)
++        {
++               printk("Couldn't set STMPE0 EGPIO:%d in Output direction\n", EGPIO_PIN_16);
++        }
++        err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,0);
++        if (err != STMPE2401_OK)
++        {
++               printk("Couldn't set STMPE0 GPIO16\n");
++        }
++        msleep(100);
++        err = STMPE2401_SetGpioVal(STMPE0,EGPIO_PIN_16,1);
++        if (err != STMPE2401_OK)
++        {
++               printk("Couldn't set STMPE0 GPIO16\n");
++        }
++        printk("BT Reset Applied !!\n");
++}
++#ifdef CONFIG_SMC91X
++static void nomadik_smc91x_irq_init(void)
++{
++      t_STMPE2401_error err;
++
++      nomadik_gpio_altfuncenable(GPIO_ALT_ETHERNET, "ETH");
++        /*reset the ethernet controller which is conected thro port expander 1*/
++        err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_10,STMPE2401_PRIMARY_FUNCTION);
++        if (err != STMPE2401_OK)
++        {
++                printk("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_10);
++        }
++        err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_10,STMPE2401_GPIO_OUT );
++        if (err != STMPE2401_OK)
++        {
++               printk("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_10);
++        }
++        err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_10,0);
++        if (err != STMPE2401_OK)
++        {
++               printk("Couldn't set STMPE GPIO10\n");
++        }
++        mdelay(200);
++}
++
++static struct resource smc91x_resources[] = {
++      [0] = {
++             .name = "smc91x-regs",
++             .start = (NOMADIK_ETH0_BASE + 0x300),
++             .end = (NOMADIK_ETH0_BASE + SZ_64M - 1),
++             .flags = IORESOURCE_MEM,
++             },
++      [1] = {
++             .start = IRQNO_GPIO(SMC91111_IRQ),
++             .end = IRQNO_GPIO(SMC91111_IRQ),
++             .flags = IORESOURCE_IRQ,
++             },
++};
++
++static struct platform_device smc91x_device = {
++      .name = "smc91x",
++      .id = 0,
++      .num_resources = ARRAY_SIZE(smc91x_resources),
++      .resource = smc91x_resources,
++};
++#endif
++
++#define NMDK_DEBUG    BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  BOARD_NAME    /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++#ifdef CONFIG_STMPE_NOMADIK
++
++/*initialize the pins which are connected thro stmpe devices
++ *This is not stmpe platform init function - FIXME
++ */
++static int nomadik_stmpe_plat_init(void)
++{
++      int err,ret;
++
++       /* Access the STMPE2401, and make the signal EXP1_GPIO8 as high
++         * for NAND flash write protet off
++         */
++        err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_8,STMPE2401_PRIMARY_FUNCTION);
++        if (err != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE1 %d as  primary function\n",EGPIO_PIN_8);
++        err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_8,STMPE2401_GPIO_OUT);
++        if (err != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE1 :%d in Output direction\n", EGPIO_PIN_8);
++        err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_8, 1);
++        if (err != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE GPIO8\n");
++
++      /*reset the WVGA display which is conected thro port expander 1*/
++      err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION);
++        if (err != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_5);
++        err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT );
++        if (err != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_5);
++        err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1);
++        if (err != STMPE2401_OK)
++                nmdk_error("Couldn't set STMPE GPIO5\n");
++
++#ifdef CONFIG_SMC91X
++      nomadik_smc91x_irq_init();
++        udelay(1000);           /*1ms*/
++#endif
++      nomadik_st2590_init();
++
++      return 0;
++}
++
++/*not yet implemented*/
++int nomadik_stmpe_plat_exit(void)
++{
++      return 0;
++}
++
++static struct resource stmpe_resources[] = {
++        [0] = {
++               .name = "STMPE",
++               .start = IRQNO_GPIO(76),
++               .end  = IRQNO_GPIO(76),
++               .flags = IORESOURCE_IRQ,
++               },
++      [1] = {
++               .name = "STMPE",
++               .start = IRQNO_GPIO(78),
++               .end  = IRQNO_GPIO(78),
++               .flags = IORESOURCE_IRQ,
++               },
++};
++static struct resource nomadik_udc_resources[] = {
++        [0] = {
++                .name   = "udc-mem",
++                .start  = IO_ADDRESS(NOMADIK_USB_BASE),
++                .end    = (IO_ADDRESS(NOMADIK_USB_BASE) + SZ_1M -1),
++                .flags  =  IORESOURCE_MEM,
++        },
++
++        [1] = {
++                .name   = "udc-irq",
++                .start  = INT_USBOTG,
++                .end    = INT_USBOTG,
++                .flags  = IORESOURCE_IRQ,
++        },
++};
++static struct platform_device nomadik_udc_device = {
++        .name = "NOMADIK USBDEV",
++        .id = 0,
++        .num_resources = ARRAY_SIZE(nomadik_udc_resources),
++        .resource = nomadik_udc_resources,
++};
++
++static struct nomadik_stmpe_platform_data nomadik_stmpe_data = {
++      .init = nomadik_stmpe_plat_init,
++      .exit = nomadik_stmpe_plat_exit,
++};
++
++static struct platform_device nomadik_stmpe_device = {
++      .name = "NOMADIK-STMPE",
++      .id = 0,
++      .dev = {
++                .platform_data = &nomadik_stmpe_data,
++                },
++      .num_resources = ARRAY_SIZE(stmpe_resources),
++      .resource = stmpe_resources,
++};
++
++#endif
++
++#undef NMDK_DEBUG     /*board*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++/*
++ * touchpanel
++ */
++
++static int nomadik_tsc2003_init_irq (void (*callback)(void* parameter), void * p)
++{
++      t_STMPE2401_error err;
++      DEBUG_TS(("nomadik_tsc2003_init_irq\n"));
++      err = STMPE2401_SetGpioAltFunction( STMPE1 , EGPIO_PIN_6 , STMPE2401_PRIMARY_FUNCTION );
++      err |= STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_6,STMPE2401_GPIO_IN );
++      err |= STMPE2401_SetGpioPull(STMPE1,EGPIO_PIN_6,STMPE2401_FLOATING );
++
++      err = STMPE2401_Install_Callback(STMPE1, STMPE2401_GPIO_IRQ(6), callback,(void*)p);
++      if (err != STMPE2401_OK)        {
++              printk("Couldn't setup touch screen callback\n");
++      }
++      err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_FALL_EDGE);
++      if (err != STMPE2401_OK)        {
++              printk("Couldn't set touch screen edge detection\n");
++      }
++      err = STMPE2401_ClearGpioEdgeStatus(STMPE1,(0x1<<EGPIO_PIN_6));
++      if (err != STMPE2401_OK)        {
++              printk("Couldn't clear touch screen edge status \n");
++      }
++      /*err = STMPE2401_InterruptAbilitation(STMPE1, STMPE2401_ENABLE_INTERRUPT );
++      if (err != STMPE2401_OK)        {
++              printk("Couldn't enable touch screen callback\n");
++      }*/
++      return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_exit_irq(void)
++{
++      t_STMPE2401_error err;
++      DEBUG_TS(("nomadik_tsc2003_exit_irq\n"));
++      err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
++      err |= STMPE2401_SetGpioEdgeDetect( STMPE1, EGPIO_PIN_6, STMPE2401_NO_EDGE);
++      return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_irqen(void)
++{
++      t_STMPE2401_error err;
++      //DEBUG_TS(("nomadik_tsc2003_irqen\n"));
++      err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_ENABLE_INTERRUPT );
++      return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_irqdis(void)
++{
++      t_STMPE2401_error err;
++      //DEBUG_TS(("nomadik_tsc2003_irqdis\n"));
++      err = STMPE2401_InterruptSourceAbilitation(STMPE1, STMPE2401_GPIO_IRQ(6), STMPE2401_DISABLE_INTERRUPT );
++      return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_irq_ack(void)
++{
++      u16 irqSource = 0x100;
++      u32 irqGpioSource = 0x40;
++      t_STMPE2401_error err;
++      //DEBUG_TS(("nomadik_tsc2003_irq_ack\n"));
++      err = STMPE2401_Acknowledge(STMPE1,irqSource,irqGpioSource);
++      return (err != STMPE2401_OK);
++}
++
++static int nomadik_tsc2003_read_pin_val(u8   * Value)
++{
++      t_STMPE2401_error   err;
++
++      err = STMPE2401_GetGpioVal(STMPE1 , EGPIO_PIN_6, Value);
++      return (err != STMPE2401_OK);
++}
++static struct touchp_tsc2003_device touchp_tsc2003_board = {
++      .irq_init = nomadik_tsc2003_init_irq,
++      .irq_exit = nomadik_tsc2003_exit_irq,
++      .pirq_en  = nomadik_tsc2003_irqen,
++      .pirq_dis = nomadik_tsc2003_irqdis,
++      .pirq_ack = nomadik_tsc2003_irq_ack,
++      .pirq_read_val = nomadik_tsc2003_read_pin_val,
++};
++
++static struct platform_device touchp_tsc2003_device = {
++      //.name = "nmdk-tp",
++      .name = "tsc2003",
++      .id = 0,
++      .dev = {
++              .platform_data = &touchp_tsc2003_board,
++              },
++      .num_resources = 0,
++      .resource = NULL,
++};
++
++/*
++ * keypad
++ */
++
++#define NMDK_DEBUG      BOARD_DEBUG     /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  BOARD_NAME      /* msg header represents this module */
++#define NMDK_DBG        KERN_ERR        /* message level */
++
++static void kp_callback (void * parameter)
++{
++    t_STMPE2401_error err;
++    t_STMPE2401_key_status keys;
++    struct keypad_t * kp = (struct keypad_t *)parameter;
++    u8 kcode,i;
++
++    /*DEBUG_KP(("kp_callback\n"));*/
++    err = STMPE2401_Keypressed(STMPE0, &keys);
++    if(keys.buttonPressed)
++    {
++        for(i=0;i<keys.buttonPressed;i++)
++        {
++            kcode = kp->board->kcode_tbl[(keys.button[i]&0x3)*4 + ((keys.button[i]>>3)&0x3)];
++            input_report_key(kp->inp_dev,kcode, 1);
++        }
++    }
++    if(keys.buttonReleased)
++    {
++        for(i=0;i<keys.buttonReleased;i++)
++        {
++            kcode = kp->board->kcode_tbl[(keys.released[i]&0x3)*4 + ((keys.released[i]>>3)&0x3)];
++            input_report_key(kp->inp_dev,kcode, 0);
++        }
++    }
++}
++
++/**
++ * nomadik_kp_init_key_hardware -  keypad hardware initialization
++ *
++ ****************************************************************************
++ */
++int nomadik_kp_init_key_hardware(struct keypad_t *kp)
++{
++      t_STMPE2401_error err;
++      t_STMPE2401_key_config kpconfig;
++
++      DEBUG_KP(("nomadik_kp_init_key_hardware\n"));
++      nmdk_dbg_ftrace();
++      /*setup Columns GPIOs (inputs)*/
++      kpconfig.columns  = 0xF;                //4 columns
++      kpconfig.rows     = 0xF;                //4 rows
++      kpconfig.nCycles  = 8;                  //number of cycles for key data updating
++      kpconfig.debounce = 64;                 //de-bounce time 64 ms
++      kpconfig.scan     = STMPE2401_SCAN_OFF;
++      err =  STMPE2401_Keypad_init(STMPE0, kpconfig);
++      if (err != STMPE2401_OK)
++      {
++              printk("Couldn't setup keypad configuration\n");
++      }
++      if (!kp->mode)
++      {       /* true if interrupt mode operation */
++              DEBUG_KP(("\tsetting up keypad interrupt stuff\n"));
++              err = STMPE2401_Install_Callback(STMPE0, STMPE2401_KEYPAD_IRQ,kp_callback,(void*)kp);
++              if (err != STMPE2401_OK)
++              {
++                      printk("Couldn't setup keypad callback\n");
++              }
++              err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
++              if (err != STMPE2401_OK)
++              {
++                      printk("Couldn't abilitate the keypad source interrupt\n");
++              }
++              /*err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_ENABLE_INTERRUPT );
++              if (err != STMPE2401_OK)
++              {
++                      printk("Couldn't enable the keypad source interrupt\n");
++              }*/
++      }
++      err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_ON);
++      if (err != STMPE2401_OK)
++      {
++              printk("Couldn't enable keypad scan\n");
++      }
++      return 0;
++}
++
++/**
++ * nomadik_kp_exit_key_hardware- keypad hardware exit function
++ *
++ */
++int nomadik_kp_exit_key_hardware(struct keypad_t *kp)
++{
++      t_STMPE2401_error err;
++
++      DEBUG_KP(("nomadik_kp_exit_key_hardware\n"));
++      err = STMPE2401_Keypad_scan(STMPE0, STMPE2401_SCAN_OFF);
++      if (err != STMPE2401_OK)
++      {
++              printk("Couldn't enable keypad scan\n");
++      }
++      if (!kp->mode)
++      {       /* true if interrupt mode operation */
++              err = STMPE2401_InterruptAbilitation(STMPE0, STMPE2401_DISABLE_INTERRUPT );
++              if (err != STMPE2401_OK)
++              {
++                      printk("Couldn't disable keypad callback\n");
++              }
++              err = STMPE2401_Remove_Callback(STMPE0, STMPE2401_KEYPAD_IRQ);
++              if (err != STMPE2401_OK)
++              {
++                      printk("Couldn't remove keypad callback\n");
++              }
++      }
++      nmdk_dbg_ftrace();
++      return 0;
++}
++
++/**
++ * nomadik_kp_key_scan - keypad scan and report event function
++ *
++ */
++int nomadik_kp_key_scan(struct keypad_t *kp)
++{
++      DEBUG_KP(("nomadik_kp_key_scan\n"));
++      kp_callback ((void *) kp);
++      return 0;
++}
++
++/**
++ * nomadik_kp_key_irqen- enables keypad interrupt
++ *
++ * enables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqen(struct keypad_t *kp)
++{
++      t_STMPE2401_error err;
++      DEBUG_KP(("nomadik_kp_key_irqen\n"));
++      err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_ENABLE_INTERRUPT );
++      return (err != STMPE2401_OK);
++}
++
++/**
++ * nomadik_kp_key_irqdis- disables keypad interrupt
++ *
++ * disables keypad interrupt through CPLD logic
++ */
++int nomadik_kp_key_irqdis(struct keypad_t *kp)
++{
++      t_STMPE2401_error err;
++      DEBUG_KP(("nomadik_kp_key_irqdis\n"));
++      err = STMPE2401_InterruptSourceAbilitation(STMPE0, STMPE2401_KEYPAD_IRQ, STMPE2401_DISABLE_INTERRUPT );
++      return (err != STMPE2401_OK);
++}
++
++/*
++ * Initializes the key scan table (lookup table) as per pre-defined the scan
++ * codes to be passed to upper layer with respective key codes
++ */
++u8 const kpd_lookup_tbl[4*4] = {
++      KEY_RESERVED, KEY_RESERVED, KEY_VOLUMEDOWN, KEY_VOLUMEUP,
++      KEY_F1, KEY_F8, KEY_F3, KEY_F4,
++      KEY_F5, KEY_F6, KEY_F7, KEY_ENTER,
++      KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN
++};
++
++static struct keypad_device keypad_board = {
++      .init = nomadik_kp_init_key_hardware,
++      .exit = nomadik_kp_exit_key_hardware,
++      .scan = nomadik_kp_key_scan,
++      .irqen = nomadik_kp_key_irqen,
++      .irqdis = nomadik_kp_key_irqdis,
++      .kcode_tbl = (u8 *) kpd_lookup_tbl,
++      .krow = 4,
++      .kcol = 4,
++};
++
++#undef NMDK_DEBUG     /*board*/
++#undef NMDK_DEBUG_PFX
++#undef NMDK_DBG
++
++
++/*static struct resource keypad_resources[] = {
++      [0] = {
++             },
++};*/
++
++static struct platform_device keypad_device = {
++      .name = "nmdk-kp",
++      .id = 0,
++      .dev = {
++              .platform_data = &keypad_board,
++              },
++      .num_resources = 0,
++      .resource = NULL,
++};
++
++static struct platform_device *nmdk_platform_devices[] __initdata = {
++      &fsmc_device,
++      &nomadik_udc_device,
++#ifdef CONFIG_MTD
++#ifdef CONFIG_MTD_NAND
++      &nomadik_nand_flash,
++#endif
++#ifdef CONFIG_MTD_ONENAND
++      &nomadik_1nand_flash,
++#endif
++#endif
++#ifdef CONFIG_SMC91X
++      &smc91x_device,
++#endif
++#ifdef CONFIG_STMPE_NOMADIK
++      &nomadik_stmpe_device,
++#endif
++      &keypad_device,
++      &touchp_tsc2003_device,
++};
++
++void add_nmdk_platform_devices(void)
++{
++      platform_add_devices(nmdk_platform_devices,
++                           ARRAY_SIZE(nmdk_platform_devices));
++}
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/normal.S
+@@ -0,0 +1,199 @@
++/*
++ * arch/arm/mach-nomadik/normal.S
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#define NORMAL_DEBUG 0
++#define mpmc_base                     0xF0110000
++#define src_base                      0xf01e0000
++#define pmu_base                      0xf01e9000
++#define uart_base                     0xcc85e000
++
++
++
++
++.align 5
++.globl nomadik_normal_mode
++
++nomadik_normal_mode:
++
++
++      stmfd sp!,{r0-r12,lr}
++
++      ldr r10,=mpmc_base
++      ldr r11,=src_base
++      ldr r12,=pmu_base
++      ldr r9,=uart_base
++
++
++      ldr r2, [r11]
++
++#if NORMAL_DEBUG
++      mov r0, #97
++      str r0, [r9]
++#endif
++
++      /*  Prefetch certain instructions in the cache.  */
++    adr r4, cache_prefetch_start
++      adr r5, cache_prefetch_end
++      mvn r1,#0x1F
++      ands r4,r1,r4
++pfetch:
++      mcr p15, 0, r4, c7, c13,1
++      cmp r4,r5
++      addls r4, r4, #0x20
++      bls pfetch
++
++.align 5
++
++cache_prefetch_start:
++      ldr r10, =mpmc_base
++
++poll_status:
++      /* Check sdram is not busy */
++      ldr r1,[r10, #0x4]
++      ands r1,r1,#0x1
++      cmp r1,#0
++      bne poll_status
++
++      /* Put SDRAM in self-refresh mode*/
++      ldr r1,[r10, #0x20]
++      bic r1,r1,#0x1
++      orr r1,r1,#0x04
++      str r1,[r10, #0x20]
++
++
++      /*Wait for SDRAM to go in self-refresh*/
++wait_self_refresh:
++      ldr r1,[r10,#0x4]
++      and r1,r1,#0x4
++      cmp r1,#0x0
++      beq wait_self_refresh
++
++      /**
++       * Stop the DLL, leave SDMC on
++       Moving 0xff9 into sdmc control register for stopping and adding dll
 +       cmd value
 +       */
 +      mov r1, #0xff0
@@ -18589,7 +20870,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +      cmp r1,#0
 +      bne wait_dll_lock
 +
-+#if NORMAL_DEBUG 
++#if NORMAL_DEBUG
 +      mov r0, #98
 +      str r0, [r9]
 +#endif
@@ -18610,13 +20891,13 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +
 +
 +
-+#if NORMAL_DEBUG 
++#if NORMAL_DEBUG
 +      mov r0, #99
 +      str r0, [r9]
 +#endif
 +
 +
-+      
++
 +       ldr r1,[r11]
 +/** Routine to put the chip in normal Mode
 +       bic r1, r1, #0x7
@@ -18636,7 +20917,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +      bne wait_normal_mode
 +
 +
-+#if NORMAL_DEBUG 
++#if NORMAL_DEBUG
 +      mov r0, #100
 +      str r0, [r9]
 +#endif
@@ -18644,7 +20925,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +
 +      /* Exit DDR-SDRAM from self-refresh mode */
 +      ldr r1,[r10, #0x20]
-+      bic r1,r1,#0x04 
++      bic r1,r1,#0x04
 +      str r1,[r10, #0x20]
 +
 +
@@ -18654,8 +20935,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +      and r1,r1,#0x4
 +      cmp r1,#0x4
 +      beq loop_refresh
-+      
-+#if NORMAL_DEBUG 
++
++#if NORMAL_DEBUG
 +      mov r0, #101
 +      str r0, [r9]
 +#endif
@@ -18674,7 +20955,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +      mov r0,r0
 +
 +
-+#if NORMAL_DEBUG 
++#if NORMAL_DEBUG
 +
 +      mov r0, #102
 +      str r0, [r9]
@@ -18683,9 +20964,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/normal.S ../new/linux-2.6.20/arc
 +    ldmfd sp!,{r0-r12,pc}
 +
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/pm.c ../new/linux-2.6.20/arch/arm/mach-nomadik/pm.c
---- linux-2.6.20/arch/arm/mach-nomadik/pm.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/pm.c     2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/pm.c
 @@ -0,0 +1,79 @@
 +/*
 + * NOMADIK Power Management Routines
@@ -18766,9 +21046,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/pm.c ../new/linux-2.6.20/arch/ar
 +}
 +
 +device_initcall(nomadik_pm_init);
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/power.c ../new/linux-2.6.20/arch/arm/mach-nomadik/power.c
---- linux-2.6.20/arch/arm/mach-nomadik/power.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/power.c  2008-11-19 16:47:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/power.c
 @@ -0,0 +1,1316 @@
 +/*
 + *  linux/arch/arm/mach-nomadik/power.c
@@ -20086,9 +22365,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/power.c ../new/linux-2.6.20/arch
 +
 +core_initcall(nomadik_power_init);
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/rtc.c ../new/linux-2.6.20/arch/arm/mach-nomadik/rtc.c
---- linux-2.6.20/arch/arm/mach-nomadik/rtc.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/rtc.c    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/rtc.c
 @@ -0,0 +1,327 @@
 +/*
 + *  linux/arch/arm/mach-nomadik/rtc.c
@@ -20266,7 +22544,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/rtc.c ../new/linux-2.6.20/arch/a
 +              {
 +                      int tmp = 0;
 +
-+                      /* 
++                      /*
 +                       * The max we can do is 8192Hz.
 +                       */
 +                      if ((arg < 2) || (arg > 8192))
@@ -20417,9 +22695,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/rtc.c ../new/linux-2.6.20/arch/a
 +MODULE_AUTHOR("Prafulla WADASKAR <prafulla.wadaskar@st.com>");
 +MODULE_DESCRIPTION("Nomadik RTC/RTT driver");
 +MODULE_LICENSE("GPL v2");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/sleep.c ../new/linux-2.6.20/arch/arm/mach-nomadik/sleep.c
---- linux-2.6.20/arch/arm/mach-nomadik/sleep.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/sleep.c  2008-08-21 18:04:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/sleep.c
 @@ -0,0 +1,280 @@
 +/*
 + * arch/arm/mach-nomadik/sleep.c
@@ -20701,9 +22978,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/sleep.c ../new/linux-2.6.20/arch
 +
 +      return 0;
 +}
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/arm/mach-nomadik/slow.S
---- linux-2.6.20/arch/arm/mach-nomadik/slow.S  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/slow.S   2008-07-28 15:20:45.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/slow.S
 @@ -0,0 +1,199 @@
 +/*
 + * arch/arm/mach-nomadik/slow.S
@@ -20744,14 +23020,14 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +      stmfd sp!,{r0-r12,lr}
 +
 +      ldr r10,=mpmc_base
-+      ldr r11,=src_base       
++      ldr r11,=src_base
 +      ldr r12,=pmu_base
 +      ldr r9,=uart_base
 +
 +
 +      ldr r2, [r11]
-+      
-+#if SLOW_DEBUG 
++
++#if SLOW_DEBUG
 +      mov r0, #97
 +      str r0, [r9]
 +#endif
@@ -20768,7 +23044,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +      bls pfetch
 +
 +.align 5
-+              
++
 +cache_prefetch_start:
 +      ldr r10, =mpmc_base
 +
@@ -20779,7 +23055,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +      cmp r1,#0
 +      bne poll_status
 +
-+      /* Put SDRAM in self-refresh mode*/     
++      /* Put SDRAM in self-refresh mode*/
 +      ldr r1,[r10, #0x20]
 +      bic r1,r1,#0x1
 +      orr r1,r1,#0x04
@@ -20795,7 +23071,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +
 +      /**
 +       * Stop the DLL, leave SDMC on
-+       Moving 0xff9 into sdmc control register for stopping and adding dll 
++       Moving 0xff9 into sdmc control register for stopping and adding dll
 +       cmd value
 +       */
 +      mov r1, #0xff0
@@ -20810,7 +23086,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +      cmp r1,#0
 +      bne wait_dll_lock
 +
-+#if SLOW_DEBUG 
++#if SLOW_DEBUG
 +      mov r0, #98
 +      str r0, [r9]
 +#endif
@@ -20831,14 +23107,14 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +
 +
 +
-+#if SLOW_DEBUG 
++#if SLOW_DEBUG
 +      mov r0, #99
 +      str r0, [r9]
 +#endif
 +
 +
 +#if 1
-+      
++
 +       ldr r1,[r11]
 +/** Routine to put the chip in Slow Mode
 +*/
@@ -20857,7 +23133,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +
 +#endif
 +
-+#if SLOW_DEBUG 
++#if SLOW_DEBUG
 +      mov r0, #100
 +      str r0, [r9]
 +#endif
@@ -20865,7 +23141,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +
 +      /* Exit DDR-SDRAM from self-refresh mode */
 +      ldr r1,[r10, #0x20]
-+      bic r1,r1,#0x04 
++      bic r1,r1,#0x04
 +      str r1,[r10, #0x20]
 +
 +
@@ -20875,8 +23151,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +      and r1,r1,#0x4
 +      cmp r1,#0x4
 +      beq loop_refresh
-+      
-+#if SLOW_DEBUG 
++
++#if SLOW_DEBUG
 +      mov r0, #101
 +      str r0, [r9]
 +#endif
@@ -20895,7 +23171,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +      mov r0,r0
 +
 +
-+#if SLOW_DEBUG 
++#if SLOW_DEBUG
 +
 +      mov r0, #102
 +      str r0, [r9]
@@ -20904,9 +23180,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/slow.S ../new/linux-2.6.20/arch/
 +    ldmfd sp!,{r0-r12,pc}
 +
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S
---- linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S     2008-07-28 15:20:47.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S
 @@ -0,0 +1,206 @@
 +/*
 + * arch/arm/mach-nomadik/soft_sleep.S
@@ -20947,16 +23222,16 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +
 +
 +      mrs r7, cpsr
-+      stmfd sp!, {r7} 
++      stmfd sp!, {r7}
 +      bic r7,r7,#0xf
 +
 +
-+                      
++
 +      ldr r10,=mpmc_base
-+      ldr r11,=src_base       
++      ldr r11,=src_base
 +      ldr r12,=pmu_base
-+      
-+ 
++
++
 +      /* Go back in SVC mode*/
 +      orr r0,r7,#0x3
 +      msr cpsr_cxsf,r0
@@ -20966,7 +23241,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +      mcr p15,0,r0,c7,c10,4
 +
 +
-+      /* Program to wake-up in Normal mode*/  
++      /* Program to wake-up in Normal mode*/
 +      ldr r0,[r11,#0x4]
 +      bic r0,r0,#0xf
 +      orr r0,r0,#0x9
@@ -20990,7 +23265,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +
 +.align 5
 +
-+              
++
 +cache_prefetch_start:
 +      ldr r10, =mpmc_base
 +
@@ -21000,7 +23275,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +      cmp r1,#0
 +      bne poll_status
 +
-+      /* Put SDRAM in self-refresh mode*/     
++      /* Put SDRAM in self-refresh mode*/
 +      ldr r1,[r10, #0x20]
 +      bic r1,r1,#0x1
 +      orr r1,r1,#0x04
@@ -21012,7 +23287,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +      and r1,r1,#0x4
 +      cmp r1,#0x0
 +      beq wait_self_refresh
-+      
++
 +/** Routine to put the chip in Sleep Mode
 +*/
 +      ldr r11,=src_base
@@ -21058,7 +23333,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +
 +
 +/*  Bring out the SDRAM from self refresh */
-+      /*Put SDRAM in self-refresh mode*/      
++      /*Put SDRAM in self-refresh mode*/
 +      ldr r1,[r10, #0x20]
 +      bic r1,r1,#0x04
 +      str r1,[r10, #0x20]
@@ -21079,7 +23354,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +      mov r0,r0
 +      mov r0,r0
 +      mov r0,r0
-+      
++
 +/* This is to add some delay */
 +      mov r0, #0
 +while_loop:
@@ -21088,35 +23363,34 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/soft_sleep.S ../new/linux-2.6.20
 +      bne while_loop
 +
 +
-+      
++
 +      /* Remove the chip from Interrupt mode */
 +      ldr r0,[r11, #0x4]
 +      bic r0,r0,#0x1
 +      str r0,[r11, #0x4]
-+      
++
 +      /* Clear the interrupt mode status bit*/
 +      mov r0, #0x0
 +      str r0, [r11, #0x8]
 +
 +
 +      /*  Store the value of cpsr in r7*/
-+      mrs r7,cpsr 
++      mrs r7,cpsr
 +      orr r7,r7,#0xC0 /*Not Needed*/
 +      bic r7,r7,#0xf
-+ 
-+ 
++
++
 +      ldr r0, [sp]
 +      msr cpsr_cxsf, r0
 +      add sp, sp,#4
-+      
-+    
++
++
 +
 +    ldmfd sp!,{r0-r12,pc}
 +
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ssp.c ../new/linux-2.6.20/arch/arm/mach-nomadik/ssp.c
---- linux-2.6.20/arch/arm/mach-nomadik/ssp.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/ssp.c    2008-07-04 23:45:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/ssp.c
 @@ -0,0 +1,930 @@
 +/*
 + * arch/arm/mach-nomadik/ssp.c
@@ -22048,9 +24322,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ssp.c ../new/linux-2.6.20/arch/a
 +MODULE_AUTHOR("Sachin Verma, <sachin.verma@st.com>");
 +MODULE_DESCRIPTION("NOMADIK SPI Controller Driver");
 +MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c        2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c
 @@ -0,0 +1,1071 @@
 +/*
 + *  linux/arch/arm/mach-nomadik/stn8810_devices.c
@@ -22488,13 +24761,13 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2
 +
 +/**
 + * dmadev_default_config_tbl - Deffault dma device configuration table
-+ * To support new dmadevice, add new default confiuration to this table 
++ * To support new dmadevice, add new default confiuration to this table
 + * refer /Documentation/arm/STM-Nomadik/dma_user_guide.txt for the same
 + */
 +static struct dmadev_description dmadev_default_config_tbl[] = {
 +      {.id = "mem",
-+       .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_WORD | 
-+              DMA_BSIZE_4 | DMA_REQUEST_LINE(31) | 
++       .config = ( DMA_AHB_M1 | DMA_ADR_INC | DMA_WIDTH_WORD |
++              DMA_BSIZE_4 | DMA_REQUEST_LINE(31) |
 +              DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE |
 +              DMA_DEV_BOTH_DMACS_CANBE_USED ),},
 +      {.id = "sdmmc",
@@ -22593,7 +24866,7 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2
 +
 +void __init arch_dma_init(struct dma_t *dma)
 +{
-+      dma_data.dma_chan = dma;        
++      dma_data.dma_chan = dma;
 +};
 +
 +static struct amba_device dma0_device = {
@@ -23074,13 +25347,13 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2
 +#ifdef CONFIG_NOMADIK_SVA_INIT_MEM
 +
 +      unsigned long gfp_address = 0;
-+      
++
 +      gfp_address = __get_free_pages(GFP_KERNEL, get_order(CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M));
 +      if(gfp_address) {
 +              sva_data.init_bus_address = (__u32) gfp_address - PAGE_OFFSET;
 +              sva_data.init_logical_address = ioremap(sva_data.init_bus_address,
 +                                                      CONFIG_NOMADIK_SVA_MEM_SIZE * SZ_1M);
-+      }       
++      }
 +      if(!sva_data.init_logical_address) {
 +              printk(KERN_ERR"SVA driver %d MB memory boot memory allocation failed\n",CONFIG_NOMADIK_SVA_MEM_SIZE);
 +
@@ -23123,9 +25396,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8810_devices.c ../new/linux-2
 +      .init_machine = nomadik_platform_init,
 +MACHINE_END
 +
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c
---- linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c        2008-11-19 16:47:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c
 @@ -0,0 +1,1971 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -25098,9 +27370,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/stn8815_devices.c ../new/linux-2
 +    0x00000100,.map_io = nomadik_map_io,.init_irq =
 +    nomadik_platform_init_irq,.timer = &nomadik_timer,.init_machine =
 +    nomadik_platform_init, MACHINE_END
-diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/timer.c ../new/linux-2.6.20/arch/arm/mach-nomadik/timer.c
---- linux-2.6.20/arch/arm/mach-nomadik/timer.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mach-nomadik/timer.c  2008-07-04 23:45:12.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/arch/arm/mach-nomadik/timer.c
 @@ -0,0 +1,366 @@
 +/*
 + *  linux/arch/arm/mach-nomadik/timer.c
@@ -25393,8 +27664,8 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/timer.c ../new/linux-2.6.20/arch
 +      if (ticks > 1) {
 +              val = mtu_reg->tmr_value1;
 +
-+              /* 
-+               *  Conservatively assuming that max. 2 timer counts can be 
++              /*
++               *  Conservatively assuming that max. 2 timer counts can be
 +               *  taken in this processing. Below condition looks unlikely
 +               */
 +              if ((mtu_reg->tmr_mis & 0x1) || (val <= 2)) {
@@ -25468,122 +27739,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/timer.c ../new/linux-2.6.20/arch
 +      .dyn_tick = &nomadik_dyn_tick,
 +#endif
 +};
-diff -Nauprw linux-2.6.20/arch/arm/Makefile ../new/linux-2.6.20/arch/arm/Makefile
---- linux-2.6.20/arch/arm/Makefile     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/Makefile      2007-11-21 11:51:41.000000000 +0530
-@@ -20,7 +20,7 @@ CFLAGS               +=$(call cc-option,-marm,)
- # Do not use arch/arm/defconfig - it's always outdated.
- # Select a platform tht is kept up-to-date
--KBUILD_DEFCONFIG := versatile_defconfig
-+KBUILD_DEFCONFIG := ndk15_defconfig
- # defines filename extension depending memory manement type.
- ifeq ($(CONFIG_MMU),)
-@@ -89,6 +89,7 @@ CHECKFLAGS   += -D__arm__
- head-y                := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
- textofs-y     := 0x00008000
-+
-  machine-$(CONFIG_ARCH_RPC)      := rpc
-  machine-$(CONFIG_ARCH_EBSA110)          := ebsa110
-  machine-$(CONFIG_ARCH_CLPS7500)   := clps7500
-@@ -106,6 +107,7 @@ endif
-  machine-$(CONFIG_ARCH_PXA)      := pxa
-  machine-$(CONFIG_ARCH_L7200)    := l7200
-  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
-+ machine-$(CONFIG_ARCH_NOMADIK)          := nomadik
-  textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
-  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
-  machine-$(CONFIG_ARCH_IOP32X)           := iop32x
-@@ -200,12 +202,21 @@ else
- endif
-       @touch $@
--archprepare: maketools
-+archprepare: maketools machprepare
--PHONY += maketools FORCE
-+PHONY += maketools machprepare machclean machmrproper FORCE
- maketools: include/linux/version.h include/asm-arm/.arch FORCE
-       $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
-+
-+# Machine specific preparation if it exists
-+MACHPREPARE_PATH = $(strip `grep "machprepare:" $(MACHINE)Makefile* | grep -o $(MACHINE)`)
-+
-+machprepare:
-+ifeq ($(wildcard $(TOPDIR)/.config), $(TOPDIR)/.config)
-+      $(Q)set -e; for i in $(MACHPREPARE_PATH); do $(MAKE) -C $$i $@; done
-+endif
-+
- # Convert bzImage to zImage
- bzImage: zImage
-@@ -218,8 +229,23 @@ zinstall install: vmlinux
- CLEAN_FILES += include/asm-arm/mach-types.h \
-              include/asm-arm/arch include/asm-arm/.arch
-+# Machine specific mrproper operation if it exists
-+MACHMRPROPER_PATH =`find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machmrproper: | sed 's/Makefile:machmrproper://g' | sed 's/Makefile://g'`
-+
-+machmrproper:
-+      $(Q)set -e; for i in $(MACHMRPROPER_PATH); do $(MAKE) -C $$i $@; done
-+
-+# We use MRPROPER_FILES 
-+archmrproper: machmrproper
-+
-+# Machine specific clean operation
-+MACHCLEAN_PATH = `find arch/$(ARCH)/mach-*/ -name Makefile | xargs grep machclean: | sed 's/Makefile:machclean://g' | sed 's/Makefile://g'`
-+
-+machclean:
-+      $(Q)set -e; for i in $(MACHCLEAN_PATH); do $(MAKE) -C $$i $@; done
-+
- # We use MRPROPER_FILES and CLEAN_FILES now
--archclean:
-+archclean: machclean
-       $(Q)$(MAKE) $(clean)=$(boot)
- # My testing targets (bypasses dependencies)
-diff -Nauprw linux-2.6.20/arch/arm/mm/extable.c ../new/linux-2.6.20/arch/arm/mm/extable.c
---- linux-2.6.20/arch/arm/mm/extable.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/extable.c  2007-11-21 11:51:41.000000000 +0530
-@@ -2,6 +2,7 @@
-  *  linux/arch/arm/mm/extable.c
-  */
- #include <linux/module.h>
-+#include <linux/kgdb.h>
- #include <asm/uaccess.h>
- int fixup_exception(struct pt_regs *regs)
-@@ -11,6 +12,12 @@ int fixup_exception(struct pt_regs *regs
-       fixup = search_exception_tables(instruction_pointer(regs));
-       if (fixup)
-               regs->ARM_pc = fixup->fixup;
-+#ifdef CONFIG_KGDB
-+      if (atomic_read(&debugger_active) && kgdb_may_fault)
-+              /* Restore our previous state. */
-+              kgdb_fault_longjmp(kgdb_fault_jmp_regs);
-+              /* Not reached. */
-+#endif
-       return fixup != NULL;
- }
-diff -Nauprw linux-2.6.20/arch/arm/mm/init.c ../new/linux-2.6.20/arch/arm/mm/init.c
---- linux-2.6.20/arch/arm/mm/init.c    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/init.c     2007-11-21 11:51:41.000000000 +0530
-@@ -89,7 +89,6 @@ void show_mem(void)
-       printk("%d pages shared\n", shared);
-       printk("%d pages swap cached\n", cached);
- }
--
- /*
-  * FIXME: We really want to avoid allocating the bootmap bitmap
-  * over the top of the initrd.  Hopefully, this is located towards
-diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kconfig
---- linux-2.6.20/arch/arm/mm/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/Kconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -60,7 +60,7 @@ config CPU_ARM710
+--- linux-2.6.20.orig/arch/arm/mm/Kconfig
++++ linux-2.6.20/arch/arm/mm/Kconfig
+@@ -58,11 +58,11 @@ config CPU_ARM710
+         Say Y if you want support for the ARM710 processor.
+         Otherwise, say N.
  
  # ARM720T
  config CPU_ARM720T
@@ -25592,7 +27752,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
        select CPU_32v4T
        select CPU_ABRT_LV4T
-@@ -109,7 +109,7 @@ config CPU_ARM9TDMI
+       select CPU_CACHE_V4
+       select CPU_CACHE_VIVT
+@@ -107,11 +107,11 @@ config CPU_ARM9TDMI
+         Otherwise, say N.
  # ARM920T
  config CPU_ARM920T
        bool "Support ARM920T processor"
@@ -25601,7 +27765,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
        select CPU_32v4T
        select CPU_ABRT_EV4T
-@@ -131,7 +131,7 @@ config CPU_ARM920T
+       select CPU_CACHE_V4WT
+       select CPU_CACHE_VIVT
+@@ -129,11 +129,11 @@ config CPU_ARM920T
+         Otherwise, say N.
  # ARM922T
  config CPU_ARM922T
        bool "Support ARM922T processor" if ARCH_INTEGRATOR
@@ -25610,7 +27778,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        default y if ARCH_LH7A40X
        select CPU_32v4T
        select CPU_ABRT_EV4T
-@@ -168,10 +168,15 @@ config CPU_ARM925T
+       select CPU_CACHE_V4WT
+       select CPU_CACHE_VIVT
+@@ -166,14 +166,19 @@ config CPU_ARM925T
+         device family.
          Say Y if you want support for the ARM925T processor.
          Otherwise, say N.
  
@@ -25627,7 +27799,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
        select CPU_32v5
        select CPU_ABRT_EV5TJ
-@@ -223,7 +228,7 @@ config CPU_ARM946E
+       select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
+@@ -221,11 +226,11 @@ config CPU_ARM946E
+         Otherwise, say N.
  # ARM1020 - needs validating
  config CPU_ARM1020
        bool "Support ARM1020T (rev 0) processor"
@@ -25636,7 +27812,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        select CPU_32v5
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
-@@ -241,7 +246,7 @@ config CPU_ARM1020
+       select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
+@@ -239,11 +244,11 @@ config CPU_ARM1020
+         Otherwise, say N.
  # ARM1020E - needs validating
  config CPU_ARM1020E
        bool "Support ARM1020E processor"
@@ -25645,7 +27825,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        select CPU_32v5
        select CPU_ABRT_EV4T
        select CPU_CACHE_V4WT
-@@ -254,7 +259,7 @@ config CPU_ARM1020E
+       select CPU_CACHE_VIVT
+       select CPU_CP15_MMU
+@@ -252,11 +257,11 @@ config CPU_ARM1020E
+       depends on n
  # ARM1022E
  config CPU_ARM1022
        bool "Support ARM1022E processor"
@@ -25654,7 +27838,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        select CPU_32v5
        select CPU_ABRT_EV4T
        select CPU_CACHE_VIVT
-@@ -272,7 +277,7 @@ config CPU_ARM1022
+       select CPU_CP15_MMU
+       select CPU_COPY_V4WB if MMU # can probably do better
+@@ -270,11 +275,11 @@ config CPU_ARM1022
+         Otherwise, say N.
  # ARM1026EJ-S
  config CPU_ARM1026
        bool "Support ARM1026EJ-S processor"
@@ -25663,7 +27851,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        select CPU_32v5
        select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
        select CPU_CACHE_VIVT
-@@ -345,7 +350,7 @@ config CPU_XSC3
+       select CPU_CP15_MMU
+       select CPU_COPY_V4WB if MMU # can probably do better
+@@ -343,11 +348,11 @@ config CPU_XSC3
+       select IO_36
  # ARMv6
  config CPU_V6
        bool "Support ARM V6 processor"
@@ -25672,10 +27864,53 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/Kconfig ../new/linux-2.6.20/arch/arm/mm/Kc
        select CPU_32v6
        select CPU_ABRT_EV6
        select CPU_CACHE_V6
-diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm/mm/proc-arm926.S
---- linux-2.6.20/arch/arm/mm/proc-arm926.S     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/mm/proc-arm926.S      2008-10-20 13:37:44.000000000 +0530
-@@ -24,6 +24,10 @@
+       select CPU_CACHE_VIPT
+       select CPU_CP15_MMU
+--- linux-2.6.20.orig/arch/arm/mm/extable.c
++++ linux-2.6.20/arch/arm/mm/extable.c
+@@ -1,16 +1,23 @@
+ /*
+  *  linux/arch/arm/mm/extable.c
+  */
+ #include <linux/module.h>
++#include <linux/kgdb.h>
+ #include <asm/uaccess.h>
+ int fixup_exception(struct pt_regs *regs)
+ {
+       const struct exception_table_entry *fixup;
+       fixup = search_exception_tables(instruction_pointer(regs));
+       if (fixup)
+               regs->ARM_pc = fixup->fixup;
++#ifdef CONFIG_KGDB
++      if (atomic_read(&debugger_active) && kgdb_may_fault)
++              /* Restore our previous state. */
++              kgdb_fault_longjmp(kgdb_fault_jmp_regs);
++              /* Not reached. */
++#endif
+       return fixup != NULL;
+ }
+--- linux-2.6.20.orig/arch/arm/mm/init.c
++++ linux-2.6.20/arch/arm/mm/init.c
+@@ -87,11 +87,10 @@ void show_mem(void)
+       printk("%d reserved pages\n", reserved);
+       printk("%d slab pages\n", slab);
+       printk("%d pages shared\n", shared);
+       printk("%d pages swap cached\n", cached);
+ }
+-
+ /*
+  * FIXME: We really want to avoid allocating the bootmap bitmap
+  * over the top of the initrd.  Hopefully, this is located towards
+  * the start of a bank, so if we allocate the bootmap bitmap at
+  * the end, we won't clash.
+--- linux-2.6.20.orig/arch/arm/mm/proc-arm926.S
++++ linux-2.6.20/arch/arm/mm/proc-arm926.S
+@@ -22,19 +22,24 @@
+  *
+  * These are the low level assembler for performing cache and TLB
   * functions on the arm926.
   *
   *  CONFIG_CPU_ARM926_CPU_IDLE -> nohlt
@@ -25686,7 +27921,9 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
   */
  #include <linux/linkage.h>
  #include <linux/init.h>
-@@ -33,6 +37,7 @@
+ #include <asm/assembler.h>
+ #include <asm/elf.h>
+ #include <asm/pgtable-hwdef.h>
  #include <asm/pgtable.h>
  #include <asm/page.h>
  #include <asm/ptrace.h>
@@ -25694,14 +27931,18 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
  #include "proc-macros.S"
  
  /*
-@@ -65,9 +70,15 @@ ENTRY(cpu_arm926_proc_fin)
+  * This is the maximum size of an area which will be invalidated
+  * using the single invalidate entry instructions.  Anything larger
+@@ -63,13 +68,19 @@ ENTRY(cpu_arm926_proc_init)
+ ENTRY(cpu_arm926_proc_fin)
+       stmfd   sp!, {lr}
        mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
        msr     cpsr_c, ip
        bl      arm926_flush_kern_cache_all
 +#ifdef CONFIG_L2CACHE_ENABLE
 +      v_l2_cache_clean_and_invalidate r0, r1
 +        v_l2_cache_sync r0, r1
-+        v_l2_cache_disable r0,r1 
++        v_l2_cache_disable r0,r1
 +#endif
        mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
        bic     r0, r0, #0x1000                 @ ...i............
@@ -25710,7 +27951,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
        mcr     p15, 0, r0, c1, c0, 0           @ disable caches
        ldmfd   sp!, {pc}
  
-@@ -253,6 +264,9 @@ ENTRY(arm926_dma_inv_range)
+ /*
+  * cpu_arm926_reset(loc)
+@@ -251,10 +262,13 @@ ENTRY(arm926_dma_inv_range)
+       bic     r0, r0, #CACHE_DLINESIZE - 1
+ 1:    mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
        add     r0, r0, #CACHE_DLINESIZE
        cmp     r0, r1
        blo     1b
@@ -25720,7 +27965,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
  
-@@ -274,6 +288,9 @@ ENTRY(arm926_dma_clean_range)
+ /*
+  *    dma_clean_range(start, end)
+@@ -272,10 +286,13 @@ ENTRY(arm926_dma_clean_range)
+ 1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       add     r0, r0, #CACHE_DLINESIZE
        cmp     r0, r1
        blo     1b
  #endif
@@ -25730,7 +27979,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
  
-@@ -296,6 +313,9 @@ ENTRY(arm926_dma_flush_range)
+ /*
+  *    dma_flush_range(start, end)
+@@ -294,10 +311,13 @@ ENTRY(arm926_dma_flush_range)
+       mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+ #endif
        add     r0, r0, #CACHE_DLINESIZE
        cmp     r0, r1
        blo     1b
@@ -25740,7 +27993,11 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
  
-@@ -341,6 +361,10 @@ ENTRY(cpu_arm926_switch_mm)
+ ENTRY(arm926_cache_fns)
+       .long   arm926_flush_kern_cache_all
+@@ -339,10 +359,14 @@ ENTRY(cpu_arm926_switch_mm)
+ @ && 'Clean & Invalidate whole DCache'
+ 1:    mrc     p15, 0, r15, c7, c14, 3         @ test,clean,invalidate
        bne     1b
  #endif
        mcr     p15, 0, ip, c7, c5, 0           @ invalidate I cache
@@ -25751,12 +28008,16 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
        mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
        mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
-@@ -411,6 +435,12 @@ __arm926_setup:
+ #endif
+       mov     pc, lr
+@@ -409,10 +433,16 @@ __arm926_setup:
+       bic     r0, r0, r5
+       orr     r0, r0, r6
  #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
        orr     r0, r0, #0x4000                 @ .1.. .... .... ....
  #endif
 +#if CONFIG_L2CACHE_ENABLE
-+      l2_cache_disable r2, r3                 @disable L2 Cache 
++      l2_cache_disable r2, r3                 @disable L2 Cache
 +      l2_cache_configure r2, r3               @configures L2 Cache Controller
 +      l2_cache_invalidate r2, r3
 +      l2_cache_enable r2, r3                  @enable L2 Cache
@@ -25764,10 +28025,13 @@ diff -Nauprw linux-2.6.20/arch/arm/mm/proc-arm926.S ../new/linux-2.6.20/arch/arm
        mov     pc, lr
        .size   __arm926_setup, . - __arm926_setup
  
-diff -Nauprw linux-2.6.20/arch/arm/oprofile/common.c ../new/linux-2.6.20/arch/arm/oprofile/common.c
---- linux-2.6.20/arch/arm/oprofile/common.c    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/arch/arm/oprofile/common.c     2008-09-17 13:23:32.000000000 +0530
-@@ -153,10 +153,11 @@ int __init oprofile_arch_init(struct opr
+       /*
+        *  R
+--- linux-2.6.20.orig/arch/arm/oprofile/common.c
++++ linux-2.6.20/arch/arm/oprofile/common.c
+@@ -151,14 +151,15 @@ int __init oprofile_arch_init(struct opr
+               ops->setup = op_arm_setup;
+               ops->shutdown = op_arm_stop;
                ops->start = op_arm_start;
                ops->stop = op_arm_stop;
                ops->cpu_type = op_arm_model->name;
@@ -25780,2036 +28044,2042 @@ diff -Nauprw linux-2.6.20/arch/arm/oprofile/common.c ../new/linux-2.6.20/arch/ar
        return ret;
  }
  
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/debug_strategy.txt       2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,66 @@
-+ 
-+ * 1.1 Nomadik Development Debugging Strategy
-+ * ==========================================
-+ *
-+ * DEBUGGING LEVELS
-+ * 0 To disable all debug messages
-+ * 1 To enable normal debug macro- nmdk_dbg
-+ * 2 To enable flow trace debug macro- nmdk_dbg_ftrace
-+ * 4 To enable interrupt and timer debug macroc- nmdk_dbg2
-+ * 8 To enable any special debug messages defined by macro- nmdk_dbg3
-+ *
-+ *
-+ * 1.2 How to use Debuggign strategy in driver development ?
-+ * =========================================================
-+ *
-+ * 1. include debug-nomadik.h file in c code
-+ *    (path: include/asm-arm/arch/nomadik/debug-nomadik.h)
-+ * 2. define NMDK_DEBUG to required debug level (this can be automated
-+ *    to pass build time debug levels -as done for keypad driver.
-+ *    See driver/input/keypad makefile)
-+ * 3. define NMDK_DEBUG_PFX to a small string to identify debug message
-+ *    This is an optional setting, if you don't define NMDK_DEBUG_PFX,
-+ *    by default "Nomadik" will be selected.
-+ * 4. define NMDK_DBG to desired Kerlen debug level
-+ *    This is an optional setting, if you don't define NMDK_DBG,
-+ *    by default KERN_DEBUG will be used
-+ *    This generally need to set to KERN_ERR to force debug messages to
-+ *    appear on the console
-+ *
-+ *
-+ * 1.3 How to activate debug messages?
-+ *====================================
-+ * 
-+ * Debug messages can be activated during build time by passing desired
-+ * debug level either hardcoding in source file or as a make parameter 
-+ *
-+ * 1. Enabling Debug messages by passing additional parameter to make
-+ *    This is a recommended method of debug messages implimentation.
-+ *    this method give flexibility to enable/disable debug messages 
-+ *    during build without modifying code
-+ *    (a) To enable this you need to updated driver make file with:-
-+ *    ex.
-+ *            ifdef <DRVNAME>_DEBUG
-+ *            CFLAGS += -<DRVNAME>_DEBUG=$(<DRVNAME>_DEBUG)
-+ *            endif
-+ *
-+ *    (b) Same <DRVNAME>_DEBUG must be used to define NMDK_DEBUG as
-+ *    explained in (1.2.2)
-+ *    (c) Debug parameter must be passed to the make with desired debug
-+ *    level as explained in (1.1)
-+ *            ex. make <DRVNAME>_DEBUG=1
-+ *    (d) you can AND several debug levels togather to enable respective 
-+ *    debug mesages
-+ *    (e) even you can pass additional parameters to enable debug messages
-+ *    of more than one module
-+ *            ex. make <DRV1>_DEBUG=1 <DRV2>_DEBUG=4 ...
-+ *
-+ * 2. Enabling Debug messages by hardcoding in source file
-+ *    This is simplest implimentation, just define NMDK_DEBUG to
-+ *    desired debug level and compile the code, the disadvantage of this
-+ *    method is, it does not offer flexibility and code with debug message
-+ *    may become part of your release if not taken care properly. 
-+ *
-+ */
+ void oprofile_arch_exit(void)
+ {
+--- linux-2.6.20.orig/drivers/Makefile
++++ linux-2.6.20/drivers/Makefile
+@@ -3,10 +3,11 @@
+ #
+ # 15 Sep 2000, Christoph Hellwig <hch@infradead.org>
+ # Rewritten to use lists instead of if-statements.
+ #
++obj-$(CONFIG_I2C)             += i2c/
+ obj-$(CONFIG_PCI)             += pci/
+ obj-$(CONFIG_PARISC)          += parisc/
+ obj-$(CONFIG_RAPIDIO)         += rapidio/
+ obj-y                         += video/
+ obj-$(CONFIG_ACPI)            += acpi/
+@@ -55,11 +56,10 @@ obj-$(CONFIG_USB_GADGET)   += usb/gadget/
+ obj-$(CONFIG_SERIO)           += input/serio/
+ obj-$(CONFIG_GAMEPORT)                += input/gameport/
+ obj-$(CONFIG_INPUT)           += input/
+ obj-$(CONFIG_I2O)             += message/
+ obj-$(CONFIG_RTC_LIB)         += rtc/
+-obj-$(CONFIG_I2C)             += i2c/
+ obj-$(CONFIG_W1)              += w1/
+ obj-$(CONFIG_HWMON)           += hwmon/
+ obj-$(CONFIG_PHONE)           += telephony/
+ obj-$(CONFIG_MD)              += md/
+ obj-$(CONFIG_BT)              += bluetooth/
+--- linux-2.6.20.orig/drivers/char/keyboard.c
++++ linux-2.6.20/drivers/char/keyboard.c
+@@ -1181,10 +1181,11 @@ static void kbd_keycode(unsigned int key
+       }
+       if (sysrq_down && !down && keycode == sysrq_alt_use)
+               sysrq_down = 0;
+       if (sysrq_down && down && !rep) {
+               handle_sysrq(kbd_sysrq_xlate[keycode], tty);
++              sysrq_down = 0;         /* In case we miss the 'up' event. */
+               return;
+       }
+ #endif
+ #ifdef CONFIG_SPARC
+       if (keycode == KEY_A && sparc_l1_a_state) {
+--- linux-2.6.20.orig/drivers/cpufreq/Kconfig
++++ linux-2.6.20/drivers/cpufreq/Kconfig
+@@ -138,6 +138,10 @@ config CPU_FREQ_GOV_CONSERVATIVE
+         For details, take a look at linux/Documentation/cpu-freq.
+         If in doubt, say N.
++config CPU_FREQ_NOMADIK
++        tristate "cpu freq scaling support for nomadik"
++        depends on CPU_FREQ
 +
+ endif # CPU_FREQ
+--- linux-2.6.20.orig/drivers/hwmon/Kconfig
++++ linux-2.6.20/drivers/hwmon/Kconfig
+@@ -228,10 +228,23 @@ config SENSORS_IT87
+         IT8716F and IT8718F sensor chips, and the SiS960 clone.
+         This driver can also be built as a module.  If so, the module
+         will be called it87.
++config SENSORS_LIS3LV02DL
++        tristate "LIS3LV02DL MEMS three-axis accelerometer I2C driver"
++        depends on HWMON && I2C && EXPERIMENTAL
++        default n
++        help
++          This driver provides support for the ST microelectronics LIS3LV02DL
++          MEMS inertial sensor which provides a three-axis, I2C controlled
++          Â± 2g/± 6g digital output linear accelerometer. The accelerometer
++          data is readable via sysfs.
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/dma_user_guide.txt       2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,420 @@
-+Filename:     ./Documentation/arm/STM-Nomadik/dma_user_guide.txt 
-+Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner:                STMicroelectronics
-+Purpose:
-+              This Users Guide explains DMA implimentation and its usage
-+              for client drivers on Nomadik platforms
-+=============================================================================
++          This driver can also be built as a module.  If so, the module
++          will be called lis3vl02dl.
 +
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
-+2. you are familier with Kernal DMA interface
-+      (References: ./Documentation/DMA-API.txt)
+ config SENSORS_LM63
+       tristate "National Semiconductor LM63"
+       depends on HWMON && I2C
+       help
+         If you say yes here you get support for the National Semiconductor
+--- linux-2.6.20.orig/drivers/hwmon/Makefile
++++ linux-2.6.20/drivers/hwmon/Makefile
+@@ -28,10 +28,11 @@ obj-$(CONFIG_SENSORS_FSCPOS)       += fscpos.o
+ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
+ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
+ obj-$(CONFIG_SENSORS_HDAPS)   += hdaps.o
+ obj-$(CONFIG_SENSORS_IT87)    += it87.o
+ obj-$(CONFIG_SENSORS_K8TEMP)  += k8temp.o
++obj-$(CONFIG_SENSORS_LIS3LV02DL)+= lis3lv02dl.o
+ obj-$(CONFIG_SENSORS_LM63)    += lm63.o
+ obj-$(CONFIG_SENSORS_LM70)    += lm70.o
+ obj-$(CONFIG_SENSORS_LM75)    += lm75.o
+ obj-$(CONFIG_SENSORS_LM77)    += lm77.o
+ obj-$(CONFIG_SENSORS_LM78)    += lm78.o
+--- /dev/null
++++ linux-2.6.20/drivers/hwmon/lis3lv02dl.c
+@@ -0,0 +1,489 @@
++/*
++    stmems.c
 +
-+DMA Configuration:
-+===================
-+By default Nomadik DMA driver is configured to link staticlly with kernel.
-+This DMA driver provides low level interface to the kernel DMA interface. 
-+To use DMA APIs, client driver should only include <asm/dma.h>
++    Copyright (c) 2008  Nicholas Angelo Crespi <roundtrip@gmail.com>
 +
-+Definations:
-+============
-+1. DMA Channel: The logical DMA channel can be used for a DMA transfer
-+2. Pipe: the physical DMA chanel H/w that is used to a DMA transfer
-+3. DMAC: Direct Memory Access Controller (Nomadik has two DMACs)
++    LIS3LV02DL MEMS inertial sensor is a 3-axis - Â± 2g/± 6g digital output
++    low voltage linear accelerometer.
++      http://www.st.com/stonline/products/literature/ds/12094/lis3lv02dl.htm
 +
-+Brief Architecture:
-+===================
-+DMA dirver is registered as amba device and will be probed only if
-+matches peripharal ID, the SOC specific data/function iterface is provided
-+through platfrom_data pointer to allign driver design in sync with multiboard
-+strategy.
-+There are two DMA controllers having 8 pipes each, there could be number of
-+dma channels which will use any one available pipe for dma transfer at run time
-+Kernel DMA interface defines and controls the interface, whereas the h/w
-+specific APIs are mapped through methods provided by upper layer (i,e.
-+arch/arm/kernel/dma.c). The configuration, usage and features provided by this
-+driver is explained below.
++    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 Users guide explains-
-+1. Support for Standard DMA APIs for Nomadik DMA usage
-+2. Additional DMA APIs to facilitate effieient/flexible DMA usage
-+3. DMA Channel configuration.
-+   a) Mode of operation: Transfer type
-+   b) Mode of operation: flow control
-+   c) Mode of operation: Double Buffered Transfer
-+   d) Mode of operation: Infinite DMA Transfer
-+   e) Mode of operation: Infinite DMA Transfer
-+   f) Mode of operation: Pipe reservation
-+   g) Mode of operation: Channel Priority
-+   h) Mode of operation: Queueing DMA transfer requests
-+4. DMA Interrupt hanndling for callback functions.
-+5. Scatter-gather Support
-+6. /proc/dma interfce.
-+7. HOWTO add new DMAable peripharal device support
++    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.
 +
-+1. Support for Standard DMA APIs for Nomadik DMA usage
-+======================================================
-+Standard kernel DMA interface exports APIs out of which request_dma, enable_dma,
-+disable_dma, free_dma, dma_channel_active, set_dma_sg, __set_dma_addr, set_dma_count,
-+are supported for Nomadik DMA Usage.
-+For any DMA transfer you need to follow a sequence-
-+  a) request_dma      : to request a DMA channel be to used for transfer,
-+                        in this request you need to pass configuration 
-+  b) request_irq      : to register DMA callback function 
-+  c) __set_dma_srcaddr        : to set src DMAble address (mapped to __set_dma_addr)
-+  d) __set_dma_destaddr       : to set dest DMAble address (mapped to set_dma_speed)
-+  e) set_dma_count    : to set transfer size in bytes
-+  f) set_dma_mode     : to set/ulter mode of operation (optional)
-+  g) enable_dma               : to start transfer
-+  h) dma_channel_active : to know the status of scheduled transfer (optional)
-+  i) disable dma      : to stop transfer (optional)
-+  j) free_irq         : to free irq used for callback (optional)
-+  k) free_dma         : to free requested DMA channel
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 +
-+2. Additional DMA APIs for effieient/flexible DMA usage
-+=======================================================
-+Following additional APIs are provided for effieient/flexible DMA usage
-+  a) request_available_dma
-+                      : This is a wrapper over request_dma,
-+                        this API will search, allocate and return available
-+                        free DMA channel.
-+  b) suspend_DMA      : to pause currently active DMA transfer
-+  c) resume_DMA               : to resume previously paused DMA transfer
++ * Compile this driver with:
 +
-+3. DMA Channel Configureation:
-+==============================
-+Durring request_dma system call you need to pass a pointer of pre-filled DMA
-+Channel configuration structure nmdk_dma_info defined in asm/arch/dma.h
-+i.e.-
-+struct nmdk_dma_info {
-+      u32 mode;               /* Mode of operation(xfer type/flow cntrl etc)*/
-+      char *srcdevtype;       /* source device type configuration*/
-+      char *destdevtype;      /* desitnation device type configuration*/
-+      u32 config;             /* User programmable dmadev configuration*/
-+};
++      echo "obj-m := tiny_i2c_chip.o" > Makefile
++      make -C <path/to/kernel/src> SUBDIRS=$PWD modules
++ */
 +
-+Each DMA channle has source DMA device and a destination DMA device, a DMA
-+channel is a hardware that connects two DMAable devices for data transfer.
-+So to have a successfull DMA transfer you need to configure all these three.
-+Below picture gives some idea about it-
++#define DEBUG 1
++#define VERSION "0.2"
 +
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <asm/arch/i2c.h>
 +
-+                      --------------------
-+   srcdevtype, src_addr |                | destdevtype, dest_addr
-+   def dmadev config  |                  | default dmadev configuration
-+                      |                  |
-+ (Src DMA periph)------>|    DMA Channel   |--------> (Dest DMA peripharal)
-+                      |                  |
-+                      --------------------
-+                      (mode of  operation)
-+                      (User configuration)
-+                      (Xfer Size in bytes)
++#define stmems_perror(format, arg...)
++//printk( KERN_ERR "STMEMS: %s " format, __func__, ## arg)
++#define stmems_pinfo(format, arg...)
++//printk( KERN_INFO "STMEMS: %s " format, __func__, ## arg)
 +
-+DMAable devices and their default configurations are SOC specific and declared
-+in arch/arm/mach-nomadik/<SOC_NAME>_devices.c file (will be explained latter
-+in this guide). Each DMAble device is identified by unique name, during
-+configuration the src and dest dmadev names need to be specified.
++/* Addresses to scan */
 +
-+Transfer Size in bytes, src_addr and dest_addr not a part of configuration as
-+they keeps changing and need to be provided before enable_dma request
++//static unsigned short normal_i2c[] = { 0x3A, I2C_CLIENT_END };
++static unsigned short normal_i2c[] = { 0x1D, I2C_CLIENT_END };
 +
-+User programmable dmadev configuration: These are optional configuration on 
-+the top of default for the changable paramters (specially Brust size and
-+transfer width). This will be exmpained latter in this guide
-+ 
-+for ex, to configure a dma chnnel for memory to MSP peripharal DMA transfer
-+the sructure should be filled as-
++//static unsigned short normal_i2c_range[] = { 0x00, 0xff, I2C_CLIENT_END };
 +
-+      struct nmdk_dma_info test_dma_config =
-+      {
-+              .mode    = MEM_TO_MEM,
-+              .srcdevtype = "mem",
-+              .destdevtype = "msp0rx",
-+              .config = NULL,
-+      };
-+                      
-+Out of all configuration parameter "mode" is very important since it decides
-+the mode of DMA channel operation, there are several features supported all
-+are configurable through mode.
++/* Insmod parameters */
++I2C_CLIENT_INSMOD_1(stmems);
 +
-+   a) Mode of operation: Transfer type
-+      there are four basic modes of operation those are
-+      MEM_TO_MEM,     MEM_TO_PERIPH,  PERIPH_TO_MEM,  PERIPH_TO_PERIPH
-+      you should program any one as per you need.
++/* Each client has this additional data */
++struct stmems_data {
++      struct i2c_client client;
++      struct class_device *class_dev;
++      struct mutex update_lock;
++      char valid;                     /* !=0 if following fields are valid */
++      unsigned long last_updated;     /* In jiffies */
++      int acc_x;                      /* Register values */
++      int acc_y;
++      int acc_z;
++      u8 divisor;
++      u8 fullscale;
++      u8 BDU;
++};
 +
-+      for ex. dma_info.mode=MEM_TO_PERIPH;
++/* stmems registers mnemonics */
++/*      mnemonic             hex    r/w    default  */
++#define MEMS_WHO_AM_I        0x0F /*r      00111010 */
++#define MEMS_OFFSET_X        0x16 /*rw     calib    */
++#define MEMS_OFFSET_Y        0x17 /*rw     calib    */
++#define MEMS_OFFSET_Z        0x18 /*rw     calib    */
++#define MEMS_GAIN_X          0x19 /*rw     calib    */
++#define MEMS_GAIN_Y          0x1A /*rw     calib    */
++#define MEMS_GAIN_Z          0x1B /*rw     calib    */
++#define MEMS_CTRL_REG1       0x20 /*rw     00000111 */
++#define MEMS_CTRL_REG2       0x21 /*rw     00000000 */
++#define MEMS_CTRL_REG3       0x22 /*rw     00001000 */
++#define MEMS_HP_FILTER RESET 0x23 /*r      dummy    */
++#define MEMS_STATUS_REG      0x27 /*rw     00000000 */
++#define MEMS_OUTX_L          0x28 /*r               */
++#define MEMS_OUTX_H          0x29 /*r               */
++#define MEMS_OUTY_L          0x2A /*r               */
++#define MEMS_OUTY_H          0x2B /*r               */
++#define MEMS_OUTZ_L          0x2C /*r               */
++#define MEMS_OUTZ_H          0x2D /*r               */
++#define MEMS_FF_WU_CFG       0x30 /*rw     00000000 */
++#define MEMS_FF_WU_SRC       0x31 /*rw     00000000 */
++#define MEMS_FF_WU_ACK       0x32 /*r               */
++#define MEMS_FF_WU_THS_L     0x34 /*rw     00000000 */
++#define MEMS_FF_WU_THS_H     0x35 /*rw     00000000 */
++#define MEMS_FF_WU_DURATION  0x36 /*rw     00000000 */
++#define MEMS_DD_CFG          0x38 /*rw     00000000 */
++#define MEMS_DD_SRC          0x39 /*rw     00000000 */
++#define MEMS_DD_ACK          0x3A /*r               */
++#define MEMS_DD_THSI_L       0x3C /*rw     00000000 */
++#define MEMS_DD_THSI_H       0x3D /*rw     00000000 */
++#define MEMS_DD_THSE_L       0x3E /*rw     00000000 */
++#define MEMS_DD_THSE_H       0x3F /*rw     00000000 */
 +
-+   b) Mode of operation: flow control
-+      By default flow controller is DMA controller, if you want to program
-+      flow controller as peripharal you can use the provided macros as
 +
-+      for ex. dma_info.mode=FLOW_CNTRL_DMA(MEM_TO_PERIPH);
-+      To mention the flow controller is DMA controller.
++static int stmems_attach_adapter(struct i2c_adapter *adapter);
++static int stmems_detect(struct i2c_adapter *adapter, int address, int kind);
++static int stmems_detach_client(struct i2c_client *client);
++static void stmems_init_sensor(struct i2c_client *client);
++static inline u8 stmems_read_value(struct i2c_client *client, u8 reg);
++static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value);
++static inline int stmems_join(u8 LSB, u8 MSB);
++static struct stmems_data *stmems_update_device(struct device *dev);
 +
-+      for ex. dma_info.mode=FLOW_CNTRL_PERIPH(MEM_TO_PERIPH);
-+      To mention the flow controller is peripharal controller.
++/* This is the driver that will be inserted */
++static struct i2c_driver stmems_driver = {
++      .driver = {
++              .name   = "stmems",
++      },
++      .attach_adapter = stmems_attach_adapter,
++      .detach_client  = stmems_detach_client,
++};
 +
-+      Flow controller device cannot be peripharal for MEM_TO_MEM transter
++/* read routines for accelerations */
++#define show(value)   \
++static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)     \
++{                                                             \
++      struct stmems_data *data = stmems_update_device(dev);   \
++      return sprintf(buf, "%d\n", data->value);               \
++}
++show(acc_x);
++show(acc_y);
++show(acc_z);
 +
-+   c) Mode of operation: Double Buffered Transfer
-+      There are some peripharals like SAA(Smart Audio Accelerator) who 
-+      requires DMA transfers to be done in double buffer mode, in double
-+      buffered mode of operation the current dma requested in divided in two,
-+      equal sequential transfers before scheduling.
++/* read routines for divisor, BDU and fullscale */
++static ssize_t show_divisor(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      if (!(data->valid))
++              data = stmems_update_device(dev);
++      return sprintf(buf, "%d\n", data->divisor);
++}
 +
-+      By default standard single buffered transfer mode is programmed,
-+      to configure Double Buffered Transfer mode a macro DMA_DOUBLE_BUFFERED
-+      should be ORed with other configuration parameters
++static ssize_t show_fullscale(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      if (!(data->valid))
++              data=stmems_update_device(dev);
++      return sprintf(buf, "%d\n", data->fullscale);
++}
++static ssize_t show_BDU(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      if (!(data->valid))
++              data=stmems_update_device(dev);
++      return sprintf(buf, "%d\n", data->BDU);
++}
 +
-+      for ex. dma_info.mode=DMA_DOUBLE_BUFFERED |
-+                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++/* this macro is useless! */
++#define set(value, reg)       \
++static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
++{                                                                     \
++      struct i2c_client *client = to_i2c_client(dev);                 \
++      struct stmems_data *data = i2c_get_clientdata(client);          \
++      int temp = simple_strtoul(buf, NULL, 10);                       \
++                                                                      \
++      mutex_lock(&data->update_lock);                                 \
++      data->value = temp;                                             \
++      mutex_unlock(&data->update_lock);                               \
++      return count;                                                   \
++}
 +
-+   d) Mode of operation: Infinite DMA Transfer
-+      If you want to establish DMA transafer between two DMAble devices
-+      infinitely without CPUs intervention, this means once transfer is
-+      scheduled, it will reschedule it self at completion automatically.
++/* Write routines for divisor, BDU and fullscale */
++static ssize_t set_divisor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      u8 ctrl_reg;
++      int temp = simple_strtoul(buf, NULL, 10);
++      /* the divisor input can only be 512,128,32 or 8 */
++      if ((temp!= 8) && (temp!= 32) && (temp!= 128) && (temp!= 512)) return 0;
++      mutex_lock(&data->update_lock);
++      data->divisor = temp;
++      ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG1);
++      if (temp == 8) {ctrl_reg |= 0x30;}
++      else if (temp == 32) {ctrl_reg |= 0x20; ctrl_reg &= 0xEF;}
++      else if (temp == 128) {ctrl_reg |= 0x10; ctrl_reg &= 0xDF;}
++      else {ctrl_reg &= 0xCF; }
++      stmems_write_value(client,MEMS_CTRL_REG1,ctrl_reg);
++      mutex_unlock(&data->update_lock);
++      return count;
++}
 +
-+      By default infinite DMA transfer is disabled,
-+      to configure Infinite DMA Transfer mode a macro DMA_INFINITE_XFER
-+      should be ORed with other configuration parameters
++static ssize_t set_fullscale(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      u8 ctrl_reg;
++      int temp = simple_strtoul(buf, NULL, 10);
++      if ((temp!= 1) && (temp!= 0)) return 0;
++      mutex_lock(&data->update_lock);
++      data->fullscale = temp;
++      ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
++      if (temp) {ctrl_reg |= 0x80;}
++      else {ctrl_reg &= 0x7F; }
++      stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
++      mutex_unlock(&data->update_lock);
++      return count;
++}
 +
-+      for ex. dma_info.mode=DMA_INFINITE_XFER |
-+                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++static ssize_t set_BDU(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      u8 ctrl_reg;
++      int temp = simple_strtoul(buf, NULL, 10);
++      if ((temp!= 1) && (temp!= 0)) return 0;
++      mutex_lock(&data->update_lock);
++      data->BDU = temp;
++      ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
++      if (temp) {ctrl_reg |= 0x40;}
++      else {ctrl_reg &= 0xBF; }
++      stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
++      mutex_unlock(&data->update_lock);
++      return count;
++}
 +
-+      In Infinite DMA transfer mode, you will never receive completion
-+      interrupt and callback interrupt handler cannot be executed
++static DEVICE_ATTR(acc_x, S_IRUGO,
++                 show_acc_x, NULL);
++static DEVICE_ATTR(acc_y, S_IRUGO,
++                 show_acc_y, NULL);
++static DEVICE_ATTR(acc_z, S_IRUGO,
++                 show_acc_z, NULL);
 +
-+   e) Mode of operation: Pipe reservation
-+      Reserving a pipe will dediate a pipe for a channel
-+      By default pipe is not reserved at the time of configuration. when you
-+      schedule a enable_dma request, system looks for the available pipe and
-+      schedules a transfer on it. This adds more flexibility to system to
-+      handle more channels on limited pipes. In case the all the pipes are
-+      busy the request will be deffered,
-+      if you want to avoid this behavior, i.e. whenever you request enable_dma
-+      pipe must be available to execute it, then you can reserve a pipe during
-+      configuration.
++static DEVICE_ATTR(fullscale, S_IWUSR | S_IRUGO,
++                 show_fullscale, set_fullscale);
++static DEVICE_ATTR(divisor, S_IWUSR | S_IRUGO,
++                 show_divisor, set_divisor);
++static DEVICE_ATTR(BDU, S_IWUSR | S_IRUGO,
++                 show_BDU, set_BDU);
 +
-+      to reserve a pipe, a macro DMA_PIPE_RESERVED
-+      should be ORed with other configuration parameters
++static int stmems_attach_adapter(struct i2c_adapter *adapter)
++{
++      int err;
 +
-+      for ex. dma_info.mode=DMA_PIPE_RESERVED |
-+                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++      stmems_pinfo("entered\n");
++      stmems_pinfo("adapter class: %d\n", adapter->class);
 +
-+   g) Mode of operation: Channel Priority
-+      At hardware level there are total 16 DMA pipes (i.e. 8 on each
-+      DMAC) each having its priority (i.e. pipe 0 having highest and 7 with
-+      lowest). but since the pipes are allocated dynamically you never know 
-+      which pipe will be assigned to which channel. To take care of this
-+      issue driver has in-built channel priority policy manager
++      if (!(adapter->class & I2C_CLASS_HWMON))
++      {
++              stmems_perror("adapter class is not HWMON skip\n");
++              return 0;
++      }
 +
-+      Priority        DMAC0 PIPES     DMAC1 PIPES     Policy
-+              -----------------------------------------------------
-+      Highest         | 0  |          | 1  |          HIGH
-+      .               | 2  |          | 3  |          (0->15)
-+      .       -----------------------------------------------------
-+      .               | 4  |          | 5  |          NORMAL
-+      .               | 6  |          | 7  |          (4->15)
-+      .       -----------------------------------------------------
-+      .               | 8  |          | 9  |          LOW
-+      .               | 10 |          | 11 |          (8->15)
-+      .       -----------------------------------------------------
-+      .               | 12 |          | 13 |  UNDEFINED (fm 15->0)
-+      Lowest          | 14 |          | 15 |  For MEM-To MEM Xfer (15->12)
-+              -----------------------------------------------------
++      err = i2c_probe(adapter, &addr_data, stmems_detect);
 +
-+      Channel priority setup during configuration tells additional
-+      information to the driver that the channel under request has a
-+      particular priority. And the pipe allocation policy of a driver
-+      allocates a pipe accordingly for a transfer under schedule.
++      return err;
++}
 +
-+      By default DMA_EXCH_PRIORITY_UNDEFINED is set for each channel, as
-+      per policy the free and available pipe search will be started from 
-+      lowest to highest.
-+      there are three other priorities HIGH, NORMAL and LOW which can be set
-+      by ORing respective macro with other configuration parameters
 +
-+      for ex. dma_info.mode=DMA_EXCH_PRIORITY_HIGH |
-+                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++/* This function is called by i2c_probe */
++static int stmems_detect(struct i2c_adapter *adapter, int address, int kind)
++{
++      struct i2c_client *new_client = NULL;
++      struct stmems_data *data = NULL;
++      int err = 0;
++      u8 temp_reg;
++      int ret;
 +
-+      Channel priority setup macros for configurations-
-+      DMA_EXCH_PRIORITY_UNDEFINED
-+      DMA_EXCH_PRIORITY_LOW    
-+      DMA_EXCH_PRIORITY_NORMAL
-+      DMA_EXCH_PRIORITY_HIGH
 +
-+   h) Mode of operation: Queueing DMA transfer requests
-+      In the standard kernel DMA interface channel queueing is not allowed
-+      once enable_dma request is executed system discards all subsequent 
-+      enable_dma request untill DMA finishes first scheduled request.
-+      Nomadik DMA driver provides you flexibility to enable and use this
-+      feature if required. Enabling this feature will accept all subsequent
-+      enable_dma requests and queue them in a pipe, as system finishes
-+      current transfer, next pre-scheduled transfer in a queue will be 
-+      executed, thus all enable_dma requests can be processed.
++      stmems_pinfo("entered\n");
 +
-+      This feature can be enabled by ORing a macro DMA_QUEUE_ENABLED with 
-+      other configuration parameters
++      stmems_pinfo("kind: %d\n", kind);
++      stmems_pinfo("address: %d\n", address);
 +
-+      for ex. dma_info.mode=DMA_QUEUE_ENABLED |
-+                              FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++      {
++              stmems_perror("no SMBUS BYTE functionality detected\n");
++              goto error;
++      }
 +
-+4. DMA Interrupt hanndling for callback functions.
-+======================================================
-+When you schedule a DMA transfer, there should be a mechanism by which you know
-+the transfer is finished sucessfully. In Nomadik DMA transfer a terminal
-+count interrupt will be generated at the end of sucessfull transfer which can 
-+be requested and processed like any other standard interrupt.
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE))
++      {
++              stmems_perror("no SMBUS READ BYTE DATA functionality detected\n");
++              goto error;
++      }
 +
-+There are S/w decoded IRQs associated with all DMA channels.
-+the macro IRQNO_FOR_DMACH(dmach) is provided to find irq for a DMA channel and
-+the macro DMACH_FOR_IRQNO(irq) can be used to find DMA channel for irq number
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA))
++      {
++              stmems_perror("no SMBUS READ BYTE functionality detected\n");
++              goto error;
++      }
 +
-+The DMA callback functions can be invoked as interrupt handler and requested 
-+through standard system calls i.e request_irq and free_irq.
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
++      {
++              stmems_perror("no SMBUS WRITE BYTE DATA functionality detected\n");
++              goto error;
++      }
 +
-+It is recommented to use your own tasklets to do deffered processing
-+since it may block other DMA interuppts being processed in time.
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
++      {
++              stmems_perror("no SMBUS WRITE BYTE functionality detected\n");
++              goto error;
++      }
 +
-+Below system messages indicates that irqno 188 to 191 are DMA interrupts
-+root@NDK10_A0:/home/prafulla/alsa# cat /proc/interrupts
-+           CPU0
-+  4:      12077:PL02          -  Nomadik Timer Tick
-+ 10:          0               -  rtc
-+ 11:          0               -  ssp
-+ 17:        581:PL08          -  uart-pl011
-+ 19:          6:PL10          -  msp
-+ 20:         33               -  i2c0
-+ 21:        296               -  i2c1
-+ 22:         81:PL02          -  NMDK_MMC (data)
-+ 26:          1               -  SAA0
-+ 27:          0               -  SAA1
-+113:          0               -  mmc_detect
-+168:      19176:PL08          -  eth0
-+188:         46           dummy  dmaclbk-sdmmc->mem
-+189:          0           dummy  <NULL>
-+190:      10462           dummy  dmaclbk-msp0rx->mem
-+191:      10437           dummy  dmaclbk-mem->msp0tx
-+Err:          0
++      /* OK. For now, we presume we have a valid client. We now create the
++         client structure, even though we cannot fill it completely yet.
++         But it allows us to access stmems_{read,write}_value. */
++      data = kzalloc(sizeof(struct stmems_data), GFP_KERNEL);
++      if (!data) {
++              err = -ENOMEM;
++              goto error;
++      }
 +
-+5. Scatter-gather Support
-+======================================================
-+The Nomadik DMA driver supprts scatter-gather transfer for MEM_TO_PERIPH and
-+PERIPH_TO_MEM type of data transfer. to use scatter gather suport following
-+sequence must be executed.
-+      a) request_dma, request_irq
-+      b) get the *sg and sg_len form the upper layers
-+      c) execute dma_map_sg with above information
-+      d) set peripharal DMA address (__set_dma_srcaddr / __set_dma_srcaddr)
-+      e) set memory DMA address using set_dma_sg API with sg information
-+      f) set_dma_count for transfer size
-+      g) execute enable_dma
-+      h) wait for transfer complete event through callback
-+      i) unmap sg list using dma_unmap_sg 
-+      j) free_dma
++      memset(data, 0x00, sizeof(*data));
 +
-+6. /proc/dma interfce.
-+======================================================
-+/proc/dma entry is created to show the information of allocated DMA resources
-+executing cat /proc/dma will list the allocation of all used DMA channles
++      new_client = &data->client;
++      i2c_set_clientdata(new_client, data);
++      new_client->addr = address;
++      new_client->adapter = adapter;
++      new_client->driver = &stmems_driver;
++      new_client->flags = 0;
 +
-+for ex-
-+root@NDK10_A0:/home/prafulla/alsa# cat /proc/dma
-+ 0:         DMACH: sdmmc->mem
-+ 1:         DMACH: mem->sdmmc
-+ 2:         DMACH: msp0rx->mem
-+ 3:         DMACH: mem->msp0tx
++      /* Chip detection:
++         since the chip has a register that holds its hardware address,
++         we use that as an identification field. */
++      if (kind < 0){
++              temp_reg = stmems_read_value(new_client, MEMS_WHO_AM_I);
++              //if ( (int)temp_reg != address)
++              //      goto free_error;
++      }
 +
-+7. HOWTO add new DMA peripharal device support
-+======================================================
-+As per multiboard strategy
-+(ref : ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt)
-+for each supported SOC there is an arch/arm/mach-nomadik/<SOC>_devices.c
-+In this file there is data structure "dmadev_default_config_tbl" 
-+Add a new entry for the table for new DMA peripharal device
-+(refer Architecture.DMA Support Chapter fo SOC specification)
++      /* Fill in the remaining client fields */
++      strncpy(new_client->name, "stmems", I2C_NAME_SIZE);
++      data->valid = 0;
++      mutex_init(&data->update_lock);
 +
-+for ex-
-+      {.id = "sdmmc",
-+         .config = ( DMA_AHB_M0 | DMA_ADR_NOINC | DMA_WIDTH_WORD |
-+                DMA_BSIZE_8 | DMA_REQUEST_LINE(21) |
-+              DMA_DEV_BSIZE_CONFIGURABLE | DMA_DEV_WIDTH_CONFIGURABLE |
-+                DMA_DEV_DMAC1_CANBE_USED  ),},
++      /* Tell the I2C layer a new client has arrived */
++      err = i2c_attach_client(new_client);
++      if (err)
++              goto error;
 +
-+      explaination:
-+      id:     This is the unique identification string will be used in
-+              configuration as srcdevtype or destdevtype.
-+      config: This should be ORed value of following selection
-+          a)  DMA_AHB_M0      : to select AHB master 0 for this device
-+              or
-+              DMA_AHB_M1      : to select AHB master 1 for this device
++      /* Initialize the chip */
++      stmems_init_sensor(new_client);
 +
-+          b)  DMA_ADR_INC     : to indicate DMA address is incremented after
-+                                each transfer (memory, buffer case)
-+              or
-+              DMA_ADR_NOINC   : to indicate DMA address is not incremented
-+                                after each transfer (fifo case)
++      /* Register sysfs hooks */
++      data->class_dev = hwmon_device_register(&new_client->dev);
++      if (IS_ERR(data->class_dev)) {
++              err = PTR_ERR(data->class_dev);
++              goto detach_error;
++      }
 +
-+          c)  DMA_WIDTH_WORD  : to select word(32bits) as transfer width
-+              or
-+              DMA_WIDTH_HALFWORD: to select halfword(16bits) as transfer width
-+              or
-+              DMA_WIDTH_BYTE  : to select byte(8bits) as transfer width
-+      
-+          d)  DMA_BSIZE_1     : to indicate 1 byte makes one DMA brust
-+              or
-+              DMA_BSIZE_4     : to indicate 4 bytes makes one DMA brust
-+              or
-+              DMA_BSIZE_8     : to indicate 8 bytes makes one DMA brust
-+              or
-+              DMA_BSIZE_16    : to indicate 16 bytes makes one DMA brust
-+              or
-+              DMA_BSIZE_32    : to indicate 32 bytes makes one DMA brust
-+              or
-+              DMA_BSIZE_64    : to indicate 64 bytes makes one DMA brust
-+              or
-+              DMA_BSIZE_128   : to indicate 128 bytes makes one DMA brust
-+              or
-+              DMA_BSIZE_256   : to indicate 256 bytes makes one DMA brust
++      ret = device_create_file(&new_client->dev, &dev_attr_acc_x);
++      ret = device_create_file(&new_client->dev, &dev_attr_acc_y);
++      ret = device_create_file(&new_client->dev, &dev_attr_acc_z);
++      ret = device_create_file(&new_client->dev, &dev_attr_divisor);
++      ret = device_create_file(&new_client->dev, &dev_attr_fullscale);
++      ret = device_create_file(&new_client->dev, &dev_attr_BDU);
++      return 0;
 +
-+          e)  DMA_REQUEST_LINE(x) : program peripharal request line number
-+                                    (x less than 32)
++detach_error:
++      i2c_detach_client(new_client);
++//free_error:
++      kfree(data);
++error:
++      return err;
++}
 +
-+          f)  DMA_DEV_BSIZE_CONFIGURABLE: to indicate the burst size can be
-+                                probrammed by user
-+              or
-+              DMA_DEV_BSIZE_NOT_CONFIGURABLE: to indicate the burst size can
-+                                not be probrammed by user
-+          g)  DMA_DEV_DWIDTH_CONFIGURABLE: to indicate the transfer width can
-+                                be probrammed by user
-+              or
-+              DMA_DEV_DWIDTH_NOT_CONFIGURABLE: to indicate the transfer width
-+                                can not be probrammed by user
++//TODO: powerdown
++static int stmems_detach_client(struct i2c_client *client)
++{
++      struct stmems_data *data =   i2c_get_clientdata(client);
++      hwmon_device_unregister(data->class_dev);
++      i2c_detach_client(client);
++      kfree(data);
++      return 0;
++}
 +
-+          h)  DMA_DEV_DMAC1_CANBE_USED: to indicate DMA controller1 can be 
-+                                used for the transfer
-+              or
-+              DMA_DEV_DMAC0_CANBE_USED: to indicate DMA controller0 can be 
-+                                used for the transfer
-+              or
-+              DMA_DEV_BOTH_DMACS_CANBE_USED: to indicate both DMA controllers
-+                                0 and 1 can be used for the transfer
++/* Configure the chip, mainly with default values */
++static void stmems_init_sensor(struct i2c_client *client){
++      u8 conf_reg;
++      /* CTRL_REG1: enable axis, turn down powerdown mode, freq divisor 512 */
 +
-+8. System Limitations and Solutions:
-+=====================================
-+1. MAX_DMA_CHANNELS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
-+     that defiens max no. of dma channels that can be used simultenously. if in 
-+     complex system scenario these channels are insuffienent, you may increase
-+     this number as per your needs.
-+2. MAX_DMA_LLIS: This macro is defined (include/asm-arm/arch-nomadik/dma.h)
-+     that defiens max no. of LLIs used internally by dma driver. lli pool is 
-+     internally maitained by driver and aquired whenver there is a enable_dma
-+     request and freed at each dma transfer completion. In a dynamic system
-+     usage a run time message "unable to find free lli.. rechecking..." can be
-+     observed, if such case you may increase the defined value for this macro,
-+     Assiging very large value eats free DMAble memory.
++      conf_reg = 0xC7;
 +
-+==============================================================================
++      stmems_pinfo("entered\n");
 +
++      stmems_write_value(client, MEMS_CTRL_REG1, conf_reg);
++      /* CTRL_REG2: fullscale 2g, batch update, big endian, disable INT,
++         12bit right-justified, */
++      conf_reg  = stmems_read_value(client, MEMS_CTRL_REG2);
++      conf_reg = 0x60;
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/faqs.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,53 @@
-+Filename:     ./Documentation/arm/STM-Nomadik/faqs.txt 
-+Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner:                STMicroelectronics
-+Purpose:
-+              This documents describes frequesnty occuring problems and
-+              their brief solutions while using Nomadik-BSP
-+=============================================================================
++      stmems_write_value(client, MEMS_CTRL_REG2, conf_reg);
++      /* CTRL_REG3:  disable interrupts generation, leave others values*/
++      conf_reg = stmems_read_value(client, MEMS_CTRL_REG3);
++      conf_reg &= 0x8F;
++      stmems_write_value(client, MEMS_CTRL_REG3, conf_reg);
++      return;
++}
 +
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++static struct stmems_data *stmems_update_device(struct device *dev)
++{
++      struct i2c_client *client = to_i2c_client(dev);
++      struct stmems_data *data = i2c_get_clientdata(client);
++      u8 status_reg;
 +
-+F.A.Qs
-+======
-+Q: I am not getting console on CLCD even though CLCD is enabled
-+A: check your command line arguments, there should not be any console related
-+   configuration, in this case by default console will be configured to CLCD.
-+   In this case system will seek console input from standard input device.
++      stmems_pinfo("entered\n");
 +
-+Q: NFS boot is giving messages "server not responding" very frequently
-+A: This may be due to network congestion, try NFS boot using "tcp" option
-+   (Ex. root=/dev/nfs nfsroot=<server_ipadr>:<mount_point_path>,tcp
-+    ip=<host_ipadr>:<server_ipadr>:<gateway_ipard>:255.255.255.0:<hostname>:: 
-+    console=ttyAMA1 mem=64M init=linuxrc)
++      mutex_lock(&data->update_lock);
++      dev_dbg(&client->dev, "%s\n", __FUNCTION__);
++      status_reg = stmems_read_value(client, MEMS_STATUS_REG);
++      //TODO: we're assuming big endianess
++      //TODO: use 0x08 instead
++      if (status_reg & 0x01)
++              data->acc_x = stmems_join(stmems_read_value(client, MEMS_OUTX_H), stmems_read_value(client, MEMS_OUTX_L));
++      if (status_reg & 0x02)
++              data->acc_y = stmems_join(stmems_read_value(client, MEMS_OUTY_H), stmems_read_value(client, MEMS_OUTY_L));
++      if (status_reg & 0x04)
++              data->acc_z = stmems_join(stmems_read_value(client, MEMS_OUTZ_H), stmems_read_value(client, MEMS_OUTZ_L));
++      data->last_updated = jiffies;
++      data->valid = 1;
++      mutex_unlock(&data->update_lock);
 +
-+Q.  How to enable/Disable cursor on CLCD panel?
-+A. Create a dummy node "mknod /dev/dummy c 4 0 ".
-+   execute a command "echo -e "\033[?1c" > /dev/dummy" to disable the cursor
-+   and "echo -e "\033[?0c" > /dev/dummy" to enable the cursor
-+   You can also use the "setterm" program to control this and other aspects of
-+   the console. "setterm -cursor off > /dev/tty0" will do what you want.
-+   "man setterm" will give a vast list of stuff.
-+   There is more here:
-+   http://linux.bri.st.com/docs/manual/distribution/distribution_guide10.php
++      if (data)
++      {
++              stmems_pinfo("acc_x: %d\n", data->acc_x);
++              stmems_pinfo("acc_y: %d\n", data->acc_y);
++              stmems_pinfo("acc_z: %d\n", data->acc_z);
++      }
 +
-+Q. How to disable CLCD screen blanking
-+A. Create a dummy node "mknod /dev/dummy c 4 0 ". 
-+   Execute a command "echo -e "\033[9;0]" > /dev/dummy", this will set
-+   screen blanking interval to 0 and will not blank the screen at all.
++      return data;
++}
 +
-+Q. Generally when the kernel is up and running, CLCD is active but after some
-+   time screen gets blanked, How to unblank the already blanked CLCD screen ?
-+A. Create a dummy node "mknod /dev/dummy c 4 0 ". 
-+   Execute a command "echo -e "\033[13]" > /dev/dummy", this will activate
-+   CLCD screen.
++/* All registers are byte-sized */
++static inline u8 stmems_read_value(struct i2c_client *client, u8 reg)
++{
++      u8 temp;
 +
-+Q. How to enable L2 Cache for Nomadik SOCs
-+A. Switch to kernel source path, execute "make menuconfig"
-+   Enable option "Enable L2 Cache controller" at location "x -> System Type"
-+   L2CC is not available on STn8810 SOC versions
++      stmems_pinfo("reading: 0x%02X\n", reg);
++      temp = i2c_smbus_read_byte_data(client, reg);
++      //nomadik_i2c_read_register(I2C_MEMS_CLIENT,&temp,reg,1);
++      stmems_pinfo("read: 0x%02X, value: 0x%02X\n", reg, temp);
 +
-+==============================================================================
++      return temp;
++}
 +
++static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value)
++{
++      stmems_pinfo("writing: 0x%02X, value: 0x%02X\n", reg, value);
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/gpio_user_guide.txt      2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,140 @@
-+Filename: ./Documentation/arm/STM-Nomadik/gpio_user_guide.txt 
-+Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner:                STMicroelectronics
-+Purpose:
-+              This Users Guide explains GPIO implimentation and its usage
-+              from other drivers for Nomadik platforms
-+=============================================================================
++      return i2c_smbus_write_byte_data(client, reg, value);
++      //return nomadik_i2c_write_register(I2C_MEMS_CLIENT,&value,reg,1);
++}
 +
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++static int __init stmems_init(void)
++{
++      stmems_pinfo("entered\n");
 +
-+GPIO Configuration:
-+===================
-+By default GPIO driver is configured to link staticlly with kernel becasue
-+it is tightly coupled with irq.c. GPIO is necessary for Nomadik architecture
++      return i2c_add_driver(&stmems_driver);
++}
 +
-+Brief Architecture:
-+GPIO dirver is registered as amba device and will be probed only if
-+matches peripharal ID, the SOC specific data and function iterface is provided
-+through platfrom_data pointer to allign driver code in sync with multiboard
-+strategy.
++static void __exit stmems_exit(void)
++{
++      stmems_pinfo("entered\n");
 +
-+GPIO driver mainly provides two kinds of functionality
-+1. GPIO Interrupt hanndling and control.
-+2. Exported GPIO APIs
-+      2.1 Usage of GPIO pins/block for read write APIs
-+      2.2 Configuration for Alternate functions APIs
++      i2c_del_driver(&stmems_driver);
++}
 +
-+1. GPIO Interrupt hanndling and control:-
-+==============================================
-+VIC generates a common interrupt for all 32 pins in a block, there are such
-+three to four blocks in a SOC, Each GPIO interrupt can be considered as
-+standard IRQ and can be processed through generic system call (please refer
-+irq_usrguide.txt). Further GPIO interrupts are softdecoded hence canot be
-+programmed as priority interrupts individually,
++static inline int stmems_join(u8 LSB, u8 MSB)
++{
++      /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
++      if (MSB & 0x10)
++      MSB |= 0xE0;
++      return (s16)(LSB | ((MSB << 8)));
++}
 +
-+2. Exported GPIO APIs
-+=====================
-+All exported GPIOs are protected against call before initialization. This
-+means if the GPIO driver cannot be probled due to any reasons and you try to 
-+use GPIO exported APIs, and error will be returned.
-+APIS nomadik_gpio_readpin and nomadik_gpio_readblock are not protected against 
-+interrupt configuration becasue reading a GPIO does not harm its usage from
-+other context. Where as all other APIS are protected against interrupt
-+cnfiguration. This means if the interrupt is already requested on a GPIO pin
-+the same pin cannot be configured untill you free that interrupt.
++MODULE_AUTHOR("Nicholas Angelo Crespi <roundtrip@gmail.com>");
++MODULE_DESCRIPTION("LIS3LV02DL MEMS three-axis accelerometer I2C driver");
++MODULE_VERSION(VERSION);
++MODULE_LICENSE("GPL");
 +
-+2.1 Usage of GPIO pins/block for read write APIs
-+================================================
-+      a) nomadik_gpio_setpinconfig:
-+              Individual pin can be configured for desired operation.
-+      for ex. 
-+      mmc_pin.dev_name = "test";
-+      mmc_pin.mode = GPIO_MODE_SOFTWARE;
-+      mmc_pin.direction = GPIO_DIR_OUTPUT;
-+      mmc_pin.debounce = GPIO_DEBOUNCE_ENABLE;
-+      mmc_pin.debounce_time = GPIO_DEBOUNCE_TIME_60_MICROSEC;
-+      ret = nomadik_gpio_setpinconfig(GPIO_PIN_75, &mmc_pin);
++module_init(stmems_init);
++module_exit(stmems_exit);
+--- linux-2.6.20.orig/drivers/i2c/Kconfig
++++ linux-2.6.20/drivers/i2c/Kconfig
+@@ -32,10 +32,11 @@ config I2C_CHARDEV
+         contained in the file <file:Documentation/i2c/dev-interface>.
+         This support is also available as a module.  If so, the module 
+         will be called i2c-dev.
 +
-+      The above code will configure GPIO_PIN_75 in GPIO mode used as output
-+      pin, enabled debouncing logic and set debounce time to 60 miroseconds.
-+      debounce logic will be enabled if supported by the SOC version.
-+      dev_name is a client device name to which the GPIO will be allocated.
-+ 
-+      b) nomadik_gpio_resetpinconfig:
-+              sets the particular pin to its reset state.
+ source drivers/i2c/algos/Kconfig
+ source drivers/i2c/busses/Kconfig
+ source drivers/i2c/chips/Kconfig
+ config I2C_DEBUG_CORE
+--- linux-2.6.20.orig/drivers/i2c/Makefile
++++ linux-2.6.20/drivers/i2c/Makefile
+@@ -1,11 +1,12 @@
+ #
+-# Makefile for the i2c core.
++# Makefile for the kernel i2c bus driver.
+ #
+ obj-$(CONFIG_I2C)             += i2c-core.o
+ obj-$(CONFIG_I2C_CHARDEV)     += i2c-dev.o
 +
-+      c) nomadik_gpio_writepin;
-+              write HIGN or LOW value on specified pin
+ obj-y                         += busses/ chips/ algos/
+ ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+--- linux-2.6.20.orig/drivers/i2c/busses/Kconfig
++++ linux-2.6.20/drivers/i2c/busses/Kconfig
+@@ -15,10 +15,20 @@ config I2C_ALI1535
+         Power Management Unit (PMU).
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-ali1535.
++config I2C_NOMADIK
++      tristate "I2C nomadik support"
++      depends on I2C
++      help
++        If you say yes to this option, support will be included for the i2c
++        controller on STn8810 .
++        This driver can also be built as a module.  If so, the module
++        will be called nmdkmod_i2c.
 +
-+      d) nomadik_gpio_readpin;
-+              reads HIGN or LOW value from specified pin
 +
-+      e) nomadik_gpio_readblock;
-+              write multiple bits on specifed group of GPIOs
-+      ex.
-+      err = nomadik_gpio_writeblock(GPIO_BLOCK_32_BITS_64_TO_95,
-+              , 0x0000aa00, 0x0000fc00);
+ config I2C_ALI1563
+       tristate "ALI 1563"
+       depends on I2C && PCI && EXPERIMENTAL
+       help
+         If you say yes to this option, support will be included for the SMB
+--- linux-2.6.20.orig/drivers/i2c/busses/Makefile
++++ linux-2.6.20/drivers/i2c/busses/Makefile
+@@ -1,9 +1,26 @@
+ #
+ # Makefile for the i2c bus drivers.
+ #
++TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
++SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
++PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
 +
-+      The above code writes HIGH on GPIO_PIN_74, LOW on GPIO_PIN_75,
-+      HIGH on GPIO_PIN_76, LOW on GPIO_PIN_77, and HIGN on GPIO_PIN_78
-+      
-+      f) nomadik_gpio_writeblock;
-+              reads multiple bits on specifed group of GPIOs
++ifeq ($(CONFIG_NOMADIK_NDK10),y)
++EXTRA_CFLAGS            := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__I2C_8810 -D__STN_8810
++endif
 +
-+2.2 Configuration for Alternate functions APIs
-+================================================
-+      a) nomadik_gpio_altfuncenable:
-+              Sets the group of GPIOs dedicated for spefic alternate mode of
-+      operation.
++ifeq ($(CONFIG_NOMADIK_NDK15),y)
++EXTRA_CFLAGS            := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10
++endif
 +
-+      for ex. 
-+      retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
-+      
-+      The above code configures GPIOs 62 abd 63 (in case of stn8810) for
-+      altfun_A, the detailed information which pins to be configured in which
-+      mode for specified gpio_alt_function value(GPIO_ALT_I2C_0) is decided by
-+      the gpio_altfun_tbl[] declared in <SOC>_devices.c. It has table entries
-+      whcih controls altfun configuration.
++ifeq ($(CONFIG_NOMADIK_NHK15),y)
++EXTRA_CFLAGS            := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10
++endif
 +
-+      for example entry in table
-+      {.altfun = GPIO_ALT_I2C_0,.start = 62,.end = 63,.cont = 0,.type =
-+       GPIO_ALTF_A,},
-+      states that- for gpio_alt_function value GPIO_ALT_I2C_0, from gpio pins 62
-+      to 63 needs to be configured for alternate function A. cont=0 specifies that
-+      there are no further pins to be configured for GPIO_ALT_I2C_0.
++obj-$(CONFIG_I2C_NOMADIK)     += nmdkmod_i2c.o
+ obj-$(CONFIG_I2C_ALI1535)     += i2c-ali1535.o
+ obj-$(CONFIG_I2C_ALI1563)     += i2c-ali1563.o
+ obj-$(CONFIG_I2C_ALI15X3)     += i2c-ali15x3.o
+ obj-$(CONFIG_I2C_AMD756)      += i2c-amd756.o
+ obj-$(CONFIG_I2C_AMD756_S4882)        += i2c-amd756-s4882.o
+@@ -48,5 +65,10 @@ obj-$(CONFIG_SCx200_ACB)    += scx200_acb.o
+ obj-$(CONFIG_SCx200_I2C)      += scx200_i2c.o
+ ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
+ EXTRA_CFLAGS += -DDEBUG
+ endif
 +
-+      example for cont=1
-+      {.altfun = GPIO_ALT_MM_CARD,.start = 8,.end = 10,.cont = 1,.type =
-+       GPIO_ALTF_A,},
-+      {.altfun = GPIO_ALT_SD_CARD,.start = 82,.end = 87,.cont = 1,.type =
-+       GPIO_ALTF_A,},
-+      {.altfun = GPIO_ALT_MM_CARD,.start = 14,.end = 16,.cont = 0,.type =
-+       GPIO_ALTF_A,},
-+      
-+      In the above example cont=1 in first and second declaration states that there  
-+      are additional entries in sequence to configure pins (82 to 87) and (14 to 16)
-+      in altfun A mode for the same gpio_alt_function value GPIO_ALT_MM_CARD
++nmdkmod_i2c-objs      := i2c-nomadik.o
++nmdkmod_i2c-objs      += i2c-$(SOC_NAME).o
 +
-+      b) nomadik_gpio_altfuncdisable:
-+              This API reconfigures the group of GPIOs dedicated for specific
-+      alternate mode of operation in to GPIO mode.
 +
-+Secured GPIO Access:
-+===================
-+To prevent GPIO resources getting used/altered by unauthorised way, a method
-+is provided to give secured control. When gpio is requested by setpinconfig,
-+you need to specify dev_name, GPIO driver records the information that the
-+particular pin is alloocated the client named "dev_name", while doing
-+resetpinconfig the same dev_id must be passed.
-+Simillarly the same should be followed while requesting enabling/disabling altfunction.
-+When the GPIO is requested for interrupt, the specified devname will be
-+configured as client name.
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c
+@@ -0,0 +1,1250 @@
 +
-+/proc/gpio interface:
-+====================
-+/proc/gpio entry is created to show the information of allocated GPIO resources
++/* drivers/i2c/busses/i2c-nomadik.c
++ *
++ * Support for i2c bus on STn8800/8810/8815 (Nomadik) chips.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
 +
-+=======================================================================================
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <linux/i2c-id.h>
++#include <asm/hardware.h>
++#include "i2c-nomadik.h"
++#include <asm/arch/gpio.h>
++#define DRIVER_VERSION "2.0.0"
++#define width 0
++#define BUSID 1
++#define error(format, arg...) printk( KERN_ERR "I2C: " format , ## arg)
++#define info(format, arg...)
++/*printk( KERN_INFO "I2C: %s " format, __func__, ## arg)*/
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt   2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,111 @@
-+Filename: ./Documentation/arm/STM-Nomadik/HOWTO-add_newboard.txt 
-+Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner:                STMicroelectronics
-+Purpose:
-+              This HOWTO explains guidlines for addition of new Nomadik
-+              board support to the kernel source code 
-+===============================================================================
++static unsigned int nomadik_i2c_func(struct i2c_adapter *adap);
++static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
++                          struct i2c_msg msgs[], int num);
++static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
++                          struct i2c_msg msgs[], int num);
 +
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++/* Other variables indexed by bus */
++static struct nomadik_i2c_private i2c_driver[2];
 +
-+Nomadik BSP kernel file naming conventions
-+============================================
-+It is strongly recommended to follow below filename conventions while adding
-+new board support for Nomadik
-+1. All the Nomadik architecture specific code must be in mach-nomadik and
-+      arch-nomadik folders in a kernel tree.
-+2. Generic and Nomadik specific device drives may be located into the respective
-+      folder in the kernel source tree (ex. nomadik keypad driver in
-+      drivers/input/keyboard/kpd-nomadik.c)
-+3. all Nomadik specific files in mach-nomadik and arch-nomadik folders should
-+      be named as <comp>.c/h
-+      (ex. gpio.h, msp.c)
-+4. all Nomadik platform specific files are named as <platform>_<purpose>.c/h
-+      (ex. ndk10_devices.c, ndk15_devices.h)
-+5. all Nomadik soc specific files are named as <soc>_<purpose>.c/h
-+      (ex. stn8810_devices.h, stn8815_devices.c)
++static struct i2c_algorithm nomadik_i2c_algo = {
++      master_xfer:nomadik_i2c_xfer,
++      smbus_xfer:NULL,
++      algo_control:NULL,
++      functionality:nomadik_i2c_func
++};
 +
-+Important definations
-+==============================
-+1. target: It is a unique identity to describe supported board with a specific
-+           board version and specific SOC version.
-+           target is created by combination of board (i.e. platform) and
-+         Nomadik chip version (i.e. soc)
++static struct i2c_adapter nomadik_i2c[2] = { {
++      name:                         "i2c0",
++      id:                           I2C_ALGO_NOMADIK |
++                                    I2C_HW_NOMADIK,
++      algo:                         &nomadik_i2c_algo,
++      data:   &i2c_driver[0],
++      class:  I2C_CLASS_HWMON
 +
-+2. platform: It is refered for board to be supported.
-+         One plaform may be supported by several targets
-+         One plaform may be supported by several socs
++                                            },
++{
++      name:"i2c1",
++      id:I2C_ALGO_NOMADIK | I2C_HW_NOMADIK,
++      algo:&nomadik_i2c_algo,
++      data:&i2c_driver[1],
++ }
++};
 +
-+3. soc: It is refered for the Nomadik chip version to be suported.
-+         same soc may be supported on several platforms
++#if !defined (CONFIG_NOMADIK_NHK15)
++static struct i2c_client nomadik_i2c_clients[] = {
++      {
++            name:"motherboard",
++            id:I2C_MB_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_MB,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"ui db",
++            id:I2C_UI_DB_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_UI_DB,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"io expansion db1",
++            id:I2C_IO_EXP_DB1_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_IO_DB1,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"io expansion db2",
++            id:I2C_IO_EXP_DB2_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_IO_DB2,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"Matisse camera",
++            id:I2C_CIF_CAM_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_CIF_CAM,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"mem exp",
++            id:I2C_MEM_EXP_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_MEM_EXP,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"audio codec",
++            id:I2C_AUDIO_CODEC_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_AC,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"FM tuner",
++            id:I2C_FM_TUNER_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_FM_TUNER,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"Gas Gauge",
++            id:I2C_GAS_GAUGE_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_GAS_GAUGE,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"Matiise for litea cam",
++            id:I2C_LITEA_CAM_MOD_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_CAM_MOD,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"i2c0 loopback",
++            id:I2C0_LOOP_CLIENT,
++            flags:0,
++            addr:I2C0_LP_OWNADDR,
++            adapter:&nomadik_i2c[0]
++       },
++      {
++            name:"i2c1 loopback",
++            id:I2C1_LOOP_CLIENT,
++            flags:0,
++            addr:I2C1_LP_OWNADDR,
++            adapter:&nomadik_i2c[1]
++       },
++      {
++            name:"Pepperpot camera",
++            id:I2C_PP_CAM_CLIENT,
++            flags:0,
++            addr:I2C_ADDR_PP_CAM,
++            adapter:&nomadik_i2c[BUSID]
++       },
++      {
++            name:"Touareg",
++            id:I2C_TOUAREG_CLIENT,
++            adapter:&nomadik_i2c[I2C_TOUAREG_ADAPTER],
++            flags:0,
++            addr:I2C_ADDR_TOUAREG,
++       }
 +
-+Hence any Nomadik borad is identified as a "target" and supported by "soc"
-+   specific code and "platform" specific code well interfaced with generic
-+   code.
++};
++#else
++static struct i2c_client nomadik_i2c_clients[] = {
++        {//0x42
++              name:"Denc",
++              id:I2C_DENC_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_DENC,
++              adapter:&nomadik_i2c[0]
++         },
++        {//0x34
++              name:"audio codec",
++              id:I2C_AUDIO_CODEC_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_AC,
++              adapter:&nomadik_i2c[0]
++         },
++        {//0x20
++              name:"FM tuner",
++              id:I2C_FM_TUNER_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_FM_TUNER,
++              adapter:&nomadik_i2c[0]
++         },
++        {//FIXME
++                name:"Matiise for litea cam",
++                id:I2C_LITEA_CAM_MOD_CLIENT,
++                flags:0,
++                addr:I2C_ADDR_CAM_MOD,
++                adapter:&nomadik_i2c[BUSID]
++        },
++        {//0x3A
++              name:"mems",
++              id:I2C_MEMS_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_MEMS,
++              adapter:&nomadik_i2c[0]
++         },
++        {//0x44, 0x46
++              name:"SIM card",
++            id:I2C_SIM_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_SIM,
++              adapter:&nomadik_i2c[0]
++         },
++        {//0x90
++              name:"touch screen",
++              id:I2C_TOUCH_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_TOUCH,
++              adapter:&nomadik_i2c[0]
++         },
++        {//0x86
++                name: "PEXP0",
++                id:I2C_STMPE0_CLIENT,
++                flags:0,
++                addr:I2C_ADDR_STMPE0,
++                adapter:&nomadik_i2c[0],
++        },
++        {//0x88
++                name: "PEXP1",
++                id:I2C_STMPE1_CLIENT,
++                flags:0,
++                addr:I2C_ADDR_STMPE1,
++                adapter:&nomadik_i2c[0],
++        },
++        {//0xE0
++              name:"Gas Gauge",
++              id:I2C_GAS_GAUGE_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_GAS_GAUGE,
++              adapter:&nomadik_i2c[0]
++         },
++        {//0x5A FIXME - MMC
++              name:"Power manager",
++              id:I2C_TOUAREG_CLIENT,
++              flags:0,
++              addr:I2C_ADDR_POWER,
++              adapter:&nomadik_i2c[0]
++         },
++       {
++              name:"i2c0 loopback",
++              id:I2C0_LOOP_CLIENT,
++              flags:0,
++              addr:I2C0_LP_OWNADDR,
++              adapter:&nomadik_i2c[0]
++         },
++        {
++              name:"i2c1 loopback",
++              id:I2C1_LOOP_CLIENT,
++              flags:0,
++              addr:I2C1_LP_OWNADDR,
++              adapter:&nomadik_i2c[1]
++         },
 +
-+Device driver Support for Nomadik:
-+====================================
-+1. All the drivers suported on a target can be either SOC or platform specific
-+2. A platform specific code for all supported driver will be refered from a 
-+   single file <platform_name>_devices.c through device specific interface.
-+3. A Nomadik chip specific code for all supported driver will be refered from a 
-+   single file <soc_name>_devices.c through device specific interface.
-+4. Each device specific header file <pltfomr_name>_devices.h and
-+   <soc_name>_devices.h must be maintained to share a common hardware
-+   parameters across the drivers. Those two files are included in
-+   asm/arch/hardware.h which is further refered through asm/hardware.h
-+   Hence any kernel code seeking for hardware specific information (like
-+   base address, irqnos) can be made available by just including
-+   <asm/hardware.h>
-+5. Each header file described here should have relevent declaration related to
-+   the scope of its usage. ex. <platform_name>_devices.h should only have 
-+   platforms specific declration.
++};
++#endif
 +
-+Any Nomadik target can be supported by following set of files:-
-+      arch/arch/mach-nomadik/<soc_name>_devices.c
-+      inclue/asm-arm/arch-nomadik/<soc_name>_devices.h
-+      arch/arch/mach-nomadik/<platform_name>_devices.c
-+      inclue/asm-arm/arch-nomadik/<platform_name>_devices.h
++#if !defined(CONFIG_NOMADIK_NHK15)
 +
-+But Generally, New board support will be added for already suported SOCs
-+hence, to add support for any new Nomadik target only three files need to be
-+added, those are:-
-+      arch/arch/mach-nomadik/<target_name>_Kconfig
-+      arch/arch/mach-nomadik/<platform_name>_devices.c
-+      inclue/asm-arm/arch0-nomadik/<platform_name>_devices.h
++/* This is an array of bus ids indexed by client id. They MUST be in the
++   sam order as the client structs above
++ */
++static __u32 nomadik_client_bus_id[] =
++    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, I2C_CLIENT_BUSID13 };
 +
-+Steps to follow to add new target support for Nomadik
-+========================================================
-+1. Add ./arch/arm/mach-nomadik/<target_name>_Kconfig file for board 
-+   configuration, <target_name> specified here will reflect as machine name.
++static struct nomadik_i2c_client priv_client[] = {
++      {
++            id:I2C_MB_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_MB,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_UI_DB_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_UI_DB,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_IO_EXP_DB1_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_IO_DB1,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_IO_EXP_DB2_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_IO_DB2,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_CIF_CAM_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_CIF_CAM,
++            endianness:LITTLE_END,
++      index_width:REG8},
++      {
++            id:I2C_MEM_EXP_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_MEM_EXP,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_AUDIO_CODEC_CLIENT,
++            bus_id:1,
++            addr:I2C_ADDR_AC,
++            endianness:LITTLE_END,
++      index_width:REG8},
++      {
++            id:I2C_FM_TUNER_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_FM_TUNER,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_GAS_GAUGE_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_GAS_GAUGE,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_LITEA_CAM_MOD_CLIENT,
++            bus_id:BUSID,
++            addr:I2C_ADDR_CAM_MOD,
++            endianness:LITTLE_END,
++      index_width:REG16},
++      {
++            id:I2C0_LOOP_CLIENT,
++            bus_id:0,
++            addr:I2C0_LP_OWNADDR,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C1_LOOP_CLIENT,
++            bus_id:1,
++            addr:I2C1_LP_OWNADDR,
++            endianness:LITTLE_END,
++      index_width:0},
++      {
++            id:I2C_PP_CAM_CLIENT,
++       /* added for Pepperpot camera */
++            bus_id:1,
++            addr:I2C_ADDR_PP_CAM,
++            endianness:BIG_END,
++      index_width:REG16},
++      {
++            id:I2C_TOUAREG_CLIENT,
++       /* added for Touareg chip for power mgmt */
++            bus_id:I2C_TOUREG_CLIENT_BUSID,
++            addr:I2C_ADDR_TOUAREG,
++            endianness:LITTLE_END,
++            index_width:REG8
++#ifdef CONFIG_NOMADIK_NDK15
++       },
++      {
++            id:I2C_CPLD_CLIENT,
++       /* added for CPLD */
++            bus_id:I2C_CPLD_CLIENT_BUSID,
++            addr:I2C_ADDR_CPLD,
++            endianness:LITTLE_END,
++       /* check */
++            index_width:REG8
++#endif
++       },
++      {
++            id:I2C_DENC_CLIENT,
++            bus_id:1,
++            addr:I2C_ADDR_DENC,
++            endianness:LITTLE_END,
++      index_width:REG8}
 +
-+      During make config/menuconfig arch/arm/mach-nomadik/Kconfig will be 
-+      checked, and if is not found, it will be created automatically using
-+      all <target_name>_Kconfig files and Kconfig_nomadik file.
-+      1. <target_name>_Kconfig file contain board specific configuration 
-+      2. Kconfig_nomadik contains generic configuration for all nomadik
-+         platforms
-+      for details refer provided ndk10_cut_a1_Kconfig file
++};
 +
-+2. Add ./arch/arm/mach-nomadik/<platform_name>_devices.c file 
-+      This file contains all the platfrom specific functions and data
-+      structures used by rest of the code. Any driver suported for Nomadik
-+      platform must access all the paramters through this file
-+      (for ex. base addres, irq number and other plaform specific data
-+       structures and function) 
-+      It is recommended to refer such file for already suported platform
++#else
++/* This is an array of bus ids indexed by client id. They MUST be in the
++   sam order as the client structs above
++ */
++static __u32 nomadik_client_bus_id[] =
++    { 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 1};
 +
-+3. Add ./include/asm-arm/arch-nomadik/<platform_name>_devices.h file 
-+      This file must contain all the declarations for this platform 
-+      which may be refered by the other drivers and kernel code.
-+      Note that this file is refered by some assembly code hence the
-+      content of this files must be maintained simple, standard and
-+      generic.
-+      It is recommended to refer such file for already suported platform
++static struct nomadik_i2c_client priv_client[] = {
++        {
++              id:I2C_DENC_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_DENC,
++              endianness:LITTLE_END,
++      index_width:REG8},
++        {
++              id:I2C_AUDIO_CODEC_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_AC,
++              endianness:LITTLE_END,
++      index_width:REG8},
++        {
++              id:I2C_FM_TUNER_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_FM_TUNER,
++              endianness:LITTLE_END,
++      index_width:0},
++        {
++              id:I2C_LITEA_CAM_MOD_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_CAM_MOD,
++              endianness:LITTLE_END,
++      index_width:0},
++        {
++              id:I2C_MEMS_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_MEMS,
++              endianness:LITTLE_END,
++      index_width:REG8},
++        {
++              id:I2C_SIM_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_SIM,
++              endianness:LITTLE_END,
++      index_width:0},
++        {
++              id:I2C_TOUCH_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_TOUCH,
++              endianness:LITTLE_END,
++      index_width:0},
++        {
++                id:I2C_STMPE0_CLIENT,
++                bus_id:0,
++                addr:I2C_ADDR_STMPE0,
++                endianness:LITTLE_END,
++      index_width:REG8
++        },
++        {
++                id:I2C_STMPE1_CLIENT,
++                bus_id:0,
++                addr:I2C_ADDR_STMPE1,
++                endianness:LITTLE_END,
++                index_width:REG8
++        },
++        {
++              id:I2C_GAS_GAUGE_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_GAS_GAUGE,
++              endianness:LITTLE_END,
++      index_width:REG8},
++        {
++              id:I2C_TOUAREG_CLIENT,
++              bus_id:0,
++              addr:I2C_ADDR_POWER,
++              endianness:LITTLE_END,
++      index_width:REG8},
++      {
++              id:I2C0_LOOP_CLIENT,
++              bus_id:0,
++              addr:I2C0_LP_OWNADDR,
++              endianness:LITTLE_END,
++      index_width:0},
++        {
++              id:I2C1_LOOP_CLIENT,
++              bus_id:1,
++              addr:I2C1_LP_OWNADDR,
++              endianness:LITTLE_END,
++      index_width:0},
 +
-+With the above addition/modification New target support will be available.
-+Select newly supported target in kernel configuration, build and execute
-+the code on new target
-+===============================================================================
++};
++#endif        /*CONFIG_NOMADIK_NHK15*/
++static int i2c_initialize(struct nomadik_i2c_private *priv)
++{
++      /* Transfer configuration */
++      priv->config.freq_scl = STD_SPEED_IN_HZ;
++      priv->config.i2c_transmit_interrupt_threshold = 4;
++      priv->config.i2c_receive_interrupt_threshold = 4;
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/HOWTO-nfsboot.txt        2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,106 @@
-+This HOWTO esplains mounting the root file system via NFS on Nomadik Platform (nfsroot) 
++      priv->config.bus_control_mode = I2C_BUS_MASTER_MODE;
++      priv->config.index_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
++      priv->config.data_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
 +
-+As you know, all of us spend lot of time in-
-+1.    Unzip/mount initrd to put the modules/application under test
-+2.    Copying modules/applications to initrd
-+3.    Unmount/gzip operation with initrd
-+4.    Then load huge initrd and kernel each time to target board
-+       for execution.
++      /* Device configuration */
++      priv->config.freq_input = STD_F_IN_HZ;
 +
-+So for each time even for a small change we need to repeat this process, and
-+downloading and system re-initialization eats lot of our development time.
-+Nfsroot is a good solution to overcome above issues.
++      if (priv->id)
++              priv->config.own_address = I2C1_LP_OWNADDR;
++      else
++              priv->config.own_address = I2C0_LP_OWNADDR;
 +
-+Root file system can be mounted via NFS (nfsroot) on host and can be accessed
-+from your target machin.
++      if (setup_i2c_controller(priv) != 0) {
++              error("i2c device config 0 failed init\n");
++              return -EIO;
++      }
 +
-+Advantages of this method are:-
-+===============================
-+1.    No need to download ramdiks time to time (saves lot of time)
-+2.    Since file system is on NFS, runtime results/logs dooes not vanishes
-+       in case of nomadik-system crash
-+3.    Since file system is on NFS, it is transperant to host and target
-+4.    Making, updating, mounting, unmounting, zipping, unzipping activities
-+       associated with ramdisk can be totally avoided (saves lot of time)
-+5.    Offers comfortable and fast development environment
++      return 0;
++}
 +
-+Host configuration to enable root NFS:-
-+========================================
-+1.    Copy a "target" folder from toolchain at some fixed path on your Linux
-+       host
-+2.      Switch to the dev folder of newly created target folder and create
-+       a node for console with command "mknod console c 5 1"
-+3.    Then swtich to the target folder and create a symbolic link with
-+       command "ln -s /bin/busybox linuxrc
-+4.    FTP and TFTP should be enabled on the host system. You can check the
-+       configuration by issuing the following command
++/**
++ * nomadik_i2c_get_info - Get status information of I2C controller
++ *
++ * @bus_id - The controller id.
++ * info - Info pointer describing  the controller status.
++ *
++ * Return an info struct with current bus parameters.
++ **/
 +
-+#> chkconfig --list | grep ftp
-+ 
-+Output should look like :-
-+vsftpd          0:off   1:off   2:on    3:on    4:on    5:on    6:off
-+              gssftp:         off
-+              tftp:           on
-+      
-+Note: Method of enabling FTP can be different for different versions of Linux.
++int nomadik_i2c_get_info(__u32 bus_id, i2c_info_t * info)
++{
++      struct nomadik_i2c_private *priv;
++      priv = &i2c_driver[bus_id];
++      info->baseAddress = (__u32) priv->regs;
++      info->id = priv->id;
++      info->mode = priv->config.mode;
++      info->enabled = priv->config.enabled;
++      info->fSCL = priv->config.freq_scl;
++      info->fIn = priv->config.freq_input;
++      info->ownAddress = priv->config.own_address;
 +
-+5.    NFS should be enabled. Same can also be checked with the following
-+       command 
++      return 0;
++}
 +
-+#> chkconfig --list | grep nfs
++/**
++ * nomadik_get_client - Get client information
++ *
++ * @client_id - Client id for the I2C device.
++ *
++ * This function returns the address of the client struct identified by
++ * client_id
++ **/
 +
-+Output should looklike 
-+nfs             0:off   1:off   2:on    3:on    4:on    5:on    6:off
++struct i2c_client *nomadik_i2c_get_client(__u32 client_id)
++{
++      if ((client_id < 0) || (client_id >= I2C_NUM_CLIENTS)) {
++              error("error: nomadik get_client: client = %d\n", client_id);
++              return 0;
++      }
++      return &nomadik_i2c_clients[client_id];
++}
 +
-+6.    Also, check the entries of the /etc/xinetd.d/tftp file accordingly.
-+       In our case, it is :
++/**
++ * nomadik_i2c_is_busy - Check if the client is busy in an operation.
++ *
++ * @client_id - Identifier for the client whose status is required.
++ *
++ * This function checks the status of an event_type I2C_NO_EVENT. If this is
++ * the current active event, the controller is not busy, and the function
++ * returns false (0). If this is not the current event type, then the bus is
++ * in the process of doing something, so we return true -EBUSY. Note that there
++ * is no guarantee that the bus will not become busy between this call and
++ * a transfer request, so calls to the transfer functions should
++ * check the return - it will be -EBUSY if the bus is in use. -EINVAL
++ * is returned for an invalid client_id.
++ **/
 +
-+service tftp
++int nomadik_i2c_is_busy(__u32 client_id)
 +{
-+        disable                       = no
-+        socket_type                   = dgram
-+        protocol                              = udp
-+        wait                                  = yes
-+        user                                  = root
-+        server                                = /usr/sbin/in.tftpd
-+        server_args                   = -T 100000000 -v -c -s
-+/local_no_backup
-+#       server_args                   = -s /tftpboot
-+        per_source                    = 11
-+        cps                                   = 100 2
-+        flags                                 = IPv4
++      int retval;
++
++      if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
++              return retval;
++
++      if (i2c_driver[nomadik_client_bus_id[client_id]].config.active_event.
++          type == I2C_NO_EVENT)
++              return 0;
++      return -EBUSY;
 +}
 +
-+7.    Also make the entries in /etc/exports for the file systems that need
-+       to be shared. For options used, please refer the man pages of exports.
-+       In our case, it is :
++static irqreturn_t nomadik_i2c_irq_handler(int irq,
++                                         void *arg)
++{
++      __u32 id = ((struct nomadik_i2c_private *)arg)->id;
++      disable_irq(irq);
++      process_interrupt(&i2c_driver[id]);
 +
-+/rtrt *(rw,insecure,no_root_squash,async)
-+/local_no_backup/target *(rw,insecure,no_root_squash,async)
++      enable_irq(i2c_driver[id].irq);
++      return IRQ_HANDLED;
++}
 +
-+How to enable NFS feature in your development?
-+===============================================
-+1.    Of cource you need to work on ethernet based environment
-+2.    Enable ethernet driver in your kernel image
-+3.    Enable following settings in your kernel image to enable nfsroot
-+a.    Networking options  --->IP: kernel level autoconfiguration
-+b.    Networking options  --->IP: BOOTP support
-+c.    File systems  --->Network File Systems  --->NFS file system support
-+d.    File systems  --->Network File Systems  --->Provide NFSv3 client support
-+e.    File systems  --->Network File Systems  --->Root file system on NFS
-+4.    Then compile kernel image, prepare uimage and download into the target
-+5.    Set the command line arguments as -
++/**
++ * nomadik_i2c_wait_msg
++ *
++ * @nomadik_i2c_private - Private data for the controller
++ * @len - Amount of data in bytes to be transferred
++ *
++ * Poll until the event we've started is finished.
++ * Wait 1000 microseconds for each byte transferred.
++ * Here we have not used wait_event_interruptible_timeout()
++ * as this would cause a schedule in interrupt context in case I2C routines
++ * called by client drivers in interrupt handlers
++ *
++ * This function should be called ONLY by this driver.
++ **/
++#define WAIT_CONDITION        (priv->config.active_event.type > I2C_NO_EVENT && priv->config.active_event.type <= I2C_BUS_ERROR_EVENT)
 +
-+ "set bootargs root=/dev/nfs nfsroot=<HOST_IP_ADDR>:/<PATH>/ramdisk
-+ip=<TARGET_IP_ADDR>:<HOST_IP_ADDR>:<GATWAY_IP_ADDR_FOR_TARGET>:255.255.255.0:nomadik:: console=ttyAMA1 mac=<MAC_ADDRESS> init=linuxrc"
++static int nomadik_i2c_wait_msg(struct nomadik_i2c_private *priv, int len)
++{
++      if(wait_event_interruptible(priv->event_wq, WAIT_CONDITION))
++              return -EINVAL;
 +
-+for example:-
-+"set bootargs root=/dev/nfs nfsroot=10.199.3.88:/local_no_backup/target
-+ip=10.199.32.165:10.199.3.88:10.199.32.254:255.255.255.0:NDK10_165::
-+mac=00:0D:88:45:5D:A5 console=ttyAMA1,115200n8 init=linuxrc"
++      return 0;
++}
 +
-+6.    And then boot the kernel with command "bootm 0x100000"
-+       (initrd address not needed since NFS)
++/**
++ * nomadik_i2c_xfer_byte - I2C transfer function used by nomadik_i2c_xfer to
++ * transfer a single byte
++ * @i2c_adapter - Adapter pointer to the controller
++ * @msgs[] - Pointer to data to be written.
++ * @num - Num messages
++ *
++ **/
 +
-+Start enjoying the advantages of root NFS
++static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
++                          struct i2c_msg msgs[], int num)
++{
++      int m, mm;
++      int status;
++      unsigned int addr;
++      struct nomadik_i2c_private *priv =
++          (struct nomadik_i2c_private *)i2c_adap->data;
++      __u32 bus_id = priv->id;
++      int read = 0;
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/irq_usrguide.txt 2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,171 @@
-+Filename: ./Documentation/arm/STM-Nomadik/irq_usrguide.txt 
-+Author:               Prafulla Wadaskar (prafulla.wadaskar@st.com)
-+Owner:                STMicroelectronics
-+Created:      9th June 2007
++      if (msgs[0].len <= 0)
++              return 0;
 +
-+Purpose:
-+This Users Guide explains interrupts implimentation and its usage from other
-+client drivers for Nomadik platforms
++      addr = msgs[0].addr;
 +
-+This document is valid subject to assumption -
-+1. valid kernel source code with Nomadik support is available
++      if (msgs[0].flags & I2C_M_TEN)
++      {
++              error("10 bit addressing not yet supported\n");
++              return -EINVAL;
++      }
 +
-+Generic:
-+========
-+All the available interrupts can be used in through standard system calls
-+To use nomadik interrupts, include <linux/interrupt.h> ONLY in your code
-+Interrupt numbers generic to all Nomadik cuts are defined in irqs.h
-+Interrupt numbers specific to Nomadik cut is defined in <soc>_devices.h
-+(refer HOWTO-add_newboard.txt for more information)
++      if (down_interruptible(&nomadik_i2c[bus_id].lock))
++              return -ERESTARTSYS;
 +
-+IRQ Description:
-+================
-+for stn8810 chip:
-+      IRQ0 to IRQ31   : IRQ lines provided by the VIC for different
-+                        on-chip peripharals.
-+      IRQ32 to IRQ127 : IRQ lines for GPIO interrupts
-+ 
-+for stn8815 chip:
-+      IRQ0 to IRQ63   : IRQ lines provided by the VIC for different
-+                        on-chip peripharals.
-+      IRQ64 to IRQ191 : IRQ lines for GPIO interrupts
-+ 
-+Specific:
-+========
-+1. Vectored Interrupt Controller (VIC) Interrupt Priority configuration:-
-+========================================================================
-+Generally whenever there is IRQ request to the VIC it will be processed
-+immediately, if two or more IRQs active at a time then first in a sequence
-+(i.e lower in number) will be processed first (this depends how you decode
-+irqnr in entry-macro.S).
++      for (m = 0; m < num; m++)
++      {
++              info("message: %d, addr: %d\n", m,  msgs[m].addr);
++              info("message: %d, flags: %d\n", m, msgs[m].flags);
++              info("message: %d, len: %d\n", m, msgs[m].len);
 +
-+Vectored interrupt processing hardware on Nomadik SOC is used to detect, 
-+process and service the interrupts in prioritized manner.
-+This provides faster interrupt processing for comples decision.
-+This adds more flexibility to the system and to the driver developers to
-+take complex decision making about which interrupt to be proceesed first
-+when more than one IRQ goes active at a time.
++              for(mm = 0; mm <  msgs[m].len; mm++)
++                      info("message: %d, buf[%d]: 0x%02X\n", m, mm, msgs[m].buf[mm]);
 +
-+also while processing priority interrupt all lower priority interrupts will
-+be disabled by hardware whereas all higher priority interrupts will be active.
-+This adds a benefit to use SA_IRQPRIORITY_x over SA_INTERRUPT becasue
-+SA_INTERRUPT disables all interrupt while processign it.
++              info("message: %d, bus id: 0x%02X\n", m, bus_id);
++      }
 +
-+Any 15 (maximum) IRQs lines of VIC can be programmed for priority,
-+GPIO_IRQs cannot be programmed for priority since the are softdecoded.
++#if !defined(CONFIG_NOMADIK_NHK15)
++      reset_i2c(priv);
++#endif
 +
-+How to program a interrupt for desired priority?
-+================================================
-+this can be done in two ways 
-+a. using request_irq
-+      for ex.
-+      err = request_irq(IRQ_UART1, test_inthandle, SA_IRQPRIORITY_4,
-+                       "test", test_data);
++      /* Save parameters. */
++      priv->config.slave_address = addr;
++      priv->config.status = I2C_STATUS_SLAVE_MODE;
++      priv->config.index_format = I2C_BYTE_INDEX;
++      priv->config.active_event.type = I2C_NO_EVENT;
++      priv->config.multi_operation = NOMADIK_TRUE;
 +
-+      will request IRQ with interrupt priority level 4
++      if (i2c_initialize(priv)) {
++              up(&nomadik_i2c[bus_id].lock);
++              return -EINVAL;
++      }
 +
-+b) using set_irq_type
-+      This call can be used any time after requesting a interrupt to
-+      to enable/disable/change priority level for specific IRQ line
++      if (verify_parameters(priv))
++      {
++              error("Error in parameters\n");
++              up(&nomadik_i2c[bus_id].lock);
++              return -EINVAL;
++      }
 +
-+      For ex.
-+      set_irq_type(IRQ_UART1, SA_IRQPRIORITY_10); 
++      if (num > 1)
++      {
++              if (msgs[1].flags & I2C_M_RD)
++              {
++                      read = 1;
++              }
++      }
 +
-+      will enable priority level for pre-requested IRQ
-+      if IRQ was requested with different priority level earlier,
-+      this call will change it to specified level
++      if (read != 0)
++      {
 +
-+How to disable interrupt priority for a IRQ?
-+===========================================
-+a) using set_irq_type api
-+      This call can be used any time after requesting a interrupt to
-+      to enable/disable/change priority level for specific IRQ line
++              /* Save parameters. */
++              priv->config.databuffer = &(msgs[1].buf[0]);
++              priv->config.count_data = msgs[1].len;
++              priv->config.register_index = msgs[0].buf[0];
++              /* Do the read */
++              priv->config.operation = I2C_READ;
 +
-+      For ex.
-+      set_irq_type(IRQ_UART1, SA_IRQPRIORITY_DISABLE); 
++              status = read_i2c(priv);
 +
-+      will disable priority level for pre-requested IRQ and will configure
-+      if as normal IRQ
++              if (status)
++              {
++                      error("Error in read_register: %d\n", status);
++                      up(&nomadik_i2c[bus_id].lock);
++                      return status;
++              }
++              else if (status == 0)
++              {
 +
-+How to know which IRQs are programmed for priority?
-+===================================================
-+executing cat /proc/interrupts interface will display all interrupt information
-+if any IRQ is programmed with some priority then it will reflect as-
++                      if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
++                      {
++                              status = nomadik_i2c_wait_msg(priv, msgs[0].len);
++                              if (status)
++                              {
++                                      error("Message timeout with no handled event\n");
++                                      error("error waiting for i2c read: %d\n", status);
++                                      up(&nomadik_i2c[bus_id].lock);
++                                      return status;
++                              }
++                      }
++              }
 +
-+# cat /proc/interrupts
-+           CPU0
-+  4:     143193       Nomadik Timer Tick
-+ 10:          0       rtc
-+ 11:          0       ssp
-+ 13:          1       dma1
-+ 15:          0       dma0
-+ 17:        745       uart-pl011
-+ 20:          0       i2c0
-+ 21:          4       i2c1
-+ 22:        132       NMDK_MMC (data)
-+ 30:          0:PL07  msp1
-+ 31:          0       msp2
-+ 72:        122       nmdk-kp
-+ 77:        433       eth0
-+ 79:       5175       nmdk-tp
-+ 81:         32       mmc_detect
-+Err:          0
-+#
++              info("ret message: 0, buf[0]: 0x%02X\n", msgs[0].buf[0]);
++              info("ret message: 1, buf[0]: 0x%02X\n", msgs[1].buf[0]);
 +
-+Above message indicates that IRQ30 for msp1 is programmed as priority interrupt
-+with level 7.
++              mdelay(1);
++              priv->config.active_event.type = I2C_NO_EVENT;
 +
-+2. GPIO Interrupt hanndling and control:-
-+==============================================
-+GPIO Interrupt control is handled through standard system calls. The macros
-+(IRQNO_GPIO(x) and GPIO_PIN_FOR_IRQ(x)) are provided to find out interrupt
-+number associated with GPIO and vice-versa.
-+Following system calls are suported for GPIO interrupt control:-
-+a) request_irq/ free_irq:
-+      works in a standard way to request and free GPIO interrupt.
-+      When request_irq is invoked for GPIO, it first configures GPIO pin
-+      for input operation with debounce disable (if supported). Then it sets
-+      interrupt type for falling edge detection by default if not specified
-+      in interrupt_flags. You can set type of interrupt during request by
-+      passing required SA_TTRIGGER_ flags. GPIO interrupt type will be set
-+      during request_irq call if the requested interrupt is NOT shared.
-+      
-+      for ex.
-+      err = request_irq(IRQNO_GPIO(x), test_inthandle, SA_TRIGGER_RISING,
-+                       "test", test_data);
++              up(&nomadik_i2c[bus_id].lock);
++      }
++      else
++      {
++              /* Save parameters. */
++              priv->config.databuffer = &(msgs[0].buf[1]);
++              priv->config.count_data = 1;
++              priv->config.register_index = msgs[0].buf[0];
 +
-+      will request rising edge interrupt for GPIO x  
-+      
-+b) enable_irq/disable_irq:
-+      These are standard system calls can be used to enable or disable GPIO
-+      irqs whenever required.
-+      
-+      for ex.
-+      enable_irq(IRQNO_GPIO(x));
++              /* Do the write */
++              priv->config.operation = I2C_WRITE;
++              status = write_i2c(priv);
++              if (status)
++              {
++                      error("Error in write_register: %d\n", status);
++                      up(&nomadik_i2c[bus_id].lock);
++                      return status;
++              }
++              else if (status == 0)
++              {
++                      if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
++                      {
++                              status = nomadik_i2c_wait_msg(priv, msgs[0].len - 1);
++                              if (status)
++                              {
++                                      error("Message timeout with no handled event\n");
++                                      error("error waiting for i2c write: %d\n", status);
++                                      up(&nomadik_i2c[bus_id].lock);
++                                      return status;
++                              }
++                      }
++              }
++              mdelay(1);
++              priv->config.active_event.type = I2C_NO_EVENT;
++              up(&nomadik_i2c[bus_id].lock);
++      }
 +
-+      will enable interrupt for GPIO x
++      return 0;
 +
-+c) set_irq_type:
-+      By defult interrupt is requested as falling edge through request_irq call.
-+      If you want to use other type of interrupt detection, this call can be used.
-+      This call will be necessary to configure shared GPIO interrupt
++}
 +
-+      For ex.
-+      set_irq_type(IRQNO_GPIO(x), SA_TRIGGER_LOW); 
-+              sets irq type as low level detection
++/**
++ * nomadik_i2c_xfer - I2C transfer function used by kernel framework
++ * @i2c_adapter - Adapter pointer to the controller
++ * @msgs[] - Pointer to data to be written.
++ * @num - Amount of data in bytes to be written
++ *
++ * This is the function called by the generic kernel i2c API calls. Note that
++ * this code is protected by the semaphore set in the kernel i2c_transfer()
++ * function.
++ * Retrive the client specific information from the client id and feed it to
++ * the controller specific configuration. Then call the respective board
++ * specific routine.
++ **/
 +
-+      set_irq_type(IRQNO_GPIO(x), (SA_TRIGGER_RISING|SA_TRIGGER_FALLING); 
-+              sets irq type for both edges detection
++static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
++                          struct i2c_msg msgs[], int num)
++{
++      int i;
++      int status;
++      unsigned int addr;
++      struct nomadik_i2c_private *priv =
++          (struct nomadik_i2c_private *)i2c_adap->data;
++      __u32 bus_id = priv->id;
++      /*read byte or write byte, SMBus emulated (see i2c_smbus_xfer_emulated)*/
++      if ((num == 2 && msgs[0].len == 1 && msgs[1].len == 1 && (msgs[1].flags & I2C_M_RD)) ||
++         (num == 1 && msgs[0].len == 2 && ((msgs[0].flags & I2C_M_RD) == 0)))
++      {
++              return nomadik_i2c_xfer_byte(i2c_adap, msgs, num);
++      }
 +
-+      Please note that set_irq_type overwites previous irq_type, hence the GPIO
-+      interrupt behaviour depends upon where you call this API.
-+      
-+      for ex. if you set_irq_type first and then requested interrupt, the
-+      request_irq will overwrite the previously set irq type and vice versa.
++      for (i = 0; i < num; i++) {     /* deal with  message i */
++              if (msgs[i].len > 0) {  /*sanity check - message length */
++                      /*prepare address */
++                      addr = msgs[i].addr;
++                      if (msgs[i].flags & I2C_M_RD)
++                              addr |= 0x1;
 +
-+d) enable_irq_wake/disable_irq_wake:
-+      the frame work is provided to handle these call for GPIO interrupt to
-+      enable/disable wakup event generation to the power management unit.
++                      if (msgs[i].flags & I2C_M_TEN) {
++                              error("10 bit addressing not yet supported\n");
++                              return -EINVAL;
++                      }
 +
-+===============================================================================
++                      if (down_interruptible(&nomadik_i2c[bus_id].lock))
++                              return -ERESTARTSYS;
 +
-diff -Nauprw linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt
---- linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/arm/STM-Nomadik/power_management.txt     2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,122 @@
-+ 
-+ * 1 Nomadik Power Management Strategy
-+ * ==========================================
-+ * Power in nomadik can be saved by following features
-+ * 1. Enable idle tick suppression or dynamic tick
-+ * 2. Frequency scaling
-+ * 3. Voltage scaling
-+ * 4. Take system into soft sleep
-+ * 5. Take system into deep sleep
-+ * 6. Taking individual device (eg. CLCD) into suspend state
-+ *
-+ *
-+ * 1.1 How to Enable idle tick suppression or dynamic tick
-+ * =========================================================
-+ *
-+ * 1. Select CONFIG_NO_IDLE_HZ in kernel features in kernel configuration
-+ * 2. To enable dynamic tick
-+ *    echo -n 1 > /sys/devices/system/timer/timer0/dyn_tick
-+ * 3. Dynamic tick can be disabled by
-+ *    echo -n 0 > /sys/devices/system/timer/timer0/dyn_tick
-+ * 4. In idle thread, arm put itself in WFI, hence power is saved. By using
-+ *    dynamic tick we can put ARM in WFI for longer duration
-+ *
-+ * 1.2 Scaling frequencies
-+ *====================================
-+ * 1. Select CONFIG_CPU_FREQ & CONFIG_CPU_FREQ_NOMADIK in kernel configuration
-+ *    during compilation
-+ * 2. Check current frequency (In Khz) by 
-+ *    cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
-+ * 3. Change system freq by
-+ *    echo -n <freq in khz > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
-+ *    If entered freq is not supported in system then next higher valid
-+ *    frequency is set
-+ * 4. For frequencies which require voltage change, new voltage will be
-+ *    reflected. It can be checked by voltage sysfs file
-+ * 5. If mapping for frequency and voltage is changed then change is required
-+ *     in arch/arm/mach-nomadik/power.c
-+ * 6. If different SDRAM parameters are to be changed then change is required
-+ *    in  arch/arm/mach-nomadik/power.c
-+ * 7. If frequencies are to be altered then change is required in  arch/arm/mach-nomadik/power.c
-+ *
-+ *
-+ * 1.3 Scaling Voltage
-+ *====================================
-+ * 1. To enable voltage scaling either CONFIG_CPU_FREQ or CONFIG_PM_NOMADIK
-+ *    must be selected in configuration
-+ * 2. Current voltage can be checked by 
-+ *    cat /sys/nomadik/current_voltage
-+ *    VOLTAGE will be shown in milli volt
-+ * 3. To change in current voltage without changing frequency use
-+ *    echo < voltage in milli volt > > current_voltage
-+ *   However directly changing voltage without frequency is not recommended
-+ *   but can be used for performance/testing purpose.
-+ * 4. If voltages are to be altered then change is required in  arch/arm/mach-nomadik/power.c
-+ *
-+ *
-+ * 1.4 Taking system into soft sleep
-+ *====================================
-+ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
-+ * 2. Change required sleep type to softsleep by
-+ *    echo -n softsleep > /sys/nomadik/sleep_type
-+ * 3. To take system into sleep use
-+ *    echo -n mem > /sys/power/state
-+ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
-+ * 5. To specify rtc wakeup duration ( sleeping time )
-+      echo -n <sleep duration in seconds > >sleep_duration
-+      Default sleep duratioon is 15 seconds
-+ * 6. To take system directly into soft sleep without linux power management
-+ *    framework use
-+ *    echo 1 > /sys/nomadik/softsleep_enable
-+ *    This is to be used when we are sure that no driver is active i.e.
-+ *    driver need not be be suspended. This interface can save transition
-+ *    time but is not recommended. It can be used for testing purpose.
-+ *
-+ *
-+ * 1.5 Taking system into deep sleep
-+ *====================================
-+ * 1. Select CONFIG_PM and CONFIG_NOMADIK_PM and CONFIG_NOMADIK_RTC
-+ * 2. Change required sleep type to deepsleep by
-+ *    echo -n deepsleep > /sys/nomadik/sleep_type
-+ * 3. To take system into sleep use
-+ *    echo -n mem > /sys/power/state
-+ * 4. Wakeup can be done by RTC or keypad/touch panel/MMC
-+ * 5. To specify rtc wakeup duration ( sleeping time )
-+ *    echo -n <sleep duration in seconds > >sleep_duration
-+ *    Default sleep duration is 15 seconds
-+ *
-+ * 1.6 Taking Individual device into suspend/resume state
-+ *=======================================================
-+ * 1. Individual device can be taken into suspended state by writing into sysfs
-+ *    file. Similiarly device can be resumed back 
-+ * 2. For example to take CLCD into suspend state use
-+      echo -n 2 > /sys/devices/mb:c0/power/state
-+ * 3. For example to take CLCD into resumed state use
-+      echo -n 0 > /sys/devices/mb:c0/power/state
-+ * 4. Similar things can be done for other devices. Few devices such as RTC,
-+ *    GPIO should not be takne into suspend state by this interface.
-+ *
-+ *
-+ * 1.7 Enabling/Disabling Individual devices(Keypad, Touchpanel, MMC) as wakeup devices
-+ *===================================================================================
-+ * 1. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
-+ *    echo enabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
-+ * 2. To enable a device (for e.g. keypad ) to be able to wakeup system from sleep do
-+ *    echo disabled > /sys/devices/platform/nmdk-kp.0/power/wakeup
-+ *    If a device's wakeup state is disabled, it cannot be used for waking the
-+ *    system from sleep.
-+ * 3. Above steps are applicable for any device that can wakeup the system
-+ *
-+ *
-+ * 1.8 To add a device that can be used to wakeup 
-+ *================================================
-+ * 1. To make a platform device to be able to wakeup a system, change is
-+ * required in board specific file like arch/arm/mach-nomadik/ndk15_devices.c
-+ * 2. To make a amba device to be able to wakeup a system, change is required
-+ * in platform specific file like arch/arm/mach-nomadik/stn8815_devices.c
-+ * 
-+ *
-+ *
-+ */ 
++                      reset_i2c(priv);
 +
++                      /* Save parameters. */
++                      priv->config.slave_address = addr;
++                      priv->config.status = I2C_STATUS_SLAVE_MODE;
++                      priv->config.index_format = I2C_NO_INDEX;
++                      priv->config.databuffer = msgs[i].buf;
++                      priv->config.count_data = msgs[i].len;
++                      priv->config.multi_operation = NOMADIK_TRUE;
 +
-diff -Nauprw linux-2.6.20/Documentation/DocBook/kgdb.tmpl ../new/linux-2.6.20/Documentation/DocBook/kgdb.tmpl
---- linux-2.6.20/Documentation/DocBook/kgdb.tmpl       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/DocBook/kgdb.tmpl        2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,234 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-+      "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
++                      if (i2c_initialize(priv)) {
++                              up(&nomadik_i2c[bus_id].lock);
++                              return -EINVAL;
++                      }
 +
-+<book id="kgdbInternals">
-+ <bookinfo>
-+  <title>KGDB Internals</title>
++                      if (verify_parameters(priv)) {
++                              error("Error in parameters\n");
++                              up(&nomadik_i2c[bus_id].lock);
++                              return -EINVAL;
++                      }
 +
-+  <authorgroup>
-+   <author>
-+    <firstname>Tom</firstname>
-+    <surname>Rini</surname>
-+    <affiliation>
-+     <address>
-+      <email>trini@kernel.crashing.org</email>
-+     </address>
-+    </affiliation>
-+   </author>
-+  </authorgroup>
++                      if (addr & 1) {
++                              /* Do the read */
++                              priv->config.operation = I2C_READ;
++                              /* read */
++                              status = read_i2c(priv);
++                              if (status) {
++                                      error("Error in read_register: %d\n",
++                                            status);
++                                      up(&nomadik_i2c[bus_id].lock);
++                                      return status;
++                              } else if (status == 0) {
 +
-+  <authorgroup>
-+   <author>
-+    <firstname>Amit S.</firstname>
-+    <surname>Kale</surname>
-+    <affiliation>
-+     <address>
-+      <email>amitkale@linsyssoft.com</email>
-+     </address>
-+    </affiliation>
-+   </author>
-+  </authorgroup>
++                                      if (priv->config.data_transfer_mode !=
++                                          I2C_TRANSFER_MODE_POLLING) {
++                                              status =
++                                                  nomadik_i2c_wait_msg(priv,
++                                                                       msgs
++                                                                       [i].
++                                                                       len);
++                                              if (status) {
++                                                      error
++                                                          ("Message timeout with no handled event\n");
++                                                      error
++                                                          ("error waiting for i2c read: %d\n",
++                                                           status);
++                                                      up(&nomadik_i2c[bus_id].
++                                                         lock);
++                                                      return status;
++                                              }
++                                      }
++                              }
++                              /* mdelay(1); */ /* NM */
++                              priv->config.active_event.type = I2C_NO_EVENT;
++                              up(&nomadik_i2c[bus_id].lock);
 +
-+  <copyright>
-+   <year>2004-2005</year>
-+   <holder>MontaVista Software, Inc.</holder>
-+  </copyright>
-+  <copyright>
-+   <year>2004</year>
-+   <holder>Amit S. Kale</holder>
-+  </copyright>
++                      } else {
++                              /* Do the write */
++                              priv->config.operation = I2C_WRITE;
++                              status = write_i2c(priv);
++                              if (status) {
++                                      error("Error in write_register: %d\n",
++                                            status);
++                                      up(&nomadik_i2c[bus_id].lock);
++                                      return status;
++                              } else if (status == 0) {
 +
-+  <legalnotice>
-+   <para>
-+   This file is licensed under the terms of the GNU General Public License
-+   version 2. This program is licensed "as is" without any warranty of any
-+   kind, whether express or implied.
-+   </para>
++                                      if (priv->config.data_transfer_mode !=
++                                          I2C_TRANSFER_MODE_POLLING) {
++                                              status =
++                                                  nomadik_i2c_wait_msg(priv,
++                                                                       msgs
++                                                                       [i].
++                                                                       len);
++                                              if (status) {
++                                                      error
++                                                          ("Message timeout with no handled event\n");
++                                                      error
++                                                          ("error waiting for i2c write: %d\n",
++                                                           status);
++                                                      up(&nomadik_i2c[bus_id].
++                                                         lock);
++                                                      return status;
++                                              }
++                                      }
++                              }
++                              /* mdelay(1); */ /* NM */
++                              priv->config.active_event.type = I2C_NO_EVENT;
++                              up(&nomadik_i2c[bus_id].lock);
++                      }
 +
-+  </legalnotice>
-+ </bookinfo>
++              }
++      }
++      return 0;
++}
 +
-+<toc></toc>
-+  <chapter id="Introduction">
-+    <title>Introduction</title>
-+    <para>
-+    kgdb is a source level debugger for linux kernel. It is used along
-+    with gdb to debug a linux kernel. Kernel developers can debug a kernel
-+    similar to application programs with the use of kgdb. It makes it
-+    possible to place breakpoints in kernel code, step through the code
-+    and observe variables.
-+    </para>
-+    <para>
-+    Two machines are required for using kgdb. One of these machines is a
-+    development machine and the other is a test machine. The machines are
-+    typically connected through a serial line, a null-modem cable which
-+    connects their serial ports.  It is also possible however, to use an
-+    ethernet connection between the machines.  The kernel to be debugged
-+    runs on the test machine. gdb runs on the development machine. The
-+    serial line or ethernet connection is used by gdb to communicate to
-+    the kernel being debugged.
-+    </para>
-+  </chapter>
-+  <chapter id="CompilingAKernel">
-+    <title>Compiling a kernel</title>
-+    <para>
-+    To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
-+    and then select "KGDB: kernel debugging with remote gdb".
-+    </para>
-+    <para>
-+    The first choice for I/O is <symbol>CONFIG_KGDB_ONLY_MODULES</symbol>.
-+    This means that you will only be able to use KGDB after loading a
-+    kernel module that defines how you want to be able to talk with
-+    KGDB.  There are two other choices (more on some architectures) that
-+    can be enabled as modules later, if not picked here.
-+    </para>
-+    <para>The first of these is <symbol>CONFIG_KGDB_8250_NOMODULE</symbol>.
-+    This has sub-options such as <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol>
-+    which toggles choosing the serial port by ttyS number or by specifying
-+    a port and IRQ number.
-+    </para>
-+    <para>
-+    The second of these choices on most systems for I/O is
-+    <symbol>CONFIG_KGDBOE</symbol>. This requires that the machine to be
-+    debugged has an ethernet card which supports the netpoll API, such as
-+    the cards supported by <symbol>CONFIG_E100</symbol>.  There are no
-+    sub-options for this, but a kernel command line option is required.
-+    </para>
-+  </chapter>
-+  <chapter id="BootingTheKernel">
-+    <title>Booting the kernel</title>
-+    <para>
-+    The Kernel command line option <constant>kgdbwait</constant> makes kgdb
-+    wait for gdb connection during booting of a kernel.  If the
-+    <symbol>CONFIG_KGDB_8250</symbol> driver is used (or if applicable,
-+    another serial driver) this breakpoint will happen very early on, before
-+    console output.  If you wish to change serial port information and you
-+    have enabled both <symbol>CONFIG_KGDB_8250</symbol> and
-+    <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> then you must pass the option
-+    <constant>kgdb8250=&lt;io or mmio&gt;,&lt;address&gt;,&lt;baud
-+    rate&gt;,&lt;irq&gt;</constant> before <constant>kgdbwait</constant>.
-+    The values <constant>io</constant> or <constant>mmio</constant> refer to
-+    if the address being passed next needs to be memory mapped
-+    (<constant>mmio</constant>) or not. The <constant>address</constant> must
-+    be passed in hex and is the hardware address and will be remapped if
-+    passed as <constant>mmio</constant>. The value
-+    <constant>baud rate</constant> and <constant>irq</constant> are base-10.
-+    The supported values for <constant>baud rate</constant> are
-+    <constant>9600</constant>, <constant>19200</constant>,
-+    <constant>38400</constant>, <constant>57600</constant>, and
-+    <constant>115200</constant>.
-+    </para>
-+    <para>
-+    To have KGDB stop the kernel and wait, with the compiled values for the
-+    serial driver, pass in: <constant>kgdbwait</constant>.
-+    </para>
-+    <para>
-+    To specify the values of the serial port at boot:
-+    <constant>kgdb8250=io,3f8,115200,3</constant>.
-+    On IA64 this could also be:
-+    <constant>kgdb8250=mmio,0xff5e0000,115200,74</constant>
-+    And to have KGDB also stop the kernel and wait for GDB to connect, pass in
-+    <constant>kgdbwait</constant> after this arguement.
-+    </para>
-+    <para>
-+    To configure the <symbol>CONFIG_KGDBOE</symbol> driver, pass in
-+    <constant>kgdboe=[src-port]@&lt;src-ip&gt;/[dev],[tgt-port]@&lt;tgt-ip&gt;/[tgt-macaddr]</constant>
-+    where:
-+    <itemizedlist>
-+      <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem>
-+      <listitem><para>src-ip: source IP to use (interface address)</para></listitem>
-+      <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem>
-+      <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem>
-+      <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem>
-+      <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem>
-+    </itemizedlist>
-+    </para>
-+    <para>
-+    The <symbol>CONFIG_KGDBOE</symbol> driver can be reconfigured at run
-+    time, if <symbol>CONFIG_SYSFS</symbol> and
-+    <symbol>CONFIG_MODULES</symbol> by echo'ing a new config string to
-+    <constant>/sys/module/kgdboe/parameter/kgdboe</constant>.  The
-+    driver can be unconfigured with the special string
-+    <constant>not_configured</constant>.
-+    </para>
-+  </chapter>
-+  <chapter id="ConnectingGDB">
-+  <title>Connecting gdb</title>
-+    <para>
-+    If you have used any of the methods to have KGDB stop and create
-+    an initial breakpoint described in the previous chapter, kgdb prints
-+    the message "Waiting for connection from remote gdb..." on the console
-+    and waits for connection from gdb. At this point you connect gdb to kgdb.
-+    </para>
-+    <para>
-+    Example (serial):
-+    </para>
-+    <programlisting>
-+    % gdb ./vmlinux
-+    (gdb) set remotebaud 115200
-+    (gdb) target remote /dev/ttyS0
-+    </programlisting>
-+    <para>
-+    Example (ethernet):
-+    </para>
-+    <programlisting>
-+    % gdb ./vmlinux
-+    (gdb) target remote udp:192.168.2.2:6443
-+    </programlisting>
-+    <para>
-+    Once connected, you can debug a kernel the way you would debug an
-+    application program.
-+    </para>
-+  </chapter>
-+  <chapter id="CommonBackEndReq">
-+    <title>The common backend (required)</title>
-+      <para>
-+      There are a few flags which must be set on every architecture in
-+      their &lt;asm/kgdb.h&gt; file.  These are:
-+      <itemizedlist>
-+        <listitem>
-+        <para>
-+        NUMREGBYTES: The size in bytes of all of the registers, so
-+        that we can ensure they will all fit into a packet.
-+        </para>
-+        <para>
-+        BUFMAX: The size in bytes of the buffer GDB will read into.
-+        This must be larger than NUMREGBYTES.
-+        </para>
-+        <para>
-+        CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call
-+        flush_cache_range or flush_icache_range.  On some architectures,
-+        these functions may not be safe to call on SMP since we keep other
-+        CPUs in a holding pattern.
-+        </para>
-+      </listitem>
-+      </itemizedlist>
-+      </para>
-+      <para>
-+      There are also the following functions for the common backend,
-+      found in kernel/kgdb.c that must be supplied by the
-+      architecture-specific backend.  No weak version of these is provided.
-+      </para>
-+!Iinclude/linux/kgdb.h
-+  </chapter>
-+  <chapter id="CommonBackEndOpt">
-+    <title>The common backend (optional)</title>
-+      <para>
-+      These functions are part of the common backend, found in kernel/kgdb.c
-+      and are optionally implemented.  Some functions (with _hw_ in the name)
-+      end up being required on arches which use hardware breakpoints.
-+      </para>
-+!Ikernel/kgdb.c
-+  </chapter>
-+  <chapter id="DriverSpecificFunctions">
-+    <title>Driver-Specific Functions</title>
-+      <para>
-+      Some of the I/O drivers have additional functions that can be
-+      called, that are specific to the driver.  Calls from other places
-+      to these functions must be wrapped in #ifdefs for the driver in
-+      question.
-+      </para>
-+!Idrivers/serial/8250_kgdb.c
-+   </chapter>
-+</book>
-diff -Nauprw linux-2.6.20/Documentation/DocBook/Makefile ../new/linux-2.6.20/Documentation/DocBook/Makefile
---- linux-2.6.20/Documentation/DocBook/Makefile        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/Documentation/DocBook/Makefile 2007-11-21 11:51:41.000000000 +0530
-@@ -11,7 +11,8 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
-           procfs-guide.xml writing_usb_driver.xml \
-           kernel-api.xml filesystems.xml lsm.xml usb.xml \
-           gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
--          genericirq.xml
-+          genericirq.xml \
-+          kgdb.xml
- ###
- # The build process is as follows (targets):
-diff -Nauprw linux-2.6.20/drivers/char/keyboard.c ../new/linux-2.6.20/drivers/char/keyboard.c
---- linux-2.6.20/drivers/char/keyboard.c       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/char/keyboard.c        2007-11-21 11:51:41.000000000 +0530
-@@ -1183,6 +1183,7 @@ static void kbd_keycode(unsigned int key
-               sysrq_down = 0;
-       if (sysrq_down && down && !rep) {
-               handle_sysrq(kbd_sysrq_xlate[keycode], tty);
-+              sysrq_down = 0;         /* In case we miss the 'up' event. */
-               return;
-       }
- #endif
-diff -Nauprw linux-2.6.20/drivers/cpufreq/Kconfig ../new/linux-2.6.20/drivers/cpufreq/Kconfig
---- linux-2.6.20/drivers/cpufreq/Kconfig       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/cpufreq/Kconfig        2007-11-21 11:51:41.000000000 +0530
-@@ -140,4 +140,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
-         If in doubt, say N.
-+config CPU_FREQ_NOMADIK
-+        tristate "cpu freq scaling support for nomadik"
-+        depends on CPU_FREQ
++/**
++ * nomadik_i2c_write_register
++ *
++ * nomadik_i2c_write_register - Write data to I2C client
++ * @client_id - Identifier for the client
++ * @data - Pointer to data to be written.
++ * @index - Register index of the client
++ * @count - Amount of data in bytes to be written
++ *
++ * Handle all register index type writes.  Using the client structs for
++ * the client_id, we can call the correct register write function and
++ * ensure a two byte index has the correct byte order.
++ * Retrive the client specific information from the client id and feed it to
++ * the controller specific configuration. Then call the respective board
++ * specific routine.
++ **/
 +
- endif # CPU_FREQ
-diff -Nauprw linux-2.6.20/drivers/hwmon/Kconfig ../new/linux-2.6.20/drivers/hwmon/Kconfig
---- linux-2.6.20/drivers/hwmon/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/hwmon/Kconfig  2008-09-16 23:41:15.000000000 +0530
-@@ -230,6 +230,19 @@ config SENSORS_IT87
-         This driver can also be built as a module.  If so, the module
-         will be called it87.
-+config SENSORS_LIS3LV02DL
-+        tristate "LIS3LV02DL MEMS three-axis accelerometer I2C driver"
-+        depends on HWMON && I2C && EXPERIMENTAL
-+        default n 
-+        help
-+          This driver provides support for the ST microelectronics LIS3LV02DL
-+          MEMS inertial sensor which provides a three-axis, I2C controlled
-+          Â± 2g/± 6g digital output linear accelerometer. The accelerometer
-+          data is readable via sysfs.
++int nomadik_i2c_write_register(__u32 client_id,
++                             __u8 * data, int index, int count)
++{
++      int bus_id;
++      int retval;
++      __u16 addr;
++      struct nomadik_i2c_client *client;
++      struct nomadik_i2c_private *priv;
 +
-+          This driver can also be built as a module.  If so, the module
-+          will be called lis3vl02dl.
++      if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
++              return retval;
 +
- config SENSORS_LM63
-       tristate "National Semiconductor LM63"
-       depends on HWMON && I2C
-diff -Nauprw linux-2.6.20/drivers/hwmon/lis3lv02dl.c ../new/linux-2.6.20/drivers/hwmon/lis3lv02dl.c
---- linux-2.6.20/drivers/hwmon/lis3lv02dl.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/hwmon/lis3lv02dl.c     2008-09-16 23:41:59.000000000 +0530
-@@ -0,0 +1,489 @@
-+/*
-+    stmems.c 
++      client = &priv_client[client_id];
++      bus_id = client->bus_id;
++      priv = &i2c_driver[bus_id];
++      addr = client->addr;
 +
-+    Copyright (c) 2008  Nicholas Angelo Crespi <roundtrip@gmail.com>
++      if (down_interruptible(&nomadik_i2c[bus_id].lock))
++              return -ERESTARTSYS;
 +
-+    LIS3LV02DL MEMS inertial sensor is a 3-axis - Â± 2g/± 6g digital output
-+    low voltage linear accelerometer.
-+      http://www.st.com/stonline/products/literature/ds/12094/lis3lv02dl.htm
++//    reset_i2c(priv);
 +
-+    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.
++      /* Save parameters. */
++      priv->config.slave_address = addr;
++      priv->config.status = I2C_STATUS_SLAVE_MODE;
++      priv->config.register_index = index;
++#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
++      priv->config.index_format =
++          ((client->index_width ==
++            REG8) ? I2C_BYTE_INDEX : (client->
++                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++                                      : I2C_HALF_WORD_BIG_ENDIAN));
++#else
++      priv->config.index_format =
++          ((client->index_width == 0)?I2C_NO_INDEX:
++           (client->index_width == REG8) ? I2C_BYTE_INDEX : (client->
++                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++                                      : I2C_HALF_WORD_BIG_ENDIAN));
++#endif
++      priv->config.databuffer = data;
++      priv->config.count_data = count;
++      priv->config.active_event.type = I2C_NO_EVENT;
++      priv->config.multi_operation = NOMADIK_TRUE;
++      /* Do the write */
++      priv->config.operation = I2C_WRITE;
 +
-+    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.
++      if (i2c_initialize(priv)) {
++              up(&nomadik_i2c[bus_id].lock);
++              return -EINVAL;
++      }
 +
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++      if (verify_parameters(priv)) {
++              error("Error in parameters\n");
++              up(&nomadik_i2c[bus_id].lock);
++              return -EINVAL;
++      }
 +
-+ * Compile this driver with:
++      retval = write_i2c(priv);
 +
-+      echo "obj-m := tiny_i2c_chip.o" > Makefile
-+      make -C <path/to/kernel/src> SUBDIRS=$PWD modules
-+ */
++      if (retval) {
++              error("Error in write_register: %d\n", retval);
++      } else if (retval == 0) {
 +
-+#define DEBUG 1
-+#define VERSION "0.2"
++              if (priv->config.data_transfer_mode !=
++                  I2C_TRANSFER_MODE_POLLING) {
++                      retval = nomadik_i2c_wait_msg(priv, count);
++                      if (retval) {
++                              error
++                                  ("Message timeout with no handled event\n");
++                              error("error waiting for i2c read: %d\n",
++                                    retval);
++                              up(&nomadik_i2c[bus_id].lock);
++                              return retval;
++                      }
++              }
++              else mdelay(1);
++              priv->config.active_event.type = I2C_NO_EVENT;
++              up(&nomadik_i2c[bus_id].lock);
++              return retval;
++      }
 +
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/jiffies.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/err.h>
-+#include <linux/mutex.h>
-+#include <asm/arch/i2c.h>
++      up(&nomadik_i2c[bus_id].lock);
 +
-+#define stmems_perror(format, arg...) 
-+//printk( KERN_ERR "STMEMS: %s " format, __func__, ## arg)
-+#define stmems_pinfo(format, arg...)  
-+//printk( KERN_INFO "STMEMS: %s " format, __func__, ## arg)
++      /* Neither register mode for this client, return an error */
++      return -EINVAL;
++}
 +
-+/* Addresses to scan */
++/**
++ * nomadik_i2c_read_register - Read data from I2C client
++ * @client_id - Identifier for the client
++ * @data - Pointer where the read data will be written.
++ * @index - Register index of the client
++ * @count - Amount of data in bytes to be read
++ *
++ * Handle all register index type writes.  Using the client structs for
++ * the client_id, we can call the correct register write function and
++ * ensure a two byte index has the correct byte order.
++ * Retrive the client specific information from the client id and feed it to
++ * the controller specific configuration. Then call the respective board
++ * specific routine.
++ **/
 +
-+//static unsigned short normal_i2c[] = { 0x3A, I2C_CLIENT_END };
-+static unsigned short normal_i2c[] = { 0x1D, I2C_CLIENT_END };
++int nomadik_i2c_read_register(__u32 client_id,
++                            __u8 * data, int index, int count)
++{
++      int bus_id;
++      int retval;
++      __u16 addr;
++      struct nomadik_i2c_client *client;
++      struct nomadik_i2c_private *priv;
 +
-+//static unsigned short normal_i2c_range[] = { 0x00, 0xff, I2C_CLIENT_END };
++      if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
++              return retval;
 +
-+/* Insmod parameters */
-+I2C_CLIENT_INSMOD_1(stmems);
++      client = &priv_client[client_id];
++      bus_id = client->bus_id;
++      priv = &i2c_driver[bus_id];
++      addr = client->addr;
 +
-+/* Each client has this additional data */
-+struct stmems_data {
-+      struct i2c_client client;
-+      struct class_device *class_dev;
-+      struct mutex update_lock;
-+      char valid;                     /* !=0 if following fields are valid */
-+      unsigned long last_updated;     /* In jiffies */
-+      int acc_x;                      /* Register values */
-+      int acc_y;
-+      int acc_z;
-+      u8 divisor;
-+      u8 fullscale;
-+      u8 BDU;
-+};
++      if (down_interruptible(&nomadik_i2c[bus_id].lock))
++              return -ERESTARTSYS;
 +
-+/* stmems registers mnemonics */
-+/*      mnemonic             hex    r/w    default  */
-+#define MEMS_WHO_AM_I        0x0F /*r      00111010 */
-+#define MEMS_OFFSET_X        0x16 /*rw     calib    */
-+#define MEMS_OFFSET_Y        0x17 /*rw     calib    */
-+#define MEMS_OFFSET_Z        0x18 /*rw     calib    */
-+#define MEMS_GAIN_X          0x19 /*rw     calib    */
-+#define MEMS_GAIN_Y          0x1A /*rw     calib    */
-+#define MEMS_GAIN_Z          0x1B /*rw     calib    */
-+#define MEMS_CTRL_REG1       0x20 /*rw     00000111 */
-+#define MEMS_CTRL_REG2       0x21 /*rw     00000000 */
-+#define MEMS_CTRL_REG3       0x22 /*rw     00001000 */
-+#define MEMS_HP_FILTER RESET 0x23 /*r      dummy    */
-+#define MEMS_STATUS_REG      0x27 /*rw     00000000 */
-+#define MEMS_OUTX_L          0x28 /*r               */
-+#define MEMS_OUTX_H          0x29 /*r               */
-+#define MEMS_OUTY_L          0x2A /*r               */
-+#define MEMS_OUTY_H          0x2B /*r               */
-+#define MEMS_OUTZ_L          0x2C /*r               */
-+#define MEMS_OUTZ_H          0x2D /*r               */
-+#define MEMS_FF_WU_CFG       0x30 /*rw     00000000 */
-+#define MEMS_FF_WU_SRC       0x31 /*rw     00000000 */
-+#define MEMS_FF_WU_ACK       0x32 /*r               */
-+#define MEMS_FF_WU_THS_L     0x34 /*rw     00000000 */
-+#define MEMS_FF_WU_THS_H     0x35 /*rw     00000000 */
-+#define MEMS_FF_WU_DURATION  0x36 /*rw     00000000 */
-+#define MEMS_DD_CFG          0x38 /*rw     00000000 */
-+#define MEMS_DD_SRC          0x39 /*rw     00000000 */
-+#define MEMS_DD_ACK          0x3A /*r               */
-+#define MEMS_DD_THSI_L       0x3C /*rw     00000000 */
-+#define MEMS_DD_THSI_H       0x3D /*rw     00000000 */
-+#define MEMS_DD_THSE_L       0x3E /*rw     00000000 */
-+#define MEMS_DD_THSE_H       0x3F /*rw     00000000 */
++//    reset_i2c(priv);
 +
++      /* Save parameters. */
++      priv->config.slave_address = addr;
++      priv->config.status = I2C_STATUS_SLAVE_MODE;
++      priv->config.register_index = index;
++#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
++      priv->config.index_format =
++          ((client->index_width ==
++            REG8) ? I2C_BYTE_INDEX : (client->
++                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++                                      : I2C_HALF_WORD_BIG_ENDIAN));
 +
-+static int stmems_attach_adapter(struct i2c_adapter *adapter);
-+static int stmems_detect(struct i2c_adapter *adapter, int address, int kind);
-+static int stmems_detach_client(struct i2c_client *client);
-+static void stmems_init_sensor(struct i2c_client *client);
-+static inline u8 stmems_read_value(struct i2c_client *client, u8 reg);
-+static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value);
-+static inline int stmems_join(u8 LSB, u8 MSB);
-+static struct stmems_data *stmems_update_device(struct device *dev);
++#else
 +
-+/* This is the driver that will be inserted */
-+static struct i2c_driver stmems_driver = {
-+      .driver = {
-+              .name   = "stmems",
-+      },
-+      .attach_adapter = stmems_attach_adapter,
-+      .detach_client  = stmems_detach_client,
-+};
++      priv->config.index_format =
++          ((client->index_width == 0)?I2C_NO_INDEX:
++           (client->index_width ==
++            REG8) ? I2C_BYTE_INDEX : (client->
++                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
++                                      : I2C_HALF_WORD_BIG_ENDIAN));
 +
-+/* read routines for accelerations */
-+#define show(value)   \
-+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)     \
-+{                                                             \
-+      struct stmems_data *data = stmems_update_device(dev);   \
-+      return sprintf(buf, "%d\n", data->value);               \
++#endif
++      priv->config.databuffer = data;
++      priv->config.count_data = count;
++      priv->config.active_event.type = I2C_NO_EVENT;
++      priv->config.multi_operation = NOMADIK_TRUE;
++      /* Do the read operation */
++      priv->config.operation = I2C_READ;
++
++      if (i2c_initialize(priv)) {
++              up(&nomadik_i2c[bus_id].lock);
++              return -EINVAL;
++      }
++
++      if (verify_parameters(priv)) {
++              error("Error in parameters\n");
++              up(&nomadik_i2c[bus_id].lock);
++              return -EINVAL;
++      }
++
++      retval = read_i2c(priv);
++
++      if (retval) {
++              error("Error in read register: %d\n", retval);
++      } else if (retval == 0) {
++
++              if (priv->config.data_transfer_mode !=
++                  I2C_TRANSFER_MODE_POLLING) {
++                      retval = nomadik_i2c_wait_msg(priv, count);
++                      if (retval) {
++                              error
++                                  ("Message timeout with no handled event\n");
++                              error("error waiting for i2c read: %d\n",
++                                    retval);
++                              up(&nomadik_i2c[bus_id].lock);
++                              return retval;
++                      }
++              }
++              else mdelay(1);
++              priv->config.active_event.type = I2C_NO_EVENT;
++              up(&nomadik_i2c[bus_id].lock);
++              return 0;
++      }
++
++      up(&nomadik_i2c[bus_id].lock);
++
++      /* Neither register mode for this client, return an error */
++      return -EINVAL;
 +}
-+show(acc_x);
-+show(acc_y);
-+show(acc_z);
 +
-+/* read routines for divisor, BDU and fullscale */
-+static ssize_t show_divisor(struct device *dev, struct device_attribute *attr, char *buf)
++static unsigned int nomadik_i2c_func(struct i2c_adapter *adap)
 +{
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      if (!(data->valid))
-+              data = stmems_update_device(dev);
-+      return sprintf(buf, "%d\n", data->divisor);
++      return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK;
++      //return I2C_FUNC_I2C;
 +}
 +
-+static ssize_t show_fullscale(struct device *dev, struct device_attribute *attr, char *buf)
++static int nomadik_i2c_remove(struct platform_device *pdev)
 +{
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      if (!(data->valid))
-+              data=stmems_update_device(dev);
-+      return sprintf(buf, "%d\n", data->fullscale);
-+}
-+static ssize_t show_BDU(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      if (!(data->valid))
-+              data=stmems_update_device(dev);
-+      return sprintf(buf, "%d\n", data->BDU);
-+}
-+
-+/* this macro is useless! */
-+#define set(value, reg)       \
-+static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
-+{                                                                     \
-+      struct i2c_client *client = to_i2c_client(dev);                 \
-+      struct stmems_data *data = i2c_get_clientdata(client);          \
-+      int temp = simple_strtoul(buf, NULL, 10);                       \
-+                                                                      \
-+      mutex_lock(&data->update_lock);                                 \
-+      data->value = temp;                                             \
-+      mutex_unlock(&data->update_lock);                               \
-+      return count;                                                   \
-+}
-+
-+/* Write routines for divisor, BDU and fullscale */
-+static ssize_t set_divisor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-+{     
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      u8 ctrl_reg;
-+      int temp = simple_strtoul(buf, NULL, 10);
-+      /* the divisor input can only be 512,128,32 or 8 */
-+      if ((temp!= 8) && (temp!= 32) && (temp!= 128) && (temp!= 512)) return 0;
-+      mutex_lock(&data->update_lock);
-+      data->divisor = temp;
-+      ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG1);
-+      if (temp == 8) {ctrl_reg |= 0x30;}
-+      else if (temp == 32) {ctrl_reg |= 0x20; ctrl_reg &= 0xEF;}
-+      else if (temp == 128) {ctrl_reg |= 0x10; ctrl_reg &= 0xDF;}
-+      else {ctrl_reg &= 0xCF; }
-+      stmems_write_value(client,MEMS_CTRL_REG1,ctrl_reg);
-+      mutex_unlock(&data->update_lock);
-+      return count;
-+}
-+
-+static ssize_t set_fullscale(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-+{
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      u8 ctrl_reg;
-+      int temp = simple_strtoul(buf, NULL, 10);
-+      if ((temp!= 1) && (temp!= 0)) return 0;
-+      mutex_lock(&data->update_lock);
-+      data->fullscale = temp;
-+      ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
-+      if (temp) {ctrl_reg |= 0x80;}
-+      else {ctrl_reg &= 0x7F; }
-+      stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
-+      mutex_unlock(&data->update_lock);
-+      return count;
-+}
 +
-+static ssize_t set_BDU(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-+{
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      u8 ctrl_reg;
-+      int temp = simple_strtoul(buf, NULL, 10);
-+      if ((temp!= 1) && (temp!= 0)) return 0;
-+      mutex_lock(&data->update_lock);
-+      data->BDU = temp;
-+      ctrl_reg = stmems_read_value(client,MEMS_CTRL_REG2);
-+      if (temp) {ctrl_reg |= 0x40;}
-+      else {ctrl_reg &= 0xBF; }
-+      stmems_write_value(client,MEMS_CTRL_REG2,ctrl_reg);
-+      mutex_unlock(&data->update_lock);
-+      return count;
-+}
++      int retval;
++      i2c_del_adapter(&nomadik_i2c[pdev->id]);
 +
-+static DEVICE_ATTR(acc_x, S_IRUGO,
-+                 show_acc_x, NULL);
-+static DEVICE_ATTR(acc_y, S_IRUGO,
-+                 show_acc_y, NULL);
-+static DEVICE_ATTR(acc_z, S_IRUGO,
-+                 show_acc_z, NULL);
++      free_irq(i2c_driver[pdev->id].irq, &i2c_driver[pdev->id]);
 +
-+static DEVICE_ATTR(fullscale, S_IWUSR | S_IRUGO,
-+                 show_fullscale, set_fullscale);
-+static DEVICE_ATTR(divisor, S_IWUSR | S_IRUGO,
-+                 show_divisor, set_divisor);
-+static DEVICE_ATTR(BDU, S_IWUSR | S_IRUGO,
-+                 show_BDU, set_BDU);
++      disable_i2c(&i2c_driver[pdev->id]);
 +
-+static int stmems_attach_adapter(struct i2c_adapter *adapter)
-+{
-+      int err;
-+      
-+      stmems_pinfo("entered\n");
-+      stmems_pinfo("adapter class: %d\n", adapter->class);
-+      
-+      if (!(adapter->class & I2C_CLASS_HWMON))
-+      {
-+              stmems_perror("adapter class is not HWMON skip\n");
-+              return 0;
++      retval =
++          nomadik_gpio_altfuncdisable(GPIO_ALT_I2C_0 + pdev->id, (char *)pdev->name);
++      if (retval) {
++              error("GPIO Disable Alt Function(%d) failed with  %d\n",
++                    pdev->id, retval);
++              return retval;
 +      }
 +
-+      err = i2c_probe(adapter, &addr_data, stmems_detect);
-+      
-+      return err;
++      return 0;
 +}
 +
-+
-+/* This function is called by i2c_probe */
-+static int stmems_detect(struct i2c_adapter *adapter, int address, int kind)
++static int nomadik_i2c_probe(struct platform_device *pdev)
 +{
-+      struct i2c_client *new_client = NULL;
-+      struct stmems_data *data = NULL;
-+      int err = 0;
-+      u8 temp_reg;
-+      int ret;
-+
-+
-+      stmems_pinfo("entered\n");
-+
-+      stmems_pinfo("kind: %d\n", kind);
-+      stmems_pinfo("address: %d\n", address);
-+
-+      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-+      {
-+              stmems_perror("no SMBUS BYTE functionality detected\n");
-+              goto error;
-+      }
++      int irq;
++      int retval = -EINVAL;
++      struct resource *res = NULL;
 +
-+      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE))
-+      {
-+              stmems_perror("no SMBUS READ BYTE DATA functionality detected\n");
-+              goto error;
++      /*Fetch the Resources, using platform data */
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (NULL == res) {
++              dev_err(&pdev->dev, "probe - MEM resources not defined\n");
++              return -ENODEV;
 +      }
 +
-+      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA))
-+      {
-+              stmems_perror("no SMBUS READ BYTE functionality detected\n");
-+              goto error;
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0) {
++              dev_err(&pdev->dev, "probe - IRQ resource not defined\n");
++              return -ENODEV;
 +      }
 +
-+      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
-+      {
-+              stmems_perror("no SMBUS WRITE BYTE DATA functionality detected\n");
-+              goto error;
-+      }
++      i2c_driver[pdev->id].regs = (void *)IO_ADDRESS(res->start);
++      i2c_driver[pdev->id].id = pdev->id;
++      i2c_driver[pdev->id].irq = irq;
++      i2c_driver[pdev->id].adap = &nomadik_i2c[pdev->id];
 +
-+      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
-+      {
-+              stmems_perror("no SMBUS WRITE BYTE functionality detected\n");
-+              goto error;
-+      }
++      nomadik_i2c[pdev->id].data = (void *)&i2c_driver[pdev->id];
++      nomadik_i2c[pdev->id].dev.parent = &pdev->dev;
 +
-+      /* OK. For now, we presume we have a valid client. We now create the
-+         client structure, even though we cannot fill it completely yet.
-+         But it allows us to access stmems_{read,write}_value. */
-+      data = kzalloc(sizeof(struct stmems_data), GFP_KERNEL);
-+      if (!data) {
-+              err = -ENOMEM;
-+              goto error;
++      retval = i2c_add_adapter(&nomadik_i2c[pdev->id]);
++      if (retval) {
++              error("Nomadik I2C[%d] Error: failed to add adapter\n",
++                    pdev->id);
++              return retval;
 +      }
 +
-+      memset(data, 0x00, sizeof(*data));
++      /* Initialize semaphores */
++      sema_init(&nomadik_i2c[pdev->id].lock, 1);
 +
-+      new_client = &data->client;
-+      i2c_set_clientdata(new_client, data);
-+      new_client->addr = address;
-+      new_client->adapter = adapter;
-+      new_client->driver = &stmems_driver;
-+      new_client->flags = 0;
-+      
-+      /* Chip detection:
-+         since the chip has a register that holds its hardware address,
-+         we use that as an identification field. */
-+      if (kind < 0){
-+              temp_reg = stmems_read_value(new_client, MEMS_WHO_AM_I);
-+              //if ( (int)temp_reg != address)
-+              //      goto free_error;
++      retval = request_irq(i2c_driver[pdev->id].irq,
++                           nomadik_i2c_irq_handler,
++                           0,
++                           nomadik_i2c[pdev->id].name, &i2c_driver[pdev->id]);
++      if (retval < 0) {
++              error("i2c[%d] can't get requested irq %d\n",
++                    pdev->id, i2c_driver[pdev->id].irq);
++              return retval;
 +      }
 +
-+      /* Fill in the remaining client fields */
-+      strncpy(new_client->name, "stmems", I2C_NAME_SIZE);
-+      data->valid = 0;
-+      mutex_init(&data->update_lock);
-+
-+      /* Tell the I2C layer a new client has arrived */
-+      err = i2c_attach_client(new_client);
-+      if (err)
-+              goto error;
-+      
-+      /* Initialize the chip */
-+      stmems_init_sensor(new_client);
-+
-+      /* Register sysfs hooks */
-+      data->class_dev = hwmon_device_register(&new_client->dev);
-+      if (IS_ERR(data->class_dev)) {
-+              err = PTR_ERR(data->class_dev);
-+              goto detach_error;
++      if (pdev->id == 0) {
++              retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
++              if (retval) {
++                      error
++                          ("GPIO Enable Alt Function(%d) failed with  return = %d\n",
++                           pdev->id, retval);
++                      return (-EIO);
++              }
++      } else {/*
++              retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_1, "I2C_1");
++              if (retval) {
++                      error
++                          ("GPIO Enable Alt Function(%d) failed with  return = %d\n",
++                           pdev->id, retval);
++                      return (-EIO);
++              }*/
 +      }
-+
-+      ret = device_create_file(&new_client->dev, &dev_attr_acc_x);
-+      ret = device_create_file(&new_client->dev, &dev_attr_acc_y);
-+      ret = device_create_file(&new_client->dev, &dev_attr_acc_z);
-+      ret = device_create_file(&new_client->dev, &dev_attr_divisor);
-+      ret = device_create_file(&new_client->dev, &dev_attr_fullscale);
-+      ret = device_create_file(&new_client->dev, &dev_attr_BDU);
++      init_waitqueue_head(&i2c_driver[pdev->id].event_wq);
++      reset_i2c(&i2c_driver[pdev->id]);
 +      return 0;
-+
-+detach_error:
-+      i2c_detach_client(new_client);
-+//free_error:
-+      kfree(data);
-+error:
-+      return err;
 +}
 +
-+//TODO: powerdown
-+static int stmems_detach_client(struct i2c_client *client)
++static struct platform_driver nomadik_i2c_driver = {
++      .probe = nomadik_i2c_probe,
++      .remove = nomadik_i2c_remove,
++      .driver = {
++                 .owner = THIS_MODULE,
++                 .name = "NOMADIK-I2C",
++                 },
++};
++
++static int __init i2c_nomadik_init(void)
 +{
-+      struct stmems_data *data =   i2c_get_clientdata(client);
-+      hwmon_device_unregister(data->class_dev);
-+      i2c_detach_client(client);
-+      kfree(data);
-+      return 0;
++      return platform_driver_register(&nomadik_i2c_driver);
 +}
 +
-+/* Configure the chip, mainly with default values */
-+static void stmems_init_sensor(struct i2c_client *client){
-+      u8 conf_reg;
-+      /* CTRL_REG1: enable axis, turn down powerdown mode, freq divisor 512 */
-+      
-+      conf_reg = 0xC7;
-+
-+      stmems_pinfo("entered\n");
-+
-+      stmems_write_value(client, MEMS_CTRL_REG1, conf_reg);
-+      /* CTRL_REG2: fullscale 2g, batch update, big endian, disable INT,
-+         12bit right-justified, */
-+      conf_reg  = stmems_read_value(client, MEMS_CTRL_REG2);
-+      conf_reg = 0x60;
-+
-+      stmems_write_value(client, MEMS_CTRL_REG2, conf_reg);
-+      /* CTRL_REG3:  disable interrupts generation, leave others values*/
-+      conf_reg = stmems_read_value(client, MEMS_CTRL_REG3);
-+      conf_reg &= 0x8F;
-+      stmems_write_value(client, MEMS_CTRL_REG3, conf_reg);
++static void __exit i2c_nomadik_exit(void)
++{
++      platform_driver_unregister(&nomadik_i2c_driver);
 +      return;
 +}
 +
-+static struct stmems_data *stmems_update_device(struct device *dev)
-+{
-+      struct i2c_client *client = to_i2c_client(dev);
-+      struct stmems_data *data = i2c_get_clientdata(client);
-+      u8 status_reg;
++EXPORT_SYMBOL(nomadik_i2c_get_info);
++EXPORT_SYMBOL(nomadik_i2c_is_busy);
++EXPORT_SYMBOL(nomadik_i2c_read_register);
++EXPORT_SYMBOL(nomadik_i2c_write_register);
++EXPORT_SYMBOL(nomadik_i2c_get_client);
 +
-+      stmems_pinfo("entered\n");
++module_init(i2c_nomadik_init);
++module_exit(i2c_nomadik_exit);
 +
-+      mutex_lock(&data->update_lock);
-+      dev_dbg(&client->dev, "%s\n", __FUNCTION__);
-+      status_reg = stmems_read_value(client, MEMS_STATUS_REG);
-+      //TODO: we're assuming big endianess
-+      //TODO: use 0x08 instead
-+      if (status_reg & 0x01)
-+              data->acc_x = stmems_join(stmems_read_value(client, MEMS_OUTX_H), stmems_read_value(client, MEMS_OUTX_L));
-+      if (status_reg & 0x02)
-+              data->acc_y = stmems_join(stmems_read_value(client, MEMS_OUTY_H), stmems_read_value(client, MEMS_OUTY_L));
-+      if (status_reg & 0x04)
-+              data->acc_z = stmems_join(stmems_read_value(client, MEMS_OUTZ_H), stmems_read_value(client, MEMS_OUTZ_L));
-+      data->last_updated = jiffies;
-+      data->valid = 1;
-+      mutex_unlock(&data->update_lock);
++MODULE_DESCRIPTION("Nomadik IIC driver v" DRIVER_VERSION);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h
+@@ -0,0 +1,93 @@
++/* drivers/i2c/busses/i2c-nomadik.h
++ *
++ * This is the non-public header file for the nomadik i2c driver.
++ *
++ * 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
++ *
++ * $Id$
++ */
 +
-+      if (data)
-+      {       
-+              stmems_pinfo("acc_x: %d\n", data->acc_x);
-+              stmems_pinfo("acc_y: %d\n", data->acc_y);
-+              stmems_pinfo("acc_z: %d\n", data->acc_z);
-+      }
-+      
-+      return data;
-+}
++#ifndef I2C_NOMADIC_PRIV_HEADER
++#define I2C_NOMADIC_PRIV_HEADER
 +
-+/* All registers are byte-sized */  
-+static inline u8 stmems_read_value(struct i2c_client *client, u8 reg)
-+{
-+      u8 temp;
++#ifndef _NOMADIK_DEFS_H
++#include <asm/arch/defs.h>
++#endif
 +
-+      stmems_pinfo("reading: 0x%02X\n", reg);
-+      temp = i2c_smbus_read_byte_data(client, reg);
-+      //nomadik_i2c_read_register(I2C_MEMS_CLIENT,&temp,reg,1);
-+      stmems_pinfo("read: 0x%02X, value: 0x%02X\n", reg, temp);
-+      
-+      return temp;
-+}
++#ifndef I2C_NOMADIC_HEADER
++#include <asm/arch/i2c.h>
++#endif
 +
-+static inline u8 stmems_write_value(struct i2c_client *client, u8 reg, u8 value)
-+{
-+      stmems_pinfo("writing: 0x%02X, value: 0x%02X\n", reg, value);
++#define I2C_ALGO_NOMADIK  0x15000000
++#define I2C_HW_NOMADIK    0x01
++#define I2C_DRIVERID_NOMADIK 0xF000
 +
-+      return i2c_smbus_write_byte_data(client, reg, value);
-+      //return nomadik_i2c_write_register(I2C_MEMS_CLIENT,&value,reg,1);
-+}
++#define I2C0_IOSIZE         0x00000FFF
++#define I2C1_IOSIZE         0x00000FFF
 +
-+static int __init stmems_init(void)
-+{     
-+      stmems_pinfo("entered\n");
++#define MSG_WAIT_USEC 500     // Wait 500 uSecs to test active event again.
++#define MAX_WIAT_TIMEOUTS 100
 +
-+      return i2c_add_driver(&stmems_driver);
-+}
++/***
++ * Other structs
++ ***/
++struct nomadik_i2c_client {
++      __u32 id;
++      __u32 bus_id;
++      __u8 addr;
++      __u8 endianness;        // This indicates endianness of device's register index
++      __u8 index_width;       // 8 or 16 bits;
++};
 +
-+static void __exit stmems_exit(void)
-+{
-+      stmems_pinfo("entered\n");
++#define BIG_END    0
++#define LITTLE_END 1
++#define REG8       8
++#define REG16      16
 +
-+      i2c_del_driver(&stmems_driver);
-+}
++struct nomadik_i2c_private {
++      __u32 id;               // bus id
++      struct i2c_adapter *adap;
++      int irq;
++      struct semaphore sema;  // Use for blocking on aa message completion
++      int fast_mode;
++      void __iomem *regs;
++      wait_queue_head_t event_wq;
++      struct i2c_controller_config config;
++};
 +
-+static inline int stmems_join(u8 LSB, u8 MSB)
++static inline int nomadik_i2c_check_client_id(__u32 id)
 +{
-+      /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
-+      if (MSB & 0x10)
-+      MSB |= 0xE0;
-+      return (s16)(LSB | ((MSB << 8)));
++      if ((id < 0) || (id >= I2C_NUM_CLIENTS)) {
++              return -EINVAL;
++      }
++      return 0;
 +}
 +
-+MODULE_AUTHOR("Nicholas Angelo Crespi <roundtrip@gmail.com>");
-+MODULE_DESCRIPTION("LIS3LV02DL MEMS three-axis accelerometer I2C driver");
-+MODULE_VERSION(VERSION);
-+MODULE_LICENSE("GPL");
++/*-----------------------------------------------------------------------------
++      Configuration functions
++-----------------------------------------------------------------------------*/
++int setup_i2c_controller(struct nomadik_i2c_private *priv);
 +
-+module_init(stmems_init);
-+module_exit(stmems_exit);
-diff -Nauprw linux-2.6.20/drivers/hwmon/Makefile ../new/linux-2.6.20/drivers/hwmon/Makefile
---- linux-2.6.20/drivers/hwmon/Makefile        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/hwmon/Makefile 2008-09-16 23:41:15.000000000 +0530
-@@ -30,6 +30,7 @@ obj-$(CONFIG_SENSORS_GL520SM)        += gl520sm
- obj-$(CONFIG_SENSORS_HDAPS)   += hdaps.o
- obj-$(CONFIG_SENSORS_IT87)    += it87.o
- obj-$(CONFIG_SENSORS_K8TEMP)  += k8temp.o
-+obj-$(CONFIG_SENSORS_LIS3LV02DL)+= lis3lv02dl.o
- obj-$(CONFIG_SENSORS_LM63)    += lm63.o
- obj-$(CONFIG_SENSORS_LM70)    += lm70.o
- obj-$(CONFIG_SENSORS_LM75)    += lm75.o
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c
---- linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c       2008-10-20 13:37:45.000000000 +0530
-@@ -0,0 +1,1250 @@
++int write_i2c(struct nomadik_i2c_private *priv);
 +
-+/* drivers/i2c/busses/i2c-nomadik.c
++int read_i2c(struct nomadik_i2c_private *priv);
++
++int process_interrupt(struct nomadik_i2c_private *priv);
++int verify_parameters(struct nomadik_i2c_private *priv);
++void reset_i2c(struct nomadik_i2c_private *priv);
++void disable_i2c(struct nomadik_i2c_private *priv);
++void stn_cut_mdelay(int dlytime);
++
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c
+@@ -0,0 +1,1723 @@
++
++/* drivers/i2c/busses/i2c-nmdk8810.c
 + *
-+ * Support for i2c bus on STn8800/8810/8815 (Nomadik) chips.
++ * Support for i2c bus on STn8810 (Nomadik) chips.
 + *
 + * 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
@@ -27825,1489 +30095,138 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.c ../new/linux-2.6.20/d
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + *
++ * Author: Melwyn LOBO <melwyn.lobo@st.com>
++ *-----------------------------------------------------------------------------
 + */
 +
++
 +#include <linux/module.h>
 +#include <linux/kernel.h>
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <linux/i2c.h>
-+#include <linux/platform_device.h>
-+#include <linux/i2c-id.h>
-+#include <asm/hardware.h>
++
 +#include "i2c-nomadik.h"
-+#include <asm/arch/gpio.h>
-+#define DRIVER_VERSION "2.0.0"
-+#define width 0
-+#define BUSID 1
-+#define error(format, arg...) printk( KERN_ERR "I2C: " format , ## arg)
-+#define info(format, arg...)
-+/*printk( KERN_INFO "I2C: %s " format, __func__, ## arg)*/
++#include <linux/delay.h>
 +
-+static unsigned int nomadik_i2c_func(struct i2c_adapter *adap);
-+static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
-+                          struct i2c_msg msgs[], int num);
-+static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
-+                          struct i2c_msg msgs[], int num);
++#define I2C_ENDAD_COUNTER       50000
++#define I2C_INT_ENDED_COUNTER   50000
++#define I2C_BTF_COUNTER         50000
++#define I2C_BTF_COUNTER_POLLING 50000
++#define I2C_FIFO_FLUSH_COUNTER       500
++#define I2C_LOWER_SLAVE       127
++#define I2C_UPPER_SLAVE       1024
 +
-+/* Other variables indexed by bus */
-+static struct nomadik_i2c_private i2c_driver[2];
++/*#######################################################################
++      Macros to access I2C Registers with their offsets
++#########################################################################
++*/
 +
-+static struct i2c_algorithm nomadik_i2c_algo = {
-+      master_xfer:nomadik_i2c_xfer,
-+      smbus_xfer:NULL,
-+      algo_control:NULL,
-+      functionality:nomadik_i2c_func
-+};
++#define I2C_REG_OFFSET_CR               0x00
++#define I2C_REG_OFFSET_SR1              0x04
++#define I2C_REG_OFFSET_SR2              0x08
++#define I2C_REG_OFFSET_CCR              0x0C
++#define I2C_REG_OFFSET_OAR1             0x10
++#define I2C_REG_OFFSET_OAR2             0x14
++#define I2C_REG_OFFSET_DR               0x18
++#define I2C_REG_OFFSET_ECCR           0x1C
 +
-+static struct i2c_adapter nomadik_i2c[2] = { {
-+      name:                         "i2c0",
-+      id:                           I2C_ALGO_NOMADIK |
-+                                    I2C_HW_NOMADIK,
-+      algo:                         &nomadik_i2c_algo,
-+      data:   &i2c_driver[0],
-+      class:  I2C_CLASS_HWMON
++/*#######################################################################
++      Macros to access I2C Interrupt Registers event
++#########################################################################
++*/
 +
-+                                            },
-+{
-+      name:"i2c1",
-+      id:I2C_ALGO_NOMADIK | I2C_HW_NOMADIK,
-+      algo:&nomadik_i2c_algo,
-+      data:&i2c_driver[1],
-+ }
-+};
++#define    I2C0_IRQ_SRC_ALL  0
++#define    I2C1_IRQ_SRC_ALL  1
 +
-+#if !defined (CONFIG_NOMADIK_NHK15)
-+static struct i2c_client nomadik_i2c_clients[] = {
-+      {
-+            name:"motherboard",
-+            id:I2C_MB_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_MB,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"ui db",
-+            id:I2C_UI_DB_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_UI_DB,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"io expansion db1",
-+            id:I2C_IO_EXP_DB1_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_IO_DB1,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"io expansion db2",
-+            id:I2C_IO_EXP_DB2_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_IO_DB2,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"Matisse camera",
-+            id:I2C_CIF_CAM_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_CIF_CAM,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"mem exp",
-+            id:I2C_MEM_EXP_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_MEM_EXP,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"audio codec",
-+            id:I2C_AUDIO_CODEC_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_AC,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"FM tuner",
-+            id:I2C_FM_TUNER_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_FM_TUNER,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"Gas Gauge",
-+            id:I2C_GAS_GAUGE_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_GAS_GAUGE,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"Matiise for litea cam",
-+            id:I2C_LITEA_CAM_MOD_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_CAM_MOD,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"i2c0 loopback",
-+            id:I2C0_LOOP_CLIENT,
-+            flags:0,
-+            addr:I2C0_LP_OWNADDR,
-+            adapter:&nomadik_i2c[0]
-+       },
-+      {
-+            name:"i2c1 loopback",
-+            id:I2C1_LOOP_CLIENT,
-+            flags:0,
-+            addr:I2C1_LP_OWNADDR,
-+            adapter:&nomadik_i2c[1]
-+       },
-+      {
-+            name:"Pepperpot camera",
-+            id:I2C_PP_CAM_CLIENT,
-+            flags:0,
-+            addr:I2C_ADDR_PP_CAM,
-+            adapter:&nomadik_i2c[BUSID]
-+       },
-+      {
-+            name:"Touareg",
-+            id:I2C_TOUAREG_CLIENT,
-+            adapter:&nomadik_i2c[I2C_TOUAREG_ADAPTER],
-+            flags:0,
-+            addr:I2C_ADDR_TOUAREG,
-+       }
++#define               I2C_IT_BTF              STD_MASK_BIT0
++#define               I2C_IT_ADSL             STD_MASK_BIT1
++#define               I2C_IT_SB               STD_MASK_BIT2
++#define               I2C_IT_AF               STD_MASK_BIT3
++#define               I2C_IT_STOPF            STD_MASK_BIT4
++#define               I2C_IT_ARLO             STD_MASK_BIT5
++#define               I2C_IT_BERR             STD_MASK_BIT6
++#define               I2C_IT_ADD10            STD_MASK_BIT7
++#define               I2C_IT_SCLFAL           STD_MASK_BIT8
++#define               I2C_IT_ENDAD            STD_MASK_BIT9
 +
-+};
-+#else
-+static struct i2c_client nomadik_i2c_clients[] = {
-+        {//0x42
-+              name:"Denc",
-+              id:I2C_DENC_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_DENC,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//0x34
-+              name:"audio codec",
-+              id:I2C_AUDIO_CODEC_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_AC,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//0x20
-+              name:"FM tuner",
-+              id:I2C_FM_TUNER_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_FM_TUNER,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//FIXME
-+                name:"Matiise for litea cam",
-+                id:I2C_LITEA_CAM_MOD_CLIENT,
-+                flags:0,
-+                addr:I2C_ADDR_CAM_MOD,
-+                adapter:&nomadik_i2c[BUSID]
-+        },
-+        {//0x3A
-+              name:"mems",
-+              id:I2C_MEMS_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_MEMS,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//0x44, 0x46
-+              name:"SIM card",
-+            id:I2C_SIM_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_SIM,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//0x90
-+              name:"touch screen",
-+              id:I2C_TOUCH_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_TOUCH,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//0x86
-+                name: "PEXP0",
-+                id:I2C_STMPE0_CLIENT,
-+                flags:0,
-+                addr:I2C_ADDR_STMPE0,
-+                adapter:&nomadik_i2c[0],
-+        },
-+        {//0x88
-+                name: "PEXP1",
-+                id:I2C_STMPE1_CLIENT,
-+                flags:0,
-+                addr:I2C_ADDR_STMPE1,
-+                adapter:&nomadik_i2c[0],
-+        },
-+        {//0xE0
-+              name:"Gas Gauge",
-+              id:I2C_GAS_GAUGE_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_GAS_GAUGE,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {//0x5A FIXME - MMC
-+              name:"Power manager",
-+              id:I2C_TOUAREG_CLIENT,
-+              flags:0,
-+              addr:I2C_ADDR_POWER,
-+              adapter:&nomadik_i2c[0]
-+         },
-+       {
-+              name:"i2c0 loopback",
-+              id:I2C0_LOOP_CLIENT,
-+              flags:0,
-+              addr:I2C0_LP_OWNADDR,
-+              adapter:&nomadik_i2c[0]
-+         },
-+        {
-+              name:"i2c1 loopback",
-+              id:I2C1_LOOP_CLIENT,
-+              flags:0,
-+              addr:I2C1_LP_OWNADDR,
-+              adapter:&nomadik_i2c[1]
-+         },
++/*#######################################################################
++      I2C Control Register
++#########################################################################
++*/
 +
-+};
-+#endif
++#define I2C_ITE                 STD_MASK_BIT0
++#define I2C_STOP                STD_MASK_BIT1
++#define I2C_ACK                 STD_MASK_BIT2
++#define I2C_START               STD_MASK_BIT3
++#define I2C_ENGC                STD_MASK_BIT4
++#define I2C_PE                  STD_MASK_BIT5
++#define I2C_TRANS               STD_MASK_BIT6
++#define I2C_DDC1EN              STD_MASK_BIT7
++#define I2C_SHIFT_ITE     0
++#define I2C_SHIFT_STOP    1
++#define I2C_SHIFT_ACK     2
++#define I2C_SHIFT_START   3
++#define I2C_SHIFT_ENGC    4
++#define I2C_SHIFT_PE      5
++#define I2C_SHIFT_TRANS   6
++#define I2C_SHIFT_DDC1EN  7
 +
-+#if !defined(CONFIG_NOMADIK_NHK15)
++/*#######################################################################
++      I2C Status Register1
++#########################################################################
++*/
 +
-+/* This is an array of bus ids indexed by client id. They MUST be in the
-+   sam order as the client structs above
-+ */
-+static __u32 nomadik_client_bus_id[] =
-+    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, I2C_CLIENT_BUSID13 };
++#define I2C_SB                  STD_MASK_BIT0
++#define I2C_MASTER              STD_MASK_BIT1
++#define I2C_ADSL                STD_MASK_BIT2
++#define I2C_BTF                 STD_MASK_BIT3
++#define I2C_BUSY                STD_MASK_BIT4
++#define I2C_TRA                 STD_MASK_BIT5
++#define I2C_ADD10               STD_MASK_BIT6
++#define I2C_EVF                 STD_MASK_BIT7
++#define I2C_SHIFT_SB            0
++#define I2C_SHIFT_MASTER        1
++#define I2C_SHIFT_ADSL          2
++#define I2C_SHIFT_BTF       3
++#define I2C_SHIFT_BUSY          4
++#define I2C_SHIFT_TRA       5
++#define I2C_SHIFT_ADD10     6
++#define I2C_SHIFT_EVF           7
 +
-+static struct nomadik_i2c_client priv_client[] = {
-+      {
-+            id:I2C_MB_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_MB,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_UI_DB_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_UI_DB,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_IO_EXP_DB1_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_IO_DB1,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_IO_EXP_DB2_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_IO_DB2,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_CIF_CAM_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_CIF_CAM,
-+            endianness:LITTLE_END,
-+      index_width:REG8},
-+      {
-+            id:I2C_MEM_EXP_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_MEM_EXP,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_AUDIO_CODEC_CLIENT,
-+            bus_id:1,
-+            addr:I2C_ADDR_AC,
-+            endianness:LITTLE_END,
-+      index_width:REG8},
-+      {
-+            id:I2C_FM_TUNER_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_FM_TUNER,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_GAS_GAUGE_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_GAS_GAUGE,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_LITEA_CAM_MOD_CLIENT,
-+            bus_id:BUSID,
-+            addr:I2C_ADDR_CAM_MOD,
-+            endianness:LITTLE_END,
-+      index_width:REG16},
-+      {
-+            id:I2C0_LOOP_CLIENT,
-+            bus_id:0,
-+            addr:I2C0_LP_OWNADDR,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C1_LOOP_CLIENT,
-+            bus_id:1,
-+            addr:I2C1_LP_OWNADDR,
-+            endianness:LITTLE_END,
-+      index_width:0},
-+      {
-+            id:I2C_PP_CAM_CLIENT,
-+       /* added for Pepperpot camera */
-+            bus_id:1,
-+            addr:I2C_ADDR_PP_CAM,
-+            endianness:BIG_END,
-+      index_width:REG16},
-+      {
-+            id:I2C_TOUAREG_CLIENT,
-+       /* added for Touareg chip for power mgmt */
-+            bus_id:I2C_TOUREG_CLIENT_BUSID,
-+            addr:I2C_ADDR_TOUAREG,
-+            endianness:LITTLE_END,
-+            index_width:REG8
-+#ifdef CONFIG_NOMADIK_NDK15
-+       },
-+      {
-+            id:I2C_CPLD_CLIENT,
-+       /* added for CPLD */
-+            bus_id:I2C_CPLD_CLIENT_BUSID,
-+            addr:I2C_ADDR_CPLD,
-+            endianness:LITTLE_END,
-+       /* check */
-+            index_width:REG8
-+#endif
-+       },
-+      {
-+            id:I2C_DENC_CLIENT,
-+            bus_id:1,
-+            addr:I2C_ADDR_DENC,
-+            endianness:LITTLE_END,
-+      index_width:REG8}
++/*#######################################################################
++      I2C Status Register2
++#########################################################################
++*/
 +
-+};
++#define I2C_GCAL                STD_MASK_BIT0
++#define I2C_BERR                STD_MASK_BIT1
++#define I2C_ARLO                STD_MASK_BIT2
++#define I2C_STOPF               STD_MASK_BIT3
++#define I2C_AF                  STD_MASK_BIT4
++#define I2C_ENDAD               STD_MASK_BIT5
++#define I2C_SCLFAL              STD_MASK_BIT7
++#define I2C_SHIFT_GCAL    0
++#define I2C_SHIFT_BERR    1
++#define I2C_SHIFT_ARLO    2
++#define I2C_SHIFT_STOPF   3
++#define I2C_SHIFT_AF      4
++#define I2C_SHIFT_ENDAD   5
++#define I2C_SHIFT_SCLFAL  7
 +
-+#else
-+/* This is an array of bus ids indexed by client id. They MUST be in the
-+   sam order as the client structs above
-+ */
-+static __u32 nomadik_client_bus_id[] =
-+    { 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 1};
++/*#######################################################################
++      I2C Clock Control Register
++#########################################################################
++*/
 +
-+static struct nomadik_i2c_client priv_client[] = {
-+        {
-+              id:I2C_DENC_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_DENC,
-+              endianness:LITTLE_END,
-+      index_width:REG8},
-+        {
-+              id:I2C_AUDIO_CODEC_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_AC,
-+              endianness:LITTLE_END,
-+      index_width:REG8},
-+        {
-+              id:I2C_FM_TUNER_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_FM_TUNER,
-+              endianness:LITTLE_END,
-+      index_width:0},
-+        {
-+              id:I2C_LITEA_CAM_MOD_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_CAM_MOD,
-+              endianness:LITTLE_END,
-+      index_width:0},
-+        {
-+              id:I2C_MEMS_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_MEMS,
-+              endianness:LITTLE_END,
-+      index_width:REG8},
-+        {
-+              id:I2C_SIM_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_SIM,
-+              endianness:LITTLE_END,
-+      index_width:0},
-+        {
-+              id:I2C_TOUCH_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_TOUCH,
-+              endianness:LITTLE_END,
-+      index_width:0},
-+        {
-+                id:I2C_STMPE0_CLIENT,
-+                bus_id:0,
-+                addr:I2C_ADDR_STMPE0,
-+                endianness:LITTLE_END,
-+      index_width:REG8
-+        },
-+        {
-+                id:I2C_STMPE1_CLIENT,
-+                bus_id:0,
-+                addr:I2C_ADDR_STMPE1,
-+                endianness:LITTLE_END,
-+                index_width:REG8
-+        },
-+        {
-+              id:I2C_GAS_GAUGE_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_GAS_GAUGE,
-+              endianness:LITTLE_END,
-+      index_width:REG8},
-+        {
-+              id:I2C_TOUAREG_CLIENT,
-+              bus_id:0,
-+              addr:I2C_ADDR_POWER,
-+              endianness:LITTLE_END,
-+      index_width:REG8},
-+      {
-+              id:I2C0_LOOP_CLIENT,
-+              bus_id:0,
-+              addr:I2C0_LP_OWNADDR,
-+              endianness:LITTLE_END,
-+      index_width:0},
-+        {
-+              id:I2C1_LOOP_CLIENT,
-+              bus_id:1,
-+              addr:I2C1_LP_OWNADDR,
-+              endianness:LITTLE_END,
-+      index_width:0},
++#define I2C_CLOCK_MASK  0x7F
++#define I2C_FM_SM_MASK  0x80
 +
-+};
-+#endif        /*CONFIG_NOMADIK_NHK15*/
-+static int i2c_initialize(struct nomadik_i2c_private *priv)
-+{
-+      /* Transfer configuration */
-+      priv->config.freq_scl = STD_SPEED_IN_HZ;
-+      priv->config.i2c_transmit_interrupt_threshold = 4;
-+      priv->config.i2c_receive_interrupt_threshold = 4;
++/*#######################################################################
++    Default I2C Register Values
++#########################################################################
++*/
 +
-+      priv->config.bus_control_mode = I2C_BUS_MASTER_MODE;
-+      priv->config.index_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
-+      priv->config.data_transfer_mode = I2C_TRANSFER_MODE_INTERRUPT;
-+
-+      /* Device configuration */
-+      priv->config.freq_input = STD_F_IN_HZ;
-+
-+      if (priv->id)
-+              priv->config.own_address = I2C1_LP_OWNADDR;
-+      else
-+              priv->config.own_address = I2C0_LP_OWNADDR;
-+
-+      if (setup_i2c_controller(priv) != 0) {
-+              error("i2c device config 0 failed init\n");
-+              return -EIO;
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * nomadik_i2c_get_info - Get status information of I2C controller
-+ *
-+ * @bus_id - The controller id.
-+ * info - Info pointer describing  the controller status.
-+ *
-+ * Return an info struct with current bus parameters.
-+ **/
-+
-+int nomadik_i2c_get_info(__u32 bus_id, i2c_info_t * info)
-+{
-+      struct nomadik_i2c_private *priv;
-+      priv = &i2c_driver[bus_id];
-+      info->baseAddress = (__u32) priv->regs;
-+      info->id = priv->id;
-+      info->mode = priv->config.mode;
-+      info->enabled = priv->config.enabled;
-+      info->fSCL = priv->config.freq_scl;
-+      info->fIn = priv->config.freq_input;
-+      info->ownAddress = priv->config.own_address;
-+
-+      return 0;
-+}
-+
-+/**
-+ * nomadik_get_client - Get client information
-+ *
-+ * @client_id - Client id for the I2C device.
-+ *
-+ * This function returns the address of the client struct identified by
-+ * client_id
-+ **/
-+
-+struct i2c_client *nomadik_i2c_get_client(__u32 client_id)
-+{
-+      if ((client_id < 0) || (client_id >= I2C_NUM_CLIENTS)) {
-+              error("error: nomadik get_client: client = %d\n", client_id);
-+              return 0;
-+      }
-+      return &nomadik_i2c_clients[client_id];
-+}
-+
-+/**
-+ * nomadik_i2c_is_busy - Check if the client is busy in an operation.
-+ *
-+ * @client_id - Identifier for the client whose status is required.
-+ *
-+ * This function checks the status of an event_type I2C_NO_EVENT. If this is
-+ * the current active event, the controller is not busy, and the function
-+ * returns false (0). If this is not the current event type, then the bus is
-+ * in the process of doing something, so we return true -EBUSY. Note that there
-+ * is no guarantee that the bus will not become busy between this call and
-+ * a transfer request, so calls to the transfer functions should
-+ * check the return - it will be -EBUSY if the bus is in use. -EINVAL
-+ * is returned for an invalid client_id.
-+ **/
-+
-+int nomadik_i2c_is_busy(__u32 client_id)
-+{
-+      int retval;
-+
-+      if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
-+              return retval;
-+
-+      if (i2c_driver[nomadik_client_bus_id[client_id]].config.active_event.
-+          type == I2C_NO_EVENT)
-+              return 0;
-+      return -EBUSY;
-+}
-+
-+static irqreturn_t nomadik_i2c_irq_handler(int irq,
-+                                         void *arg)
-+{
-+      __u32 id = ((struct nomadik_i2c_private *)arg)->id;
-+      disable_irq(irq);
-+      process_interrupt(&i2c_driver[id]);
-+
-+      enable_irq(i2c_driver[id].irq);
-+      return IRQ_HANDLED;
-+}
-+
-+/**
-+ * nomadik_i2c_wait_msg
-+ *
-+ * @nomadik_i2c_private - Private data for the controller
-+ * @len - Amount of data in bytes to be transferred
-+ *
-+ * Poll until the event we've started is finished.
-+ * Wait 1000 microseconds for each byte transferred.
-+ * Here we have not used wait_event_interruptible_timeout()
-+ * as this would cause a schedule in interrupt context in case I2C routines
-+ * called by client drivers in interrupt handlers
-+ *
-+ * This function should be called ONLY by this driver.
-+ **/
-+#define WAIT_CONDITION        (priv->config.active_event.type > I2C_NO_EVENT && priv->config.active_event.type <= I2C_BUS_ERROR_EVENT)
-+
-+static int nomadik_i2c_wait_msg(struct nomadik_i2c_private *priv, int len)
-+{
-+      if(wait_event_interruptible(priv->event_wq, WAIT_CONDITION))
-+              return -EINVAL;
-+
-+      return 0;
-+}
-+
-+/**
-+ * nomadik_i2c_xfer_byte - I2C transfer function used by nomadik_i2c_xfer to
-+ * transfer a single byte
-+ * @i2c_adapter - Adapter pointer to the controller
-+ * @msgs[] - Pointer to data to be written.
-+ * @num - Num messages
-+ *
-+ **/
-+
-+static int nomadik_i2c_xfer_byte(struct i2c_adapter *i2c_adap,
-+                          struct i2c_msg msgs[], int num)
-+{
-+      int m, mm;
-+      int status;
-+      unsigned int addr;
-+      struct nomadik_i2c_private *priv =
-+          (struct nomadik_i2c_private *)i2c_adap->data;
-+      __u32 bus_id = priv->id;
-+      int read = 0;
-+
-+      if (msgs[0].len <= 0)
-+              return 0;
-+
-+      addr = msgs[0].addr;
-+
-+      if (msgs[0].flags & I2C_M_TEN)
-+      {
-+              error("10 bit addressing not yet supported\n");
-+              return -EINVAL;
-+      }
-+
-+      if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+              return -ERESTARTSYS;
-+
-+      for (m = 0; m < num; m++)
-+      {
-+              info("message: %d, addr: %d\n", m,  msgs[m].addr);
-+              info("message: %d, flags: %d\n", m, msgs[m].flags);
-+              info("message: %d, len: %d\n", m, msgs[m].len);
-+
-+              for(mm = 0; mm <  msgs[m].len; mm++)
-+                      info("message: %d, buf[%d]: 0x%02X\n", m, mm, msgs[m].buf[mm]);
-+
-+              info("message: %d, bus id: 0x%02X\n", m, bus_id);
-+      }
-+
-+#if !defined(CONFIG_NOMADIK_NHK15)
-+      reset_i2c(priv);
-+#endif
-+
-+      /* Save parameters. */
-+      priv->config.slave_address = addr;
-+      priv->config.status = I2C_STATUS_SLAVE_MODE;
-+      priv->config.index_format = I2C_BYTE_INDEX;
-+      priv->config.active_event.type = I2C_NO_EVENT;
-+      priv->config.multi_operation = NOMADIK_TRUE;
-+
-+      if (i2c_initialize(priv)) {
-+              up(&nomadik_i2c[bus_id].lock);
-+              return -EINVAL;
-+      }
-+
-+      if (verify_parameters(priv))
-+      {
-+              error("Error in parameters\n");
-+              up(&nomadik_i2c[bus_id].lock);
-+              return -EINVAL;
-+      }
-+
-+      if (num > 1)
-+      {
-+              if (msgs[1].flags & I2C_M_RD)
-+              {
-+                      read = 1;
-+              }
-+      }
-+
-+      if (read != 0)
-+      {
-+
-+              /* Save parameters. */
-+              priv->config.databuffer = &(msgs[1].buf[0]);
-+              priv->config.count_data = msgs[1].len;
-+              priv->config.register_index = msgs[0].buf[0];
-+              /* Do the read */
-+              priv->config.operation = I2C_READ;
-+
-+              status = read_i2c(priv);
-+
-+              if (status)
-+              {
-+                      error("Error in read_register: %d\n", status);
-+                      up(&nomadik_i2c[bus_id].lock);
-+                      return status;
-+              }
-+              else if (status == 0)
-+              {
-+
-+                      if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
-+                      {
-+                              status = nomadik_i2c_wait_msg(priv, msgs[0].len);
-+                              if (status)
-+                              {
-+                                      error("Message timeout with no handled event\n");
-+                                      error("error waiting for i2c read: %d\n", status);
-+                                      up(&nomadik_i2c[bus_id].lock);
-+                                      return status;
-+                              }
-+                      }
-+              }
-+
-+              info("ret message: 0, buf[0]: 0x%02X\n", msgs[0].buf[0]);
-+              info("ret message: 1, buf[0]: 0x%02X\n", msgs[1].buf[0]);
-+
-+              mdelay(1);
-+              priv->config.active_event.type = I2C_NO_EVENT;
-+
-+              up(&nomadik_i2c[bus_id].lock);
-+      }
-+      else
-+      {
-+              /* Save parameters. */
-+              priv->config.databuffer = &(msgs[0].buf[1]);
-+              priv->config.count_data = 1;
-+              priv->config.register_index = msgs[0].buf[0];
-+
-+              /* Do the write */
-+              priv->config.operation = I2C_WRITE;
-+              status = write_i2c(priv);
-+              if (status)
-+              {
-+                      error("Error in write_register: %d\n", status);
-+                      up(&nomadik_i2c[bus_id].lock);
-+                      return status;
-+              }
-+              else if (status == 0)
-+              {
-+                      if (priv->config.data_transfer_mode != I2C_TRANSFER_MODE_POLLING)
-+                      {
-+                              status = nomadik_i2c_wait_msg(priv, msgs[0].len - 1);
-+                              if (status)
-+                              {
-+                                      error("Message timeout with no handled event\n");
-+                                      error("error waiting for i2c write: %d\n", status);
-+                                      up(&nomadik_i2c[bus_id].lock);
-+                                      return status;
-+                              }
-+                      }
-+              }
-+              mdelay(1);
-+              priv->config.active_event.type = I2C_NO_EVENT;
-+              up(&nomadik_i2c[bus_id].lock);
-+      }
-+
-+      return 0;
-+
-+}
-+
-+/**
-+ * nomadik_i2c_xfer - I2C transfer function used by kernel framework
-+ * @i2c_adapter - Adapter pointer to the controller
-+ * @msgs[] - Pointer to data to be written.
-+ * @num - Amount of data in bytes to be written
-+ *
-+ * This is the function called by the generic kernel i2c API calls. Note that
-+ * this code is protected by the semaphore set in the kernel i2c_transfer()
-+ * function.
-+ * Retrive the client specific information from the client id and feed it to
-+ * the controller specific configuration. Then call the respective board
-+ * specific routine.
-+ **/
-+
-+static int nomadik_i2c_xfer(struct i2c_adapter *i2c_adap,
-+                          struct i2c_msg msgs[], int num)
-+{
-+      int i;
-+      int status;
-+      unsigned int addr;
-+      struct nomadik_i2c_private *priv =
-+          (struct nomadik_i2c_private *)i2c_adap->data;
-+      __u32 bus_id = priv->id;
-+      /*read byte or write byte, SMBus emulated (see i2c_smbus_xfer_emulated)*/
-+      if ((num == 2 && msgs[0].len == 1 && msgs[1].len == 1 && (msgs[1].flags & I2C_M_RD)) ||
-+         (num == 1 && msgs[0].len == 2 && ((msgs[0].flags & I2C_M_RD) == 0)))
-+      {
-+              return nomadik_i2c_xfer_byte(i2c_adap, msgs, num);
-+      }
-+
-+      for (i = 0; i < num; i++) {     /* deal with  message i */
-+              if (msgs[i].len > 0) {  /*sanity check - message length */
-+                      /*prepare address */
-+                      addr = msgs[i].addr;
-+                      if (msgs[i].flags & I2C_M_RD)
-+                              addr |= 0x1;
-+
-+                      if (msgs[i].flags & I2C_M_TEN) {
-+                              error("10 bit addressing not yet supported\n");
-+                              return -EINVAL;
-+                      }
-+
-+                      if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+                              return -ERESTARTSYS;
-+
-+                      reset_i2c(priv);
-+
-+                      /* Save parameters. */
-+                      priv->config.slave_address = addr;
-+                      priv->config.status = I2C_STATUS_SLAVE_MODE;
-+                      priv->config.index_format = I2C_NO_INDEX;
-+                      priv->config.databuffer = msgs[i].buf;
-+                      priv->config.count_data = msgs[i].len;
-+                      priv->config.multi_operation = NOMADIK_TRUE;
-+
-+                      if (i2c_initialize(priv)) {
-+                              up(&nomadik_i2c[bus_id].lock);
-+                              return -EINVAL;
-+                      }
-+
-+                      if (verify_parameters(priv)) {
-+                              error("Error in parameters\n");
-+                              up(&nomadik_i2c[bus_id].lock);
-+                              return -EINVAL;
-+                      }
-+
-+                      if (addr & 1) {
-+                              /* Do the read */
-+                              priv->config.operation = I2C_READ;
-+                              /* read */
-+                              status = read_i2c(priv);
-+                              if (status) {
-+                                      error("Error in read_register: %d\n",
-+                                            status);
-+                                      up(&nomadik_i2c[bus_id].lock);
-+                                      return status;
-+                              } else if (status == 0) {
-+
-+                                      if (priv->config.data_transfer_mode !=
-+                                          I2C_TRANSFER_MODE_POLLING) {
-+                                              status =
-+                                                  nomadik_i2c_wait_msg(priv,
-+                                                                       msgs
-+                                                                       [i].
-+                                                                       len);
-+                                              if (status) {
-+                                                      error
-+                                                          ("Message timeout with no handled event\n");
-+                                                      error
-+                                                          ("error waiting for i2c read: %d\n",
-+                                                           status);
-+                                                      up(&nomadik_i2c[bus_id].
-+                                                         lock);
-+                                                      return status;
-+                                              }
-+                                      }
-+                              }
-+                              /* mdelay(1); */ /* NM */
-+                              priv->config.active_event.type = I2C_NO_EVENT;
-+                              up(&nomadik_i2c[bus_id].lock);
-+
-+                      } else {
-+                              /* Do the write */
-+                              priv->config.operation = I2C_WRITE;
-+                              status = write_i2c(priv);
-+                              if (status) {
-+                                      error("Error in write_register: %d\n",
-+                                            status);
-+                                      up(&nomadik_i2c[bus_id].lock);
-+                                      return status;
-+                              } else if (status == 0) {
-+
-+                                      if (priv->config.data_transfer_mode !=
-+                                          I2C_TRANSFER_MODE_POLLING) {
-+                                              status =
-+                                                  nomadik_i2c_wait_msg(priv,
-+                                                                       msgs
-+                                                                       [i].
-+                                                                       len);
-+                                              if (status) {
-+                                                      error
-+                                                          ("Message timeout with no handled event\n");
-+                                                      error
-+                                                          ("error waiting for i2c write: %d\n",
-+                                                           status);
-+                                                      up(&nomadik_i2c[bus_id].
-+                                                         lock);
-+                                                      return status;
-+                                              }
-+                                      }
-+                              }
-+                              /* mdelay(1); */ /* NM */
-+                              priv->config.active_event.type = I2C_NO_EVENT;
-+                              up(&nomadik_i2c[bus_id].lock);
-+                      }
-+
-+              }
-+      }
-+      return 0;
-+}
-+
-+/**
-+ * nomadik_i2c_write_register
-+ *
-+ * nomadik_i2c_write_register - Write data to I2C client
-+ * @client_id - Identifier for the client
-+ * @data - Pointer to data to be written.
-+ * @index - Register index of the client
-+ * @count - Amount of data in bytes to be written
-+ *
-+ * Handle all register index type writes.  Using the client structs for
-+ * the client_id, we can call the correct register write function and
-+ * ensure a two byte index has the correct byte order.
-+ * Retrive the client specific information from the client id and feed it to
-+ * the controller specific configuration. Then call the respective board
-+ * specific routine.
-+ **/
-+
-+int nomadik_i2c_write_register(__u32 client_id,
-+                             __u8 * data, int index, int count)
-+{
-+      int bus_id;
-+      int retval;
-+      __u16 addr;
-+      struct nomadik_i2c_client *client;
-+      struct nomadik_i2c_private *priv;
-+
-+      if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
-+              return retval;
-+
-+      client = &priv_client[client_id];
-+      bus_id = client->bus_id;
-+      priv = &i2c_driver[bus_id];
-+      addr = client->addr;
-+
-+      if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+              return -ERESTARTSYS;
-+
-+//    reset_i2c(priv);
-+
-+      /* Save parameters. */
-+      priv->config.slave_address = addr;
-+      priv->config.status = I2C_STATUS_SLAVE_MODE;
-+      priv->config.register_index = index;
-+#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
-+      priv->config.index_format =
-+          ((client->index_width ==
-+            REG8) ? I2C_BYTE_INDEX : (client->
-+                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+                                      : I2C_HALF_WORD_BIG_ENDIAN));
-+#else
-+      priv->config.index_format =
-+          ((client->index_width == 0)?I2C_NO_INDEX:
-+           (client->index_width == REG8) ? I2C_BYTE_INDEX : (client->
-+                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+                                      : I2C_HALF_WORD_BIG_ENDIAN));
-+#endif
-+      priv->config.databuffer = data;
-+      priv->config.count_data = count;
-+      priv->config.active_event.type = I2C_NO_EVENT;
-+      priv->config.multi_operation = NOMADIK_TRUE;
-+      /* Do the write */
-+      priv->config.operation = I2C_WRITE;
-+
-+      if (i2c_initialize(priv)) {
-+              up(&nomadik_i2c[bus_id].lock);
-+              return -EINVAL;
-+      }
-+
-+      if (verify_parameters(priv)) {
-+              error("Error in parameters\n");
-+              up(&nomadik_i2c[bus_id].lock);
-+              return -EINVAL;
-+      }
-+
-+      retval = write_i2c(priv);
-+
-+      if (retval) {
-+              error("Error in write_register: %d\n", retval);
-+      } else if (retval == 0) {
-+
-+              if (priv->config.data_transfer_mode !=
-+                  I2C_TRANSFER_MODE_POLLING) {
-+                      retval = nomadik_i2c_wait_msg(priv, count);
-+                      if (retval) {
-+                              error
-+                                  ("Message timeout with no handled event\n");
-+                              error("error waiting for i2c read: %d\n",
-+                                    retval);
-+                              up(&nomadik_i2c[bus_id].lock);
-+                              return retval;
-+                      }
-+              }
-+              else mdelay(1);
-+              priv->config.active_event.type = I2C_NO_EVENT;
-+              up(&nomadik_i2c[bus_id].lock);
-+              return retval;
-+      }
-+
-+      up(&nomadik_i2c[bus_id].lock);
-+
-+      /* Neither register mode for this client, return an error */
-+      return -EINVAL;
-+}
-+
-+/**
-+ * nomadik_i2c_read_register - Read data from I2C client
-+ * @client_id - Identifier for the client
-+ * @data - Pointer where the read data will be written.
-+ * @index - Register index of the client
-+ * @count - Amount of data in bytes to be read
-+ *
-+ * Handle all register index type writes.  Using the client structs for
-+ * the client_id, we can call the correct register write function and
-+ * ensure a two byte index has the correct byte order.
-+ * Retrive the client specific information from the client id and feed it to
-+ * the controller specific configuration. Then call the respective board
-+ * specific routine.
-+ **/
-+
-+int nomadik_i2c_read_register(__u32 client_id,
-+                            __u8 * data, int index, int count)
-+{
-+      int bus_id;
-+      int retval;
-+      __u16 addr;
-+      struct nomadik_i2c_client *client;
-+      struct nomadik_i2c_private *priv;
-+
-+      if ((retval = nomadik_i2c_check_client_id(client_id)) < 0)
-+              return retval;
-+
-+      client = &priv_client[client_id];
-+      bus_id = client->bus_id;
-+      priv = &i2c_driver[bus_id];
-+      addr = client->addr;
-+
-+      if (down_interruptible(&nomadik_i2c[bus_id].lock))
-+              return -ERESTARTSYS;
-+
-+//    reset_i2c(priv);
-+
-+      /* Save parameters. */
-+      priv->config.slave_address = addr;
-+      priv->config.status = I2C_STATUS_SLAVE_MODE;
-+      priv->config.register_index = index;
-+#if !defined(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)
-+      priv->config.index_format =
-+          ((client->index_width ==
-+            REG8) ? I2C_BYTE_INDEX : (client->
-+                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+                                      : I2C_HALF_WORD_BIG_ENDIAN));
-+
-+#else
-+
-+      priv->config.index_format =
-+          ((client->index_width == 0)?I2C_NO_INDEX:
-+           (client->index_width ==
-+            REG8) ? I2C_BYTE_INDEX : (client->
-+                                      endianness ? I2C_HALF_WORD_LITTLE_ENDIAN
-+                                      : I2C_HALF_WORD_BIG_ENDIAN));
-+
-+#endif
-+      priv->config.databuffer = data;
-+      priv->config.count_data = count;
-+      priv->config.active_event.type = I2C_NO_EVENT;
-+      priv->config.multi_operation = NOMADIK_TRUE;
-+      /* Do the read operation */
-+      priv->config.operation = I2C_READ;
-+
-+      if (i2c_initialize(priv)) {
-+              up(&nomadik_i2c[bus_id].lock);
-+              return -EINVAL;
-+      }
-+
-+      if (verify_parameters(priv)) {
-+              error("Error in parameters\n");
-+              up(&nomadik_i2c[bus_id].lock);
-+              return -EINVAL;
-+      }
-+
-+      retval = read_i2c(priv);
-+
-+      if (retval) {
-+              error("Error in read register: %d\n", retval);
-+      } else if (retval == 0) {
-+
-+              if (priv->config.data_transfer_mode !=
-+                  I2C_TRANSFER_MODE_POLLING) {
-+                      retval = nomadik_i2c_wait_msg(priv, count);
-+                      if (retval) {
-+                              error
-+                                  ("Message timeout with no handled event\n");
-+                              error("error waiting for i2c read: %d\n",
-+                                    retval);
-+                              up(&nomadik_i2c[bus_id].lock);
-+                              return retval;
-+                      }
-+              }
-+              else mdelay(1);
-+              priv->config.active_event.type = I2C_NO_EVENT;
-+              up(&nomadik_i2c[bus_id].lock);
-+              return 0;
-+      }
-+
-+      up(&nomadik_i2c[bus_id].lock);
-+
-+      /* Neither register mode for this client, return an error */
-+      return -EINVAL;
-+}
-+
-+static unsigned int nomadik_i2c_func(struct i2c_adapter *adap)
-+{
-+      return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK;
-+      //return I2C_FUNC_I2C;
-+}
-+
-+static int nomadik_i2c_remove(struct platform_device *pdev)
-+{
-+
-+      int retval;
-+      i2c_del_adapter(&nomadik_i2c[pdev->id]);
-+
-+      free_irq(i2c_driver[pdev->id].irq, &i2c_driver[pdev->id]);
-+
-+      disable_i2c(&i2c_driver[pdev->id]);
-+
-+      retval =
-+          nomadik_gpio_altfuncdisable(GPIO_ALT_I2C_0 + pdev->id, (char *)pdev->name);
-+      if (retval) {
-+              error("GPIO Disable Alt Function(%d) failed with  %d\n",
-+                    pdev->id, retval);
-+              return retval;
-+      }
-+
-+      return 0;
-+}
-+
-+static int nomadik_i2c_probe(struct platform_device *pdev)
-+{
-+      int irq;
-+      int retval = -EINVAL;
-+      struct resource *res = NULL;
-+
-+      /*Fetch the Resources, using platform data */
-+      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+      if (NULL == res) {
-+              dev_err(&pdev->dev, "probe - MEM resources not defined\n");
-+              return -ENODEV;
-+      }
-+
-+      irq = platform_get_irq(pdev, 0);
-+      if (irq < 0) {
-+              dev_err(&pdev->dev, "probe - IRQ resource not defined\n");
-+              return -ENODEV;
-+      }
-+
-+      i2c_driver[pdev->id].regs = (void *)IO_ADDRESS(res->start);
-+      i2c_driver[pdev->id].id = pdev->id;
-+      i2c_driver[pdev->id].irq = irq;
-+      i2c_driver[pdev->id].adap = &nomadik_i2c[pdev->id];
-+
-+      nomadik_i2c[pdev->id].data = (void *)&i2c_driver[pdev->id];
-+      nomadik_i2c[pdev->id].dev.parent = &pdev->dev;
-+
-+      retval = i2c_add_adapter(&nomadik_i2c[pdev->id]);
-+      if (retval) {
-+              error("Nomadik I2C[%d] Error: failed to add adapter\n",
-+                    pdev->id);
-+              return retval;
-+      }
-+
-+      /* Initialize semaphores */
-+      sema_init(&nomadik_i2c[pdev->id].lock, 1);
-+
-+      retval = request_irq(i2c_driver[pdev->id].irq,
-+                           nomadik_i2c_irq_handler,
-+                           0,
-+                           nomadik_i2c[pdev->id].name, &i2c_driver[pdev->id]);
-+      if (retval < 0) {
-+              error("i2c[%d] can't get requested irq %d\n",
-+                    pdev->id, i2c_driver[pdev->id].irq);
-+              return retval;
-+      }
-+
-+      if (pdev->id == 0) {
-+              retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C_0");
-+              if (retval) {
-+                      error
-+                          ("GPIO Enable Alt Function(%d) failed with  return = %d\n",
-+                           pdev->id, retval);
-+                      return (-EIO);
-+              }
-+      } else {/*
-+              retval = nomadik_gpio_altfuncenable(GPIO_ALT_I2C_1, "I2C_1");
-+              if (retval) {
-+                      error
-+                          ("GPIO Enable Alt Function(%d) failed with  return = %d\n",
-+                           pdev->id, retval);
-+                      return (-EIO);
-+              }*/
-+      }
-+      init_waitqueue_head(&i2c_driver[pdev->id].event_wq);
-+      reset_i2c(&i2c_driver[pdev->id]);
-+      return 0;
-+}
-+
-+static struct platform_driver nomadik_i2c_driver = {
-+      .probe = nomadik_i2c_probe,
-+      .remove = nomadik_i2c_remove,
-+      .driver = {
-+                 .owner = THIS_MODULE,
-+                 .name = "NOMADIK-I2C",
-+                 },
-+};
-+
-+static int __init i2c_nomadik_init(void)
-+{
-+      return platform_driver_register(&nomadik_i2c_driver);
-+}
-+
-+static void __exit i2c_nomadik_exit(void)
-+{
-+      platform_driver_unregister(&nomadik_i2c_driver);
-+      return;
-+}
-+
-+EXPORT_SYMBOL(nomadik_i2c_get_info);
-+EXPORT_SYMBOL(nomadik_i2c_is_busy);
-+EXPORT_SYMBOL(nomadik_i2c_read_register);
-+EXPORT_SYMBOL(nomadik_i2c_write_register);
-+EXPORT_SYMBOL(nomadik_i2c_get_client);
-+
-+module_init(i2c_nomadik_init);
-+module_exit(i2c_nomadik_exit);
-+
-+MODULE_DESCRIPTION("Nomadik IIC driver v" DRIVER_VERSION);
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h
---- linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-nomadik.h       2008-07-04 23:45:14.000000000 +0530
-@@ -0,0 +1,93 @@
-+/* drivers/i2c/busses/i2c-nomadik.h
-+ *
-+ * This is the non-public header file for the nomadik i2c driver.
-+ *
-+ * 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
-+ *
-+ * $Id$
-+ */
-+
-+#ifndef I2C_NOMADIC_PRIV_HEADER
-+#define I2C_NOMADIC_PRIV_HEADER
-+
-+#ifndef _NOMADIK_DEFS_H
-+#include <asm/arch/defs.h>
-+#endif
-+
-+#ifndef I2C_NOMADIC_HEADER
-+#include <asm/arch/i2c.h>
-+#endif
-+
-+#define I2C_ALGO_NOMADIK  0x15000000
-+#define I2C_HW_NOMADIK    0x01
-+#define I2C_DRIVERID_NOMADIK 0xF000
-+
-+#define I2C0_IOSIZE         0x00000FFF
-+#define I2C1_IOSIZE         0x00000FFF
-+
-+#define MSG_WAIT_USEC 500     // Wait 500 uSecs to test active event again.
-+#define MAX_WIAT_TIMEOUTS 100
-+
-+/***
-+ * Other structs
-+ ***/
-+struct nomadik_i2c_client {
-+      __u32 id;
-+      __u32 bus_id;
-+      __u8 addr;
-+      __u8 endianness;        // This indicates endianness of device's register index
-+      __u8 index_width;       // 8 or 16 bits;
-+};
-+
-+#define BIG_END    0
-+#define LITTLE_END 1
-+#define REG8       8
-+#define REG16      16
-+
-+struct nomadik_i2c_private {
-+      __u32 id;               // bus id
-+      struct i2c_adapter *adap;
-+      int irq;
-+      struct semaphore sema;  // Use for blocking on aa message completion
-+      int fast_mode;
-+      void __iomem *regs;
-+      wait_queue_head_t event_wq;
-+      struct i2c_controller_config config;
-+};
-+
-+static inline int nomadik_i2c_check_client_id(__u32 id)
-+{
-+      if ((id < 0) || (id >= I2C_NUM_CLIENTS)) {
-+              return -EINVAL;
-+      }
-+      return 0;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+      Configuration functions
-+-----------------------------------------------------------------------------*/
-+int setup_i2c_controller(struct nomadik_i2c_private *priv);
-+
-+int write_i2c(struct nomadik_i2c_private *priv);
-+
-+int read_i2c(struct nomadik_i2c_private *priv);
-+
-+int process_interrupt(struct nomadik_i2c_private *priv);
-+int verify_parameters(struct nomadik_i2c_private *priv);
-+void reset_i2c(struct nomadik_i2c_private *priv);
-+void disable_i2c(struct nomadik_i2c_private *priv);
-+void stn_cut_mdelay(int dlytime);
-+
-+#endif
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c
---- linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c       2008-07-04 23:45:14.000000000 +0530
-@@ -0,0 +1,1723 @@
-+
-+/* drivers/i2c/busses/i2c-nmdk8810.c
-+ *
-+ * Support for i2c bus on STn8810 (Nomadik) chips.
-+ *
-+ * 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
-+ *
-+ * Author: Melwyn LOBO <melwyn.lobo@st.com>
-+ *-----------------------------------------------------------------------------
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+
-+#include "i2c-nomadik.h"
-+#include <linux/delay.h>
-+
-+#define I2C_ENDAD_COUNTER       50000
-+#define I2C_INT_ENDED_COUNTER   50000
-+#define I2C_BTF_COUNTER         50000
-+#define I2C_BTF_COUNTER_POLLING 50000
-+#define I2C_FIFO_FLUSH_COUNTER       500
-+#define I2C_LOWER_SLAVE       127
-+#define I2C_UPPER_SLAVE       1024
-+
-+/*#######################################################################
-+      Macros to access I2C Registers with their offsets
-+#########################################################################
-+*/
-+
-+#define I2C_REG_OFFSET_CR               0x00
-+#define I2C_REG_OFFSET_SR1              0x04
-+#define I2C_REG_OFFSET_SR2              0x08
-+#define I2C_REG_OFFSET_CCR              0x0C
-+#define I2C_REG_OFFSET_OAR1             0x10
-+#define I2C_REG_OFFSET_OAR2             0x14
-+#define I2C_REG_OFFSET_DR               0x18
-+#define I2C_REG_OFFSET_ECCR           0x1C
-+
-+/*#######################################################################
-+      Macros to access I2C Interrupt Registers event
-+#########################################################################
-+*/
-+
-+#define    I2C0_IRQ_SRC_ALL  0
-+#define    I2C1_IRQ_SRC_ALL  1
-+
-+#define               I2C_IT_BTF              STD_MASK_BIT0
-+#define               I2C_IT_ADSL             STD_MASK_BIT1
-+#define               I2C_IT_SB               STD_MASK_BIT2
-+#define               I2C_IT_AF               STD_MASK_BIT3
-+#define               I2C_IT_STOPF            STD_MASK_BIT4
-+#define               I2C_IT_ARLO             STD_MASK_BIT5
-+#define               I2C_IT_BERR             STD_MASK_BIT6
-+#define               I2C_IT_ADD10            STD_MASK_BIT7
-+#define               I2C_IT_SCLFAL           STD_MASK_BIT8
-+#define               I2C_IT_ENDAD            STD_MASK_BIT9
-+
-+/*#######################################################################
-+      I2C Control Register
-+#########################################################################
-+*/
-+
-+#define I2C_ITE                 STD_MASK_BIT0
-+#define I2C_STOP                STD_MASK_BIT1
-+#define I2C_ACK                 STD_MASK_BIT2
-+#define I2C_START               STD_MASK_BIT3
-+#define I2C_ENGC                STD_MASK_BIT4
-+#define I2C_PE                  STD_MASK_BIT5
-+#define I2C_TRANS               STD_MASK_BIT6
-+#define I2C_DDC1EN              STD_MASK_BIT7
-+#define I2C_SHIFT_ITE     0
-+#define I2C_SHIFT_STOP    1
-+#define I2C_SHIFT_ACK     2
-+#define I2C_SHIFT_START   3
-+#define I2C_SHIFT_ENGC    4
-+#define I2C_SHIFT_PE      5
-+#define I2C_SHIFT_TRANS   6
-+#define I2C_SHIFT_DDC1EN  7
-+
-+/*#######################################################################
-+      I2C Status Register1
-+#########################################################################
-+*/
-+
-+#define I2C_SB                  STD_MASK_BIT0
-+#define I2C_MASTER              STD_MASK_BIT1
-+#define I2C_ADSL                STD_MASK_BIT2
-+#define I2C_BTF                 STD_MASK_BIT3
-+#define I2C_BUSY                STD_MASK_BIT4
-+#define I2C_TRA                 STD_MASK_BIT5
-+#define I2C_ADD10               STD_MASK_BIT6
-+#define I2C_EVF                 STD_MASK_BIT7
-+#define I2C_SHIFT_SB            0
-+#define I2C_SHIFT_MASTER        1
-+#define I2C_SHIFT_ADSL          2
-+#define I2C_SHIFT_BTF       3
-+#define I2C_SHIFT_BUSY          4
-+#define I2C_SHIFT_TRA       5
-+#define I2C_SHIFT_ADD10     6
-+#define I2C_SHIFT_EVF           7
-+
-+/*#######################################################################
-+      I2C Status Register2
-+#########################################################################
-+*/
-+
-+#define I2C_GCAL                STD_MASK_BIT0
-+#define I2C_BERR                STD_MASK_BIT1
-+#define I2C_ARLO                STD_MASK_BIT2
-+#define I2C_STOPF               STD_MASK_BIT3
-+#define I2C_AF                  STD_MASK_BIT4
-+#define I2C_ENDAD               STD_MASK_BIT5
-+#define I2C_SCLFAL              STD_MASK_BIT7
-+#define I2C_SHIFT_GCAL    0
-+#define I2C_SHIFT_BERR    1
-+#define I2C_SHIFT_ARLO    2
-+#define I2C_SHIFT_STOPF   3
-+#define I2C_SHIFT_AF      4
-+#define I2C_SHIFT_ENDAD   5
-+#define I2C_SHIFT_SCLFAL  7
-+
-+/*#######################################################################
-+      I2C Clock Control Register
-+#########################################################################
-+*/
-+
-+#define I2C_CLOCK_MASK  0x7F
-+#define I2C_FM_SM_MASK  0x80
-+
-+/*#######################################################################
-+    Default I2C Register Values       
-+#########################################################################
-+*/
-+
-+#define DEFAULT_CR_REG (GEN_MASK(0UL,I2C_ENGC,I2C_SHIFT_ENGC) | \
-+                      GEN_MASK(0UL,I2C_DDC1EN,I2C_SHIFT_DDC1EN)  \
-+                      )
++#define DEFAULT_CR_REG (GEN_MASK(0UL,I2C_ENGC,I2C_SHIFT_ENGC) | \
++                      GEN_MASK(0UL,I2C_DDC1EN,I2C_SHIFT_DDC1EN)  \
++                      )
 +
 +#define DEFAULT_OAR1_REG(address) ( GEN_MASK(((address)<<1),0xFF,0)  \
 +                              )
@@ -29454,7 +30373,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +      I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_STOP);
 +
 +      dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR);
-+      dummy = dummy;  
++      dummy = dummy;
 +
 +      if (I2C_TEST_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE)) {
 +              I2C_CLR_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE);
@@ -29517,7 +30436,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +      dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR1);
 +      dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_SR2);
 +      dummy = I2C_READ_REG(priv->regs + I2C_REG_OFFSET_DR);
-+      dummy = dummy;  
++      dummy = dummy;
 +
 +      I2C_SET_BIT(priv->regs + I2C_REG_OFFSET_CR, I2C_PE);
 +      priv->config.enabled = NOMADIK_TRUE;
@@ -29815,7 +30734,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +          (priv->regs + I2C_REG_OFFSET_SR2, I2C_ENDAD, I2C_SHIFT_ENDAD,
 +           I2C_ENDAD_COUNTER)) {
 +              i2c_abort(priv);
-+              return -EIO;    
++              return -EIO;
 +      }
 +
 +      if (priv->config.index_format > I2C_NO_INDEX) {
@@ -29909,7 +30828,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +                              i2c_abort(priv);
 +                              return -EIO;
 +                      }
-+              }       
++              }
 +      }
 +      if ((I2C_READ == priv->config.operation)
 +          && (priv->config.slave_address < 1024
@@ -29951,7 +30870,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +
 +      switch (priv->config.index_transfer_mode) {
 +      case I2C_TRANSFER_MODE_POLLING:
-+              /*          
++              /*
 +                 Index Transfer
 +               */
 +              if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
@@ -30009,7 +30928,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +
 +      switch (priv->config.index_transfer_mode) {
 +      case I2C_TRANSFER_MODE_POLLING:
-+              /*          
++              /*
 +                 Index Transfer
 +               */
 +              if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
@@ -30097,7 +31016,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +      priv->config.active_event.type = I2C_NO_EVENT;
 +
 +      dummy = readl(priv->regs + I2C_REG_OFFSET_CR);
-+      dummy = dummy;  
++      dummy = dummy;
 +
 +      sr1 = readl(priv->regs + I2C_REG_OFFSET_SR1);
 +      sr2 = readl(priv->regs + I2C_REG_OFFSET_SR2);
@@ -30236,7 +31155,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +
 +                                      }
 +                              }
-+                      } 
++                      }
 +                      else if (I2C_STATUS_MASTER_RECEIVER_MODE ==
 +                               priv->config.status) {
 +                              switch (priv->config.index_format) {
@@ -30353,7 +31272,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +                                      }       /*End of Multi Operation */
 +                              }       /*End Of switch */
 +                      } /*End Of Master Receiver */
-+                      
++
 +                      else if (I2C_STATUS_SLAVE_TRANSMITTER_MODE ==
 +                               priv->config.status) {
 +                              if (priv->config.count_data > 0) {
@@ -30880,9 +31799,8 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8810.c ../new/linux-2.6.20/d
 +}
 +
 +
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c
---- linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c       2008-07-04 23:45:16.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c
 @@ -0,0 +1,1817 @@
 +
 +/* drivers/i2c/busses/i2c-nmdk8815.c
@@ -31134,7 +32052,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +#define I2C_INT_SHIFT_BERR      25
 +
 +/*#######################################################################
-+    Default I2C Register Values       
++    Default I2C Register Values
 +#########################################################################
 + */
 +
@@ -31215,7 +32133,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +#define READ_FIELD(reg_name,mask,shift)    ((reg_name & mask) >> shift )
 +
 +/*#######################################################################
-+    Defines used various operations   
++    Defines used various operations
 +#########################################################################
 +*/
 +#define I2C_ENDAD_COUNTER       50000
@@ -31524,7 +32442,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +                      priv->config.transfer_data++;
 +                      priv->config.count_data--;
 +                      priv->config.active_event.type = I2C_DATA_RX_EVENT;
-+              }       
++              }
 +
 +              loop_counter = 0;
 +              if (loop_till_set
@@ -31556,7 +32474,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +                      priv->config.transfer_data++;
 +                      priv->config.count_data--;
 +                      priv->config.active_event.type = I2C_DATA_RX_EVENT;
-+              }       
++              }
 +
 +              loop_counter = 0;
 +              if (loop_till_set
@@ -31585,7 +32503,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +      if (loop_till_clear((priv->regs + I2C_REG_OFFSET_RISR), I2C_INT_TXFF,
 +                          I2C_INT_SHIFT_TXFF, I2C_ENDAD_COUNTER)) {
 +              i2c_abort(priv);
-+              return -EBUSY;  
++              return -EBUSY;
 +      }
 +
 +      switch (priv->config.index_format) {
@@ -31687,7 +32605,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +              int error_status = 0;
 +
 +      case I2C_TRANSFER_MODE_POLLING:
-+              /*          
++              /*
 +                 Index Transfer
 +               */
 +              if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
@@ -31974,7 +32892,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +      switch (priv->config.index_transfer_mode) {
 +              int error_status = 0;
 +      case I2C_TRANSFER_MODE_POLLING:
-+              /*          
++              /*
 +                 Index Transfer
 +               */
 +              if (I2C_BUS_SLAVE_MODE == priv->config.bus_control_mode) {
@@ -32683,7 +33601,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +
 +      default:
 +              break;
-+      }       
++      }
 +
 +      priv->config.active_event.id = priv->id;
 +      priv->config.active_event.transfer_data = priv->config.transfer_data;
@@ -32701,65 +33619,45 @@ diff -Nauprw linux-2.6.20/drivers/i2c/busses/i2c-stn8815.c ../new/linux-2.6.20/d
 +}
 +
 +
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/Kconfig ../new/linux-2.6.20/drivers/i2c/busses/Kconfig
---- linux-2.6.20/drivers/i2c/busses/Kconfig    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/Kconfig     2007-11-21 11:51:41.000000000 +0530
-@@ -17,6 +17,16 @@ config I2C_ALI1535
+--- linux-2.6.20.orig/drivers/i2c/chips/Kconfig
++++ linux-2.6.20/drivers/i2c/chips/Kconfig
+@@ -123,6 +123,15 @@ config SENSORS_MAX6875
+         sequencer/supervisor if found at a compatible address.
          This driver can also be built as a module.  If so, the module
-         will be called i2c-ali1535.
+         will be called max6875.
  
-+config I2C_NOMADIK
-+      tristate "I2C nomadik support"
-+      depends on I2C
++config CPLD_I2C
++      tristate "NOMADIK NDK15 CPLD"
++      depends on I2C && NOMADIK_NDK15
++      default y
 +      help
-+        If you say yes to this option, support will be included for the i2c
-+        controller on STn8810 . 
-+        This driver can also be built as a module.  If so, the module
-+        will be called nmdkmod_i2c.
-+
++        If you say yes here you get support for the cpld chip.
 +
- config I2C_ALI1563
-       tristate "ALI 1563"
-       depends on I2C && PCI && EXPERIMENTAL
-diff -Nauprw linux-2.6.20/drivers/i2c/busses/Makefile ../new/linux-2.6.20/drivers/i2c/busses/Makefile
---- linux-2.6.20/drivers/i2c/busses/Makefile   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/busses/Makefile    2007-11-21 11:51:41.000000000 +0530
-@@ -2,6 +2,23 @@
- # Makefile for the i2c bus drivers.
- #
++        This driver can also be built as a module. If so, the module
++        will be called epio-nomadik.
+ endmenu
+--- linux-2.6.20.orig/drivers/i2c/chips/Makefile
++++ linux-2.6.20/drivers/i2c/chips/Makefile
+@@ -10,10 +10,16 @@ obj-$(CONFIG_SENSORS_M41T00)       += m41t00.o
+ obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
+ obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
+ obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
+ obj-$(CONFIG_ISP1301_OMAP)    += isp1301_omap.o
+ obj-$(CONFIG_TPS65010)                += tps65010.o
++obj-$(CONFIG_CPLD_I2C)        += epio-nomadik.o
  
-+TARGET_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET))
-+SOC_NAME = $(shell echo $(CONFIG_NOMADIK_SOC))
-+PLATFORM_NAME = $(shell echo $(CONFIG_NOMADIK_PLATFORM))
-+
-+ifeq ($(CONFIG_NOMADIK_NDK10),y)
-+EXTRA_CFLAGS            := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__I2C_8810 -D__STN_8810
-+endif
-+
-+ifeq ($(CONFIG_NOMADIK_NDK15),y)
-+EXTRA_CFLAGS            := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10
-+endif
-+
-+ifeq ($(CONFIG_NOMADIK_NHK15),y)
-+EXTRA_CFLAGS            := -D__I2C_ENHANCED -D__RELEASE -D__NOMADIK_I2C -D__STN_8815=10
-+endif
-+
-+obj-$(CONFIG_I2C_NOMADIK)     += nmdkmod_i2c.o
- obj-$(CONFIG_I2C_ALI1535)     += i2c-ali1535.o
- obj-$(CONFIG_I2C_ALI1563)     += i2c-ali1563.o
- obj-$(CONFIG_I2C_ALI15X3)     += i2c-ali15x3.o
-@@ -50,3 +67,8 @@ obj-$(CONFIG_SCx200_I2C)     += scx200_i2c.o
- ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
+ ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
  EXTRA_CFLAGS += -DDEBUG
  endif
-+
-+nmdkmod_i2c-objs      := i2c-nomadik.o
-+nmdkmod_i2c-objs      += i2c-$(SOC_NAME).o
++ifdef EPIO_DEBUG
++EXTRA_CFLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG)
++endif
 +
 +
-diff -Nauprw linux-2.6.20/drivers/i2c/chips/epio-nomadik.c ../new/linux-2.6.20/drivers/i2c/chips/epio-nomadik.c
---- linux-2.6.20/drivers/i2c/chips/epio-nomadik.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/chips/epio-nomadik.c       2008-07-04 23:45:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/i2c/chips/epio-nomadik.c
 @@ -0,0 +1,195 @@
 +
 +/*
@@ -32769,7 +33667,7 @@ diff -Nauprw linux-2.6.20/drivers/i2c/chips/epio-nomadik.c ../new/linux-2.6.20/d
 + *
 + *  Nomadik EPIO driver.
 + *
-+ *  This driver provides an API for device drivers to utilize the NOMADIK EPIO 
++ *  This driver provides an API for device drivers to utilize the NOMADIK EPIO
 + *  EPIO is accesses theu i2c
 + *
 + * This program is free software; you can redistribute it and/or modify
@@ -32832,13 +33730,13 @@ diff -Nauprw linux-2.6.20/drivers/i2c/chips/epio-nomadik.c ../new/linux-2.6.20/d
 + * Two byte Access mode -
 + * By default Single byte i2c access mode is enabled
 + * . i.e. the CPLD read/write is performed using single i2c operation
-+ * 
++ *
 + * You can enable Two bytes access mode for system debug purpose
 + * In this mode two i2c operations will be performed for each CPLD register
 + * read/write operation
 + *
 + * 2Byte Access mode can be enabled duirng make vmlinux by providing
-+ * additional command line parameter "EPIO_DEBUG=0x80000000" 
++ * additional command line parameter "EPIO_DEBUG=0x80000000"
 + */
 +
 +#define EPIO_2BYTE_I2C_ACCESS         (EPIO_DEBUG & 0x80000000UL) ? (1) :(0)
@@ -32956,71 +33854,11 @@ diff -Nauprw linux-2.6.20/drivers/i2c/chips/epio-nomadik.c ../new/linux-2.6.20/d
 +MODULE_LICENSE("GPL v2");
 +
 +
-diff -Nauprw linux-2.6.20/drivers/i2c/chips/Kconfig ../new/linux-2.6.20/drivers/i2c/chips/Kconfig
---- linux-2.6.20/drivers/i2c/chips/Kconfig     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/chips/Kconfig      2007-11-21 11:51:41.000000000 +0530
-@@ -125,4 +125,13 @@ config SENSORS_MAX6875
-         This driver can also be built as a module.  If so, the module
-         will be called max6875.
-+config CPLD_I2C
-+      tristate "NOMADIK NDK15 CPLD"
-+      depends on I2C && NOMADIK_NDK15
-+      default y
-+      help
-+        If you say yes here you get support for the cpld chip.
-+
-+        This driver can also be built as a module. If so, the module
-+        will be called epio-nomadik.
- endmenu
-diff -Nauprw linux-2.6.20/drivers/i2c/chips/Makefile ../new/linux-2.6.20/drivers/i2c/chips/Makefile
---- linux-2.6.20/drivers/i2c/chips/Makefile    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/chips/Makefile     2007-11-21 11:51:41.000000000 +0530
-@@ -12,8 +12,14 @@ obj-$(CONFIG_SENSORS_PCF8574)       += pcf8574
- obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
- obj-$(CONFIG_ISP1301_OMAP)    += isp1301_omap.o
- obj-$(CONFIG_TPS65010)                += tps65010.o
-+obj-$(CONFIG_CPLD_I2C)        += epio-nomadik.o
- ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
- EXTRA_CFLAGS += -DDEBUG
- endif
-+ifdef EPIO_DEBUG
-+EXTRA_CFLAGS += -DEPIO_DEBUG=$(EPIO_DEBUG)
-+endif
-+
-+
-diff -Nauprw linux-2.6.20/drivers/i2c/Kconfig ../new/linux-2.6.20/drivers/i2c/Kconfig
---- linux-2.6.20/drivers/i2c/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/Kconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -34,6 +34,7 @@ config I2C_CHARDEV
-         This support is also available as a module.  If so, the module 
-         will be called i2c-dev.
-+
- source drivers/i2c/algos/Kconfig
- source drivers/i2c/busses/Kconfig
- source drivers/i2c/chips/Kconfig
-diff -Nauprw linux-2.6.20/drivers/i2c/Makefile ../new/linux-2.6.20/drivers/i2c/Makefile
---- linux-2.6.20/drivers/i2c/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/i2c/Makefile   2007-11-21 11:51:41.000000000 +0530
-@@ -1,9 +1,10 @@
- #
--# Makefile for the i2c core.
-+# Makefile for the kernel i2c bus driver.
- #
- obj-$(CONFIG_I2C)             += i2c-core.o
- obj-$(CONFIG_I2C_CHARDEV)     += i2c-dev.o
-+
- obj-y                         += busses/ chips/ algos/
+--- linux-2.6.20.orig/drivers/input/input.c
++++ linux-2.6.20/drivers/input/input.c
+@@ -926,10 +926,23 @@ struct input_dev *input_allocate_device(
  
- ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
-diff -Nauprw linux-2.6.20/drivers/input/input.c ../new/linux-2.6.20/drivers/input/input.c
---- linux-2.6.20/drivers/input/input.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/input.c  2007-11-21 11:51:41.000000000 +0530
-@@ -928,6 +928,19 @@ struct input_dev *input_allocate_device(
+       return dev;
  }
  EXPORT_SYMBOL(input_allocate_device);
  
@@ -33040,15 +33878,18 @@ diff -Nauprw linux-2.6.20/drivers/input/input.c ../new/linux-2.6.20/drivers/inpu
  /**
   * input_free_device - free memory occupied by input_dev structure
   * @dev: input device to free
-diff -Nauprw linux-2.6.20/drivers/input/keyboard/Kconfig ../new/linux-2.6.20/drivers/input/keyboard/Kconfig
---- linux-2.6.20/drivers/input/keyboard/Kconfig        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/keyboard/Kconfig 2007-11-21 11:51:41.000000000 +0530
-@@ -214,4 +214,17 @@ config KEYBOARD_AAED2000
+  *
+  * This function should only be used if input_register_device()
+--- linux-2.6.20.orig/drivers/input/keyboard/Kconfig
++++ linux-2.6.20/drivers/input/keyboard/Kconfig
+@@ -212,6 +212,19 @@ config KEYBOARD_AAED2000
+         development board.
          To compile this driver as a module, choose M here: the
          module will be called aaed2000_kbd.
  
 +config KEYPAD_NOMADIK
-+      tristate "Nomadik keypad support" 
++      tristate "Nomadik keypad support"
 +      depends on ARCH_NOMADIK
 +      default n
 +      help
@@ -33061,9 +33902,35 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/Kconfig ../new/linux-2.6.20/dri
 +        module will be called nomadik_kpd.
 +
  endif
-diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c
---- linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c   2008-07-04 23:45:18.000000000 +0530
+--- linux-2.6.20.orig/drivers/input/keyboard/Makefile
++++ linux-2.6.20/drivers/input/keyboard/Makefile
+@@ -2,10 +2,14 @@
+ # Makefile for the input core drivers.
+ #
+ # Each configuration option enables a list of files.
++ifdef KEYPAD_DEBUG
++CFLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG)
++endif
++
+ obj-$(CONFIG_KEYBOARD_ATKBD)          += atkbd.o
+ obj-$(CONFIG_KEYBOARD_SUNKBD)         += sunkbd.o
+ obj-$(CONFIG_KEYBOARD_LKKBD)          += lkkbd.o
+ obj-$(CONFIG_KEYBOARD_XTKBD)          += xtkbd.o
+ obj-$(CONFIG_KEYBOARD_AMIGA)          += amikbd.o
+@@ -16,6 +20,9 @@ obj-$(CONFIG_KEYBOARD_CORGI)         += corgikb
+ obj-$(CONFIG_KEYBOARD_SPITZ)          += spitzkbd.o
+ obj-$(CONFIG_KEYBOARD_HIL)            += hil_kbd.o
+ obj-$(CONFIG_KEYBOARD_HIL_OLD)                += hilkbd.o
+ obj-$(CONFIG_KEYBOARD_OMAP)             += omap-keypad.o
+ obj-$(CONFIG_KEYBOARD_AAED2000)         += aaed2000_kbd.o
++obj-$(CONFIG_KEYPAD_NOMADIK)          += nmdkmod_kpd.o
++
++nmdkmod_kpd-objs      :=      kpd-nomadik.o
+--- /dev/null
++++ linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c
 @@ -0,0 +1,359 @@
 +/*
 + * linux/drivers/input/keyboard/kpd-nomadik.c
@@ -33115,7 +33982,7 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.
 +irqreturn_t nomadik_kp_intrhandler(int irq, void *dev_id);
 +static void nomadik_kp_wq_kscan(struct work_struct *work);
 +
-+/* 
++/*
 + * Module parameter defination to pass mode of operation
 + * 0 = to initialize driver in Interrupt mode (default mode)
 + * 1 = to Intialize driver in polling mode of operation
@@ -33220,7 +34087,7 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.
 +{
 +#if 0
 +      struct keypad_t *kp = platform_get_drvdata(pdev);
-+      if ( kpmode ) 
++      if ( kpmode )
 +              kp->board->irqen(kp);
 +      if ( !device_may_wakeup(&pdev->dev) )
 +              kp->board->irqdis(kp);
@@ -33232,7 +34099,7 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.
 +{
 +#if 0
 +      struct keypad_t *kp = platform_get_drvdata(pdev);
-+      if ( kpmode ) 
++      if ( kpmode )
 +              kp->board->irqdis(kp);
 +      if ( !device_may_wakeup(&pdev->dev) )
 +              kp->board->irqen(kp);
@@ -33338,7 +34205,7 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.
 +      schedule_delayed_work(&kp->kscan_work, KEYPAD_SCAN_PERIOD);
 +        nmdk_info("Keypad polling started");
 +        }
-+      
++
 +
 +#endif
 +      nmdk_info("Module initialized Ver(%d.%d.%d)",
@@ -33347,7 +34214,7 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.
 +
 +      err_req_irq:
 +      err_inp_reg:
-+#if !defined (CONFIG_NOMADIK_NHK15)      
++#if !defined (CONFIG_NOMADIK_NHK15)
 +      if (!kp->mode)
 +              free_irq(kp->irq, kp);
 +#endif
@@ -33424,39 +34291,18 @@ diff -Nauprw linux-2.6.20/drivers/input/keyboard/kpd-nomadik.c ../new/linux-2.6.
 +MODULE_AUTHOR("Prafulla Wadaskar (prafulla.wadaskar@st.com)");
 +MODULE_DESCRIPTION("Nomadik keyboard driver");
 +MODULE_LICENSE("GPL v2");
-diff -Nauprw linux-2.6.20/drivers/input/keyboard/Makefile ../new/linux-2.6.20/drivers/input/keyboard/Makefile
---- linux-2.6.20/drivers/input/keyboard/Makefile       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/keyboard/Makefile        2007-11-21 11:51:41.000000000 +0530
-@@ -4,6 +4,10 @@
+--- linux-2.6.20.orig/drivers/input/touchscreen/Kconfig
++++ linux-2.6.20/drivers/input/touchscreen/Kconfig
+@@ -157,6 +157,26 @@ config TOUCHSCREEN_UCB1400
+         modular) for this driver to work.
  
- # Each configuration option enables a list of files.
-+ifdef KEYPAD_DEBUG
-+CFLAGS += -DKEYPAD_DEBUG=$(KEYPAD_DEBUG)
-+endif
-+
- obj-$(CONFIG_KEYBOARD_ATKBD)          += atkbd.o
- obj-$(CONFIG_KEYBOARD_SUNKBD)         += sunkbd.o
- obj-$(CONFIG_KEYBOARD_LKKBD)          += lkkbd.o
-@@ -18,4 +22,7 @@ obj-$(CONFIG_KEYBOARD_HIL)           += hil_kbd.o
- obj-$(CONFIG_KEYBOARD_HIL_OLD)                += hilkbd.o
- obj-$(CONFIG_KEYBOARD_OMAP)             += omap-keypad.o
- obj-$(CONFIG_KEYBOARD_AAED2000)         += aaed2000_kbd.o
-+obj-$(CONFIG_KEYPAD_NOMADIK)          += nmdkmod_kpd.o
-+
-+nmdkmod_kpd-objs      :=      kpd-nomadik.o
-diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Kconfig ../new/linux-2.6.20/drivers/input/touchscreen/Kconfig
---- linux-2.6.20/drivers/input/touchscreen/Kconfig     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/touchscreen/Kconfig      2007-11-21 11:51:41.000000000 +0530
-@@ -159,4 +159,24 @@ config TOUCHSCREEN_UCB1400
          To compile this driver as a module, choose M here: the
          module will be called ucb1400_ts.
  
 +config TOUCHSCREEN_NOMADIK
 +        tristate "ADS 7846 based touchscreens for... Nomadik-board"
 +        depends on NOMADIK_SPI
-+      default m 
++      default m
 +        help
 +          Say Y here if you have a touchscreen interface using the
 +          ADS7846 controller for Nomadik platform.
@@ -33474,10 +34320,10 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Kconfig ../new/linux-2.6.20/
 +          TS2003 controller for Nomadik platform.
 +
  endif
-diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Makefile ../new/linux-2.6.20/drivers/input/touchscreen/Makefile
---- linux-2.6.20/drivers/input/touchscreen/Makefile    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/touchscreen/Makefile     2007-11-21 11:51:41.000000000 +0530
-@@ -2,6 +2,10 @@
+--- linux-2.6.20.orig/drivers/input/touchscreen/Makefile
++++ linux-2.6.20/drivers/input/touchscreen/Makefile
+@@ -1,9 +1,13 @@
+ #
  # Makefile for the mouse drivers.
  #
  
@@ -33488,7 +34334,11 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Makefile ../new/linux-2.6.20
  # Each configuration option enables a list of files.
  
  obj-$(CONFIG_TOUCHSCREEN_ADS7846)     += ads7846.o
-@@ -16,3 +20,7 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)   += pe
+ obj-$(CONFIG_TOUCHSCREEN_BITSY)       += h3600_ts_input.o
+ obj-$(CONFIG_TOUCHSCREEN_CORGI)       += corgi_ts.o
+@@ -14,5 +18,9 @@ obj-$(CONFIG_TOUCHSCREEN_MK712)      += mk712
+ obj-$(CONFIG_TOUCHSCREEN_HP600)       += hp680_ts_input.o
+ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)    += penmount.o
  obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)  += touchright.o
  obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)    += touchwin.o
  obj-$(CONFIG_TOUCHSCREEN_UCB1400)     += ucb1400_ts.o
@@ -33496,579 +34346,8 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/Makefile ../new/linux-2.6.20
 +obj-$(CONFIG_TOUCHSCREEN_NOMADIK_TS2003)      += touchp2003-nomadik.o
 +
 +nmdkmod_tp-objs       :=      touchp-nomadik.o
-diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c ../new/linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c
---- linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c 2008-07-04 23:45:18.000000000 +0530
-@@ -0,0 +1,566 @@
-+/*
-+ *  linux/drivers/i2c/chips/tsc2003.c
-+ *
-+ *  Copyright (C) 2005 Bill Gatliff <bgat at billgatliff.com>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as
-+ *  published by the Free Software Foundation.
-+ *
-+ *  Driver for TI's TSC2003 I2C Touch Screen Controller
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/i2c.h>
-+#include <linux/string.h>
-+#include <linux/bcd.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+#include <asm/arch/touchp2003.h>
-+#include <asm/arch/i2c.h>
-+
-+#define DEBUG_TS(x) printk x
-+
-+/*
-+ * Insmod parameters
-+ */
-+
-+#define DRIVER_NAME "tsc2003"
-+
-+enum tsc2003_pd {
-+  PD_POWERDOWN = 0, /* penirq */
-+  PD_IREFOFF_ADCON = 1, /* no penirq */
-+  PD_IREFON_ADCOFF = 2, /* penirq */
-+  PD_IREFON_ADCON = 3, /* no penirq */
-+  PD_PENIRQ_ARM = PD_IREFON_ADCOFF,
-+  PD_PENIRQ_DISARM = PD_IREFON_ADCON,
-+};
-+
-+enum tsc2003_m {
-+  M_12BIT = 0,
-+  M_8BIT = 1
-+};
-+
-+enum tsc2003_cmd {
-+  MEAS_TEMP0 = 0,
-+  MEAS_VBAT1 = 1,
-+  MEAS_IN1 = 2,
-+  MEAS_TEMP1 = 4,
-+  MEAS_VBAT2 = 5,
-+  MEAS_IN2 = 6,
-+  ACTIVATE_NX_DRIVERS = 8,
-+  ACTIVATE_NY_DRIVERS = 9,
-+  ACTIVATE_YNX_DRIVERS = 10,
-+  MEAS_XPOS = 12,
-+  MEAS_YPOS = 13,
-+  MEAS_Z1POS = 14,
-+  MEAS_Z2POS = 15
-+};
-+
-+#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1))
-+
-+#define ADC_MAX ((1 << 12) - 1)
-+
-+struct tsc2003_data {
-+  struct i2c_client client;
-+
-+  /*struct device_driver driver; FRED*/
-+  struct platform_driver         driver;
-+  struct touchp_tsc2003_device   * board;
-+
-+  struct input_dev    idev;
-+  struct timer_list   penirq_timer;
-+  struct semaphore    sem;
-+  int                 is_opened;
-+  enum tsc2003_pd     pd;
-+  enum tsc2003_m      m;
-+  int                 penirq;
-+ struct work_struct     workq;
-+  int vbat1;
-+  int vbat2;
-+  int temp0;
-+  int temp1;
-+  int in1;
-+  int in2;
-+};
-+
-+static void   ReactivatePenIRQ (struct tsc2003_data *data);
-+static void   tsc2003ts_task   (void *v);
-+
-+static inline int tsc2003_command (struct tsc2003_data *data,
-+                                   enum tsc2003_cmd cmd,
-+                                   enum tsc2003_pd pd)
-+{
-+  char c;
-+  int ret;
-+  //down(&data->sem);
-+  c = TSC2003_CMD(cmd, pd, data->m);
-+  //ret = i2c_master_send(&data->client, &c, 1);
-+  ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
-+
-+  //up(&data->sem);
-+  return ret;
-+}
-+
-+static int tsc2003_read (struct tsc2003_data *data,
-+                         enum tsc2003_cmd cmd,
-+                         enum tsc2003_pd pd,
-+                         int *val)
-+{
-+    char c;
-+    char d_read[2];
-+    int ret;
-+
-+    c = TSC2003_CMD(cmd, pd, data->m);
-+    //ret = i2c_master_send(&data->client, &c, 1);
-+    ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
-+    if (ret) goto err;
-+
-+    udelay(20);
-+    //ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1);
-+    ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
-+    if (ret) goto err;
-+
-+    if (val)
-+    {
-+        *val = d_read[0];
-+        *val <<= 4;
-+        if (data->m == M_12BIT)
-+          *val += (d_read[1] >> 4);
-+    }
-+
-+#if defined(CONFIG_I2C_DEBUG_CHIP)
-+    printk(KERN_ERR "%s: val[%x] = %d\n",
-+           __FUNCTION__, cmd, (((int)d_read[0]) << 8) + d_read[1]);
-+#endif
-+
-+    return 0;
-+  err:
-+    if (!ret) ret = -ENODEV;
-+    return ret;
-+}
-+
-+static int send_command (struct tsc2003_data *data,
-+                         unsigned char    command_byte, unsigned short *val)
-+{
-+    char d_read[2];
-+    int ret;
-+
-+    ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&command_byte,0,1);
-+    if (ret) goto err;
-+
-+    udelay(20);
-+    ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
-+    if (ret) goto err;
-+
-+    if (val)
-+    {
-+        *val = d_read[0];
-+        *val <<= 4;
-+        if (data->m == M_12BIT)
-+          *val += (d_read[1] >> 4);
-+    }
-+
-+    return 0;
-+  err:
-+    if (!ret) ret = -ENODEV;
-+    return ret;
-+}
-+
-+static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+  return tsc2003_read(d, MEAS_TEMP0, pd, t);
-+}
-+
-+static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+  return tsc2003_read(d, MEAS_TEMP1, pd, t);
-+}
-+
-+static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *x)
-+{
-+  return tsc2003_read(d, MEAS_XPOS, pd, x);
-+}
-+
-+static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *y)
-+{
-+  return tsc2003_read(d, MEAS_YPOS, pd, y);
-+}
-+
-+static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *p)
-+{
-+  return tsc2003_read(d, MEAS_Z1POS, pd, p);
-+}
-+
-+static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+  return tsc2003_read(d, MEAS_IN1, pd, t);
-+}
-+
-+static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+  return tsc2003_read(d, MEAS_IN2, pd, t);
-+}
-+
-+static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+  return tsc2003_read(d, MEAS_VBAT1, pd, t);
-+}
-+
-+static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum
-+tsc2003_pd pd, int *t)
-+{
-+  return tsc2003_read(d, MEAS_VBAT2, pd, t);
-+}
-+
-+static inline int tsc2003_powerdown (struct tsc2003_data *d)
-+{
-+  /* we don't have a distinct powerdown command,
-+     so do a benign read with the PD bits cleared */
-+  return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0);
-+}
-+
-+
-+#define PENUP_TIMEOUT    50 /* msec */
-+
-+/*static irqreturn_t tsc2003_penirq (int irq, void *v, struct pt_regs *regs)
-+{
-+  struct tsc2003_data *d = v;
-+  DEBUG_TS(("tsc2003_penirq\n"));
-+  complete(&d->penirq_completion);
-+  return IRQ_HANDLED;
-+}*/
-+
-+/* Fred : replaced by callback */
-+static void ts2003_callback (void * parameter)
-+{
-+    struct tsc2003_data *d = (struct tsc2003_data *)parameter;
-+    //DEBUG_TS(("ts2003_callback\n"));
-+
-+    tsc2003ts_task(d);
-+}
-+
-+static int tsc2003_remove(struct platform_device *pdev)
-+{
-+  struct tsc2003_data *data;
-+
-+  data = platform_get_drvdata(pdev);
-+  //input_free_device(&data->idev);
-+  input_unregister_device(&data->idev);
-+  kfree(data);
-+
-+  return 0;
-+}
-+
-+static inline void tsc2003_restart_pen_up_timer (struct tsc2003_data *d)
-+{
-+    mod_timer(&d->penirq_timer, jiffies + (PENUP_TIMEOUT * HZ) / 1000);
-+}
-+
-+
-+static void tsc2003_timer_callback (unsigned long v)
-+{
-+      struct tsc2003_data   *d = (struct tsc2003_data *)v;
-+      schedule_work(&d->workq);
-+}
-+
-+static void tsc2003_timer_callback1(struct work_struct  *work)
-+{
-+      /*struct tsc2003_data   *d = (struct tsc2003_data *)v;*/
-+      struct tsc2003_data *d = container_of(work, struct tsc2003_data, workq);
-+      unsigned char         pin_value ;
-+      unsigned int          x, y, p;
-+    
-+      struct  task_struct *tsk = current;
-+      set_task_state(tsk, TASK_INTERRUPTIBLE);
-+      
-+      d->board->pirq_read_val(&pin_value);
-+      if( pin_value == 1)
-+      {
-+              /* The pen is up */
-+              /*printk("pen is up....\n"); */
-+              input_report_abs(&d->idev, ABS_PRESSURE, 0);
-+              input_sync(&d->idev);
-+              /*schedule_timeout(HZ/20);*/
-+              return ;
-+      }
-+      
-+      tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
-+      tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
-+      tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
-+      ReactivatePenIRQ(d);
-+    
-+      input_report_abs(&d->idev, ABS_X, x);
-+      input_report_abs(&d->idev, ABS_Y, y);
-+      input_report_abs(&d->idev, ABS_PRESSURE, p);
-+      input_sync(&d->idev);
-+    
-+      /*d->board->pirq_read_val(&pin_value); */
-+      if( pin_value == 0)
-+      {
-+              /* pen down event, (re)start the pen up timer */
-+              tsc2003_restart_pen_up_timer(d);
-+      }
-+#if 0 
-+    else
-+    {
-+      /* The pen is up */
-+      /*printk("pen is up again ....\n");*/
-+      input_report_abs(&d->idev, ABS_PRESSURE, 0);
-+        input_sync(&d->idev);
-+      /*schedule_timeout(HZ/20); */
-+    }
-+#endif
-+    return;
-+}
-+
-+static void   ReactivatePenIRQ (struct tsc2003_data *data)
-+{
-+      unsigned char   command_byte;
-+      unsigned short  dummy ;
-+
-+      /* Send I2C command to reactivate PENIRQn */
-+      /* C3=1, C2=1, C1=0, C0=0, PD1=0, PD2=0, M=0 */
-+      command_byte = 0xC0;
-+      send_command(data, command_byte, &dummy);
-+
-+      // acknowledge possible pending interrupt
-+      //data->board->pirq_ack();
-+}
-+
-+static void tsc2003ts_task (void *v)
-+{
-+    struct  tsc2003_data  *d = v;
-+    unsigned int          x, y, p;
-+    
-+    tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
-+    tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
-+    tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
-+    ReactivatePenIRQ(d);
-+            
-+    input_report_abs(&d->idev, ABS_X, x);
-+    input_report_abs(&d->idev, ABS_Y, y);
-+    input_report_abs(&d->idev, ABS_PRESSURE, p);
-+    input_sync(&d->idev);
-+    
-+    /* pen down event, (re)start the pen up timer */
-+    tsc2003_restart_pen_up_timer(d);  
-+
-+    d->board->pirq_ack();
-+    d->board->pirq_en();
-+}
-+
-+static int tsc2003_idev_open (struct input_dev *i_dev)
-+{
-+    struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
-+    int    ret = 0;
-+    
-+    DEBUG_TS(("tsc2003_idev_open\n"));
-+    if (down_interruptible(&d->sem))
-+        return -EINTR;
-+
-+    if (d->is_opened)
-+        panic(DRIVER_NAME "tsd already running (!). abort.");
-+
-+    if (d->board->irq_init)
-+    {
-+          if (d->board->irq_init(ts2003_callback,(void*)d))
-+              {
-+                  return -1;
-+              }
-+              d->board->pirq_en();
-+    }
-+    DEBUG_TS(("\tcallback setup\n"));
-+    d->penirq_timer.data = (unsigned long)d;
-+    d->penirq_timer.function = tsc2003_timer_callback;
-+    
-+    d->is_opened  = 1 ;
-+    up(&d->sem);
-+
-+    return 0;
-+}
-+
-+static void tsc2003_idev_close (struct input_dev *i_dev)
-+{
-+  struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
-+  DEBUG_TS(("tsc2003_idev_close\n"));
-+  down_interruptible(&d->sem);
-+  
-+  d->is_opened   = 0 ;
-+  //free_irq(d->penirq, d);
-+  if (d->board->irq_exit)
-+  {
-+      d->board->irq_exit();
-+  }
-+  
-+  if (timer_pending(&d->penirq_timer))
-+    del_timer(&d->penirq_timer);
-+    
-+  up(&d->sem);
-+  return;
-+}
-+
-+static int tsc2003_driver_register (struct tsc2003_data *data)
-+{
-+  int ret = 0;
-+  DEBUG_TS(("tsc2003_driver_register\n"));
-+
-+  init_MUTEX(&data->sem);
-+  init_timer(&data->penirq_timer);
-+  data->is_opened         = 0 ;
-+  data->penirq_timer.data = (unsigned long)data;
-+  data->penirq_timer.function = tsc2003_timer_callback;
-+  
-+INIT_WORK(&data->workq, tsc2003_timer_callback1);
-+
-+  //init_input_dev(&data->idev);
-+  init_ts_input_dev(&data->idev);
-+  data->idev.name = DRIVER_NAME;
-+  data->idev.evbit[0] = BIT(EV_ABS);
-+  data->idev.open = tsc2003_idev_open;
-+  data->idev.close = tsc2003_idev_close;
-+  data->idev.absbit[LONG(ABS_X)] = BIT(ABS_X);
-+  data->idev.absbit[LONG(ABS_Y)] = BIT(ABS_Y);
-+  data->idev.absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE);
-+
-+  input_set_abs_params(&data->idev, ABS_X, 0, ADC_MAX, 0, 0);
-+  input_set_abs_params(&data->idev, ABS_Y, 0, ADC_MAX, 0, 0);
-+
-+  ret = input_register_device(&data->idev);
-+
-+  return ret;
-+}
-+
-+
-+static int __init tsc2003_probe(struct platform_device *pdev)
-+{
-+      struct tsc2003_data *d;
-+      int err;
-+      struct touchp_tsc2003_device *touchp_board = pdev->dev.platform_data;
-+
-+    DEBUG_TS(("tsc2003_probe\n"));
-+
-+    d = kcalloc(1, sizeof(*d), GFP_KERNEL);
-+    if (!d)
-+    {
-+        err = -ENOMEM;
-+              goto err_kzalloc;
-+    }
-+
-+    DEBUG_TS(("\tdata allocated(%x)\n",(unsigned int)d));
-+      platform_set_drvdata(pdev, d);
-+      d = platform_get_drvdata(pdev);
-+
-+      if (!touchp_board) {
-+              printk("touchp platform data not defined");
-+              err = -1;
-+              goto err_board;
-+      }
-+      d->board = touchp_board;
-+
-+    DEBUG_TS(("Probing TSC2003\n"));
-+    err = tsc2003_powerdown(d);
-+    if (err >= 0)
-+    {
-+        DEBUG_TS(("\tpowerdown ok\n"));
-+        d->pd = PD_PENIRQ_DISARM;
-+        d->m  = M_8BIT;
-+        err = tsc2003_driver_register(d);
-+        if (err) {
-+              goto err_init_tsc2003;
-+        }
-+        printk("\tTSC2003 Module initialized\n");
-+        return 0;
-+    }
-+
-+      err_init_tsc2003:
-+      err_board:
-+      kfree(d);
-+      err_kzalloc:
-+      return err;
-+}
-+
-+#ifdef CONFIG_PM
-+int nomadik_tsc2003_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+#if 0
-+      struct tsc2003_data *d = platform_get_drvdata(pdev);
-+      
-+      if (d->board->pirq_en)          {
-+              /*printk("touchscreen suspend: enabling interrupt...\n");*/
-+              d->board->pirq_en();
-+      }
-+      
-+      if ( !device_may_wakeup(&pdev->dev) )
-+              if (d->board->pirq_dis) {
-+                      /*printk("touchscreen suspend: disabling interrupt...\n");*/
-+                      d->board->pirq_dis();
-+      }
-+#endif
-+      return 0;
-+}
-+
-+int nomadik_tsc2003_resume(struct platform_device *pdev)
-+{
-+#if 0
-+      struct tsc2003_data *d = platform_get_drvdata(pdev);
-+              
-+      if (d->board->pirq_dis) {
-+              /*printk("touchscreen resume: disabling interrupt...\n");*/
-+              d->board->pirq_dis();
-+      }
-+
-+      if ( !device_may_wakeup(&pdev->dev) )   
-+              if (d->board->pirq_en)  {       
-+              /*printk("touchscreen resume: enabling interrupt...\n");*/
-+                      d->board->pirq_en();
-+              }
-+#endif                
-+      return 0;
-+}
-+
-+#else
-+#define nomadik_tsc2003_suspend NULL
-+#define nomadik_tsc2003_resume NULL
-+#endif                                /* CONFIG_PM */
-+
-+static struct platform_driver tsc2003_driver = {
-+      .probe          = tsc2003_probe,
-+      .remove         = tsc2003_remove,
-+      .driver         = {
-+              .name   = "tsc2003",
-+      },
-+      .suspend = nomadik_tsc2003_suspend,
-+      .resume = nomadik_tsc2003_resume,
-+};
-+
-+static int __devinit tsc2003_init(void)
-+{
-+      return platform_driver_register(&tsc2003_driver);
-+}
-+
-+static void __exit tsc2003_exit(void)
-+{
-+      platform_driver_unregister(&tsc2003_driver);
-+}
-+
-+MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>");
-+MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver");
-+MODULE_LICENSE("GPL");
-+
-+module_init(tsc2003_init);
-+module_exit(tsc2003_exit);
-diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c
---- linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c     2008-07-04 23:45:19.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c
 @@ -0,0 +1,755 @@
 +/*
 + * drivers/misc/touchp-nomadik.c
@@ -34088,9 +34367,9 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 + *   thread goes to sleep and the pen_down interrupt handler is enabled.
 + *
 + *   In polling mode operation of this driver, driver never sleeps, whereas
-+ *   it is rescheduled to poll periodically as per POLL_SAMPLES_PER_SECOND 
++ *   it is rescheduled to poll periodically as per POLL_SAMPLES_PER_SECOND
 + *
-+ *   The driver is interfaced with Input Subsystem and passes the events for 
++ *   The driver is interfaced with Input Subsystem and passes the events for
 + *   pen touch/untouch, presure, x and y co-rodinates
 + */
 +
@@ -34164,7 +34443,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +static t_TP_VERSION nomadik_tp_version;
 +/*struct nomadik_gpio_int_handle gpio_penirq_handle;*/
 +
-+/** 
++/**
 + * Module parameter defination to pass mode of operation
 + * 0 = to initialize driver in Interrupt mode (default mode)
 + * 1 = to Intialize driver in polling mode of operation
@@ -34174,7 +34453,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +MODULE_PARM_DESC(tpmode, "Touch panel Operating mode (INT/POLL)=(0/1)");
 +
 +/**
-+ * nomadik_tp_spi_cs_control - callback function for ssp 
++ * nomadik_tp_spi_cs_control - callback function for ssp
 + * @comand: flag decides chip select/deselect operation
 + */
 +void nomadik_tp_spi_cs_control(u32 command)
@@ -34281,7 +34560,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +/**
 + * int nomadik_tp_read_ssp - writes & reads tp adc data using SSP
 + * @p_adsContext: device structure
-+ * 
++ *
 + * Returns 0 on sucess, negavive on failure
 + */
 +static int nomadik_tp_read_ssp(struct t_adsContext *p_adsContext, int pensts)
@@ -34317,7 +34596,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +/**
 + * int nomadik_tp_ssp_close - closes SSP
 + * @p_adsContext: device structure
-+ * 
++ *
 + * Returns 0 on sucess, negavive on failure
 + */
 +static void nomadik_tp_ssp_close(struct t_adsContext *p_adsContext)
@@ -34333,7 +34612,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +/**
 + * void nomadik_tp_read_data - reads a set of coordinate data from the SSP
 + * @p_adsContext: device structur
-+ * 
++ *
 + */
 +static void nomadik_tp_read_data(struct t_adsContext *p_adsContext)
 +{
@@ -34461,7 +34740,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +      struct task_struct *tsk = current;
 +      DECLARE_WAITQUEUE(wait, tsk);
 +//    t_bool pen_down = TRUE;
-+      
++
 +      nmdk_dbg_ftrace();
 +
 +      daemonize("touchpanel");
@@ -34498,7 +34777,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +              /* Read the pen_down data first as it jitters after the other reads */
 +              if (p_adsContext->board->pdown) {
 +                      if (!p_adsContext->board->pdown(p_adsContext)) {
-+                              /* If pen down, sleep for one sample interval, then 
++                              /* If pen down, sleep for one sample interval, then
 +                                 process touchscreen. */
 +                              nomadik_tp_read_data(p_adsContext);
 +                              if (!p_adsContext->board->pdown(p_adsContext)) {
@@ -34530,7 +34809,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +                      nmdk_dbg2("%s(): scheduling next poll ",
 +                                        __FUNCTION__);
 +                      schedule_timeout(HZ / p_adsContext->board->samples);
-+              } else 
++              } else
 +              if (p_adsContext->old_event.p == 1 && p_adsContext->new_event.p == 1) {
 +                      if (p_adsContext->debounce_flag == 0x01) {
 +                              p_adsContext->debounce_flag = 0x00;
@@ -34591,7 +34870,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +
 +/**
 + * nomadik_tp_init -  initializes the module
-+ * 
++ *
 + * This function registers and initializes the module.
 + * RETURN: Zero or negative nmdk_error code
 + */
@@ -34752,7 +35031,7 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +      }
 +      nomadik_tp_ssp_close(p_adsContext);
 +      if (p_adsContext->board->gpio_exit) {
-+              if (p_adsContext->board->gpio_exit(p_adsContext)){ 
++              if (p_adsContext->board->gpio_exit(p_adsContext)){
 +                      status = 1;
 +                      nmdk_error("Gpio free for touchpanel failed..");
 +              }
@@ -34771,11 +35050,11 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +int nomadik_tp_suspend(struct platform_device *pdev, pm_message_t state)
 +{
 +      struct t_adsContext *p_adsContext = platform_get_drvdata(pdev);
-+      if ( tpmode ) 
++      if ( tpmode )
 +              if (p_adsContext->board->pirq_en)
 +                      p_adsContext->board->pirq_en(p_adsContext);
 +      if ( !device_may_wakeup(&pdev->dev) )
-+              if (p_adsContext->board->pirq_dis) 
++              if (p_adsContext->board->pirq_dis)
 +                      p_adsContext->board->pirq_dis(p_adsContext);
 +      return 0;
 +}
@@ -34783,8 +35062,8 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +int nomadik_tp_resume(struct platform_device *pdev)
 +{
 +      struct t_adsContext *p_adsContext = platform_get_drvdata(pdev);
-+      if ( tpmode ) 
-+              if (p_adsContext->board->pirq_dis) 
++      if ( tpmode )
++              if (p_adsContext->board->pirq_dis)
 +                      p_adsContext->board->pirq_dis(p_adsContext);
 +      if ( !device_may_wakeup(&pdev->dev) )
 +              if (p_adsContext->board->pirq_en)
@@ -34825,29 +35104,580 @@ diff -Nauprw linux-2.6.20/drivers/input/touchscreen/touchp-nomadik.c ../new/linu
 +    ("Prafulla Wadaskar <prafulla.wadaskar@st.com>, ST Microelectronics");
 +MODULE_DESCRIPTION("Nomadik Touchpanel Driver");
 +MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/Makefile ../new/linux-2.6.20/drivers/Makefile
---- linux-2.6.20/drivers/Makefile      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/Makefile       2007-11-21 11:51:41.000000000 +0530
-@@ -5,6 +5,7 @@
- # Rewritten to use lists instead of if-statements.
- #
+--- /dev/null
++++ linux-2.6.20/drivers/input/touchscreen/touchp2003-nomadik.c
+@@ -0,0 +1,566 @@
++/*
++ *  linux/drivers/i2c/chips/tsc2003.c
++ *
++ *  Copyright (C) 2005 Bill Gatliff <bgat at billgatliff.com>
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  published by the Free Software Foundation.
++ *
++ *  Driver for TI's TSC2003 I2C Touch Screen Controller
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/string.h>
++#include <linux/bcd.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <asm/arch/touchp2003.h>
++#include <asm/arch/i2c.h>
++
++#define DEBUG_TS(x) printk x
++
++/*
++ * Insmod parameters
++ */
++
++#define DRIVER_NAME "tsc2003"
++
++enum tsc2003_pd {
++  PD_POWERDOWN = 0, /* penirq */
++  PD_IREFOFF_ADCON = 1, /* no penirq */
++  PD_IREFON_ADCOFF = 2, /* penirq */
++  PD_IREFON_ADCON = 3, /* no penirq */
++  PD_PENIRQ_ARM = PD_IREFON_ADCOFF,
++  PD_PENIRQ_DISARM = PD_IREFON_ADCON,
++};
++
++enum tsc2003_m {
++  M_12BIT = 0,
++  M_8BIT = 1
++};
++
++enum tsc2003_cmd {
++  MEAS_TEMP0 = 0,
++  MEAS_VBAT1 = 1,
++  MEAS_IN1 = 2,
++  MEAS_TEMP1 = 4,
++  MEAS_VBAT2 = 5,
++  MEAS_IN2 = 6,
++  ACTIVATE_NX_DRIVERS = 8,
++  ACTIVATE_NY_DRIVERS = 9,
++  ACTIVATE_YNX_DRIVERS = 10,
++  MEAS_XPOS = 12,
++  MEAS_YPOS = 13,
++  MEAS_Z1POS = 14,
++  MEAS_Z2POS = 15
++};
++
++#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1))
++
++#define ADC_MAX ((1 << 12) - 1)
++
++struct tsc2003_data {
++  struct i2c_client client;
++
++  /*struct device_driver driver; FRED*/
++  struct platform_driver         driver;
++  struct touchp_tsc2003_device   * board;
++
++  struct input_dev    idev;
++  struct timer_list   penirq_timer;
++  struct semaphore    sem;
++  int                 is_opened;
++  enum tsc2003_pd     pd;
++  enum tsc2003_m      m;
++  int                 penirq;
++ struct work_struct     workq;
++  int vbat1;
++  int vbat2;
++  int temp0;
++  int temp1;
++  int in1;
++  int in2;
++};
++
++static void   ReactivatePenIRQ (struct tsc2003_data *data);
++static void   tsc2003ts_task   (void *v);
++
++static inline int tsc2003_command (struct tsc2003_data *data,
++                                   enum tsc2003_cmd cmd,
++                                   enum tsc2003_pd pd)
++{
++  char c;
++  int ret;
++  //down(&data->sem);
++  c = TSC2003_CMD(cmd, pd, data->m);
++  //ret = i2c_master_send(&data->client, &c, 1);
++  ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
++
++  //up(&data->sem);
++  return ret;
++}
++
++static int tsc2003_read (struct tsc2003_data *data,
++                         enum tsc2003_cmd cmd,
++                         enum tsc2003_pd pd,
++                         int *val)
++{
++    char c;
++    char d_read[2];
++    int ret;
++
++    c = TSC2003_CMD(cmd, pd, data->m);
++    //ret = i2c_master_send(&data->client, &c, 1);
++    ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&c,0,1);
++    if (ret) goto err;
++
++    udelay(20);
++    //ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1);
++    ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
++    if (ret) goto err;
++
++    if (val)
++    {
++        *val = d_read[0];
++        *val <<= 4;
++        if (data->m == M_12BIT)
++          *val += (d_read[1] >> 4);
++    }
++
++#if defined(CONFIG_I2C_DEBUG_CHIP)
++    printk(KERN_ERR "%s: val[%x] = %d\n",
++           __FUNCTION__, cmd, (((int)d_read[0]) << 8) + d_read[1]);
++#endif
++
++    return 0;
++  err:
++    if (!ret) ret = -ENODEV;
++    return ret;
++}
++
++static int send_command (struct tsc2003_data *data,
++                         unsigned char    command_byte, unsigned short *val)
++{
++    char d_read[2];
++    int ret;
++
++    ret = nomadik_i2c_write_register(I2C_TOUCH_CLIENT,&command_byte,0,1);
++    if (ret) goto err;
++
++    udelay(20);
++    ret = nomadik_i2c_read_register(I2C_TOUCH_CLIENT,d_read,0,data->m == M_12BIT ? 2 : 1);
++    if (ret) goto err;
++
++    if (val)
++    {
++        *val = d_read[0];
++        *val <<= 4;
++        if (data->m == M_12BIT)
++          *val += (d_read[1] >> 4);
++    }
++
++    return 0;
++  err:
++    if (!ret) ret = -ENODEV;
++    return ret;
++}
++
++static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++  return tsc2003_read(d, MEAS_TEMP0, pd, t);
++}
++
++static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++  return tsc2003_read(d, MEAS_TEMP1, pd, t);
++}
++
++static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *x)
++{
++  return tsc2003_read(d, MEAS_XPOS, pd, x);
++}
++
++static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *y)
++{
++  return tsc2003_read(d, MEAS_YPOS, pd, y);
++}
++
++static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *p)
++{
++  return tsc2003_read(d, MEAS_Z1POS, pd, p);
++}
++
++static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++  return tsc2003_read(d, MEAS_IN1, pd, t);
++}
++
++static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++  return tsc2003_read(d, MEAS_IN2, pd, t);
++}
++
++static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++  return tsc2003_read(d, MEAS_VBAT1, pd, t);
++}
++
++static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum
++tsc2003_pd pd, int *t)
++{
++  return tsc2003_read(d, MEAS_VBAT2, pd, t);
++}
++
++static inline int tsc2003_powerdown (struct tsc2003_data *d)
++{
++  /* we don't have a distinct powerdown command,
++     so do a benign read with the PD bits cleared */
++  return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0);
++}
++
++
++#define PENUP_TIMEOUT    50 /* msec */
++
++/*static irqreturn_t tsc2003_penirq (int irq, void *v, struct pt_regs *regs)
++{
++  struct tsc2003_data *d = v;
++  DEBUG_TS(("tsc2003_penirq\n"));
++  complete(&d->penirq_completion);
++  return IRQ_HANDLED;
++}*/
++
++/* Fred : replaced by callback */
++static void ts2003_callback (void * parameter)
++{
++    struct tsc2003_data *d = (struct tsc2003_data *)parameter;
++    //DEBUG_TS(("ts2003_callback\n"));
++
++    tsc2003ts_task(d);
++}
++
++static int tsc2003_remove(struct platform_device *pdev)
++{
++  struct tsc2003_data *data;
++
++  data = platform_get_drvdata(pdev);
++  //input_free_device(&data->idev);
++  input_unregister_device(&data->idev);
++  kfree(data);
++
++  return 0;
++}
++
++static inline void tsc2003_restart_pen_up_timer (struct tsc2003_data *d)
++{
++    mod_timer(&d->penirq_timer, jiffies + (PENUP_TIMEOUT * HZ) / 1000);
++}
++
++
++static void tsc2003_timer_callback (unsigned long v)
++{
++      struct tsc2003_data   *d = (struct tsc2003_data *)v;
++      schedule_work(&d->workq);
++}
++
++static void tsc2003_timer_callback1(struct work_struct  *work)
++{
++      /*struct tsc2003_data   *d = (struct tsc2003_data *)v;*/
++      struct tsc2003_data *d = container_of(work, struct tsc2003_data, workq);
++      unsigned char         pin_value ;
++      unsigned int          x, y, p;
++
++      struct  task_struct *tsk = current;
++      set_task_state(tsk, TASK_INTERRUPTIBLE);
++
++      d->board->pirq_read_val(&pin_value);
++      if( pin_value == 1)
++      {
++              /* The pen is up */
++              /*printk("pen is up....\n"); */
++              input_report_abs(&d->idev, ABS_PRESSURE, 0);
++              input_sync(&d->idev);
++              /*schedule_timeout(HZ/20);*/
++              return ;
++      }
++
++      tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
++      tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
++      tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
++      ReactivatePenIRQ(d);
++
++      input_report_abs(&d->idev, ABS_X, x);
++      input_report_abs(&d->idev, ABS_Y, y);
++      input_report_abs(&d->idev, ABS_PRESSURE, p);
++      input_sync(&d->idev);
++
++      /*d->board->pirq_read_val(&pin_value); */
++      if( pin_value == 0)
++      {
++              /* pen down event, (re)start the pen up timer */
++              tsc2003_restart_pen_up_timer(d);
++      }
++#if 0
++    else
++    {
++      /* The pen is up */
++      /*printk("pen is up again ....\n");*/
++      input_report_abs(&d->idev, ABS_PRESSURE, 0);
++        input_sync(&d->idev);
++      /*schedule_timeout(HZ/20); */
++    }
++#endif
++    return;
++}
++
++static void   ReactivatePenIRQ (struct tsc2003_data *data)
++{
++      unsigned char   command_byte;
++      unsigned short  dummy ;
++
++      /* Send I2C command to reactivate PENIRQn */
++      /* C3=1, C2=1, C1=0, C0=0, PD1=0, PD2=0, M=0 */
++      command_byte = 0xC0;
++      send_command(data, command_byte, &dummy);
++
++      // acknowledge possible pending interrupt
++      //data->board->pirq_ack();
++}
++
++static void tsc2003ts_task (void *v)
++{
++    struct  tsc2003_data  *d = v;
++    unsigned int          x, y, p;
++
++    tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x);
++    tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y);
++    tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p);
++    ReactivatePenIRQ(d);
++
++    input_report_abs(&d->idev, ABS_X, x);
++    input_report_abs(&d->idev, ABS_Y, y);
++    input_report_abs(&d->idev, ABS_PRESSURE, p);
++    input_sync(&d->idev);
++
++    /* pen down event, (re)start the pen up timer */
++    tsc2003_restart_pen_up_timer(d);
++
++    d->board->pirq_ack();
++    d->board->pirq_en();
++}
++
++static int tsc2003_idev_open (struct input_dev *i_dev)
++{
++    struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
++    int    ret = 0;
++
++    DEBUG_TS(("tsc2003_idev_open\n"));
++    if (down_interruptible(&d->sem))
++        return -EINTR;
++
++    if (d->is_opened)
++        panic(DRIVER_NAME "tsd already running (!). abort.");
++
++    if (d->board->irq_init)
++    {
++          if (d->board->irq_init(ts2003_callback,(void*)d))
++              {
++                  return -1;
++              }
++              d->board->pirq_en();
++    }
++    DEBUG_TS(("\tcallback setup\n"));
++    d->penirq_timer.data = (unsigned long)d;
++    d->penirq_timer.function = tsc2003_timer_callback;
++
++    d->is_opened  = 1 ;
++    up(&d->sem);
++
++    return 0;
++}
++
++static void tsc2003_idev_close (struct input_dev *i_dev)
++{
++  struct tsc2003_data *d = container_of(i_dev, struct tsc2003_data, idev);
++  DEBUG_TS(("tsc2003_idev_close\n"));
++  down_interruptible(&d->sem);
++
++  d->is_opened   = 0 ;
++  //free_irq(d->penirq, d);
++  if (d->board->irq_exit)
++  {
++      d->board->irq_exit();
++  }
++
++  if (timer_pending(&d->penirq_timer))
++    del_timer(&d->penirq_timer);
++
++  up(&d->sem);
++  return;
++}
++
++static int tsc2003_driver_register (struct tsc2003_data *data)
++{
++  int ret = 0;
++  DEBUG_TS(("tsc2003_driver_register\n"));
++
++  init_MUTEX(&data->sem);
++  init_timer(&data->penirq_timer);
++  data->is_opened         = 0 ;
++  data->penirq_timer.data = (unsigned long)data;
++  data->penirq_timer.function = tsc2003_timer_callback;
++
++INIT_WORK(&data->workq, tsc2003_timer_callback1);
++
++  //init_input_dev(&data->idev);
++  init_ts_input_dev(&data->idev);
++  data->idev.name = DRIVER_NAME;
++  data->idev.evbit[0] = BIT(EV_ABS);
++  data->idev.open = tsc2003_idev_open;
++  data->idev.close = tsc2003_idev_close;
++  data->idev.absbit[LONG(ABS_X)] = BIT(ABS_X);
++  data->idev.absbit[LONG(ABS_Y)] = BIT(ABS_Y);
++  data->idev.absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE);
++
++  input_set_abs_params(&data->idev, ABS_X, 0, ADC_MAX, 0, 0);
++  input_set_abs_params(&data->idev, ABS_Y, 0, ADC_MAX, 0, 0);
++
++  ret = input_register_device(&data->idev);
++
++  return ret;
++}
++
++
++static int __init tsc2003_probe(struct platform_device *pdev)
++{
++      struct tsc2003_data *d;
++      int err;
++      struct touchp_tsc2003_device *touchp_board = pdev->dev.platform_data;
++
++    DEBUG_TS(("tsc2003_probe\n"));
++
++    d = kcalloc(1, sizeof(*d), GFP_KERNEL);
++    if (!d)
++    {
++        err = -ENOMEM;
++              goto err_kzalloc;
++    }
++
++    DEBUG_TS(("\tdata allocated(%x)\n",(unsigned int)d));
++      platform_set_drvdata(pdev, d);
++      d = platform_get_drvdata(pdev);
++
++      if (!touchp_board) {
++              printk("touchp platform data not defined");
++              err = -1;
++              goto err_board;
++      }
++      d->board = touchp_board;
++
++    DEBUG_TS(("Probing TSC2003\n"));
++    err = tsc2003_powerdown(d);
++    if (err >= 0)
++    {
++        DEBUG_TS(("\tpowerdown ok\n"));
++        d->pd = PD_PENIRQ_DISARM;
++        d->m  = M_8BIT;
++        err = tsc2003_driver_register(d);
++        if (err) {
++              goto err_init_tsc2003;
++        }
++        printk("\tTSC2003 Module initialized\n");
++        return 0;
++    }
++
++      err_init_tsc2003:
++      err_board:
++      kfree(d);
++      err_kzalloc:
++      return err;
++}
++
++#ifdef CONFIG_PM
++int nomadik_tsc2003_suspend(struct platform_device *pdev, pm_message_t state)
++{
++#if 0
++      struct tsc2003_data *d = platform_get_drvdata(pdev);
++
++      if (d->board->pirq_en)          {
++              /*printk("touchscreen suspend: enabling interrupt...\n");*/
++              d->board->pirq_en();
++      }
++
++      if ( !device_may_wakeup(&pdev->dev) )
++              if (d->board->pirq_dis) {
++                      /*printk("touchscreen suspend: disabling interrupt...\n");*/
++                      d->board->pirq_dis();
++      }
++#endif
++      return 0;
++}
++
++int nomadik_tsc2003_resume(struct platform_device *pdev)
++{
++#if 0
++      struct tsc2003_data *d = platform_get_drvdata(pdev);
++
++      if (d->board->pirq_dis) {
++              /*printk("touchscreen resume: disabling interrupt...\n");*/
++              d->board->pirq_dis();
++      }
++
++      if ( !device_may_wakeup(&pdev->dev) )
++              if (d->board->pirq_en)  {
++              /*printk("touchscreen resume: enabling interrupt...\n");*/
++                      d->board->pirq_en();
++              }
++#endif
++      return 0;
++}
++
++#else
++#define nomadik_tsc2003_suspend NULL
++#define nomadik_tsc2003_resume NULL
++#endif                                /* CONFIG_PM */
++
++static struct platform_driver tsc2003_driver = {
++      .probe          = tsc2003_probe,
++      .remove         = tsc2003_remove,
++      .driver         = {
++              .name   = "tsc2003",
++      },
++      .suspend = nomadik_tsc2003_suspend,
++      .resume = nomadik_tsc2003_resume,
++};
++
++static int __devinit tsc2003_init(void)
++{
++      return platform_driver_register(&tsc2003_driver);
++}
++
++static void __exit tsc2003_exit(void)
++{
++      platform_driver_unregister(&tsc2003_driver);
++}
++
++MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>");
++MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver");
++MODULE_LICENSE("GPL");
++
++module_init(tsc2003_init);
++module_exit(tsc2003_exit);
+--- linux-2.6.20.orig/drivers/media/Kconfig
++++ linux-2.6.20/drivers/media/Kconfig
+@@ -63,10 +63,12 @@ source "drivers/media/radio/Kconfig"
  
-+obj-$(CONFIG_I2C)             += i2c/
- obj-$(CONFIG_PCI)             += pci/
- obj-$(CONFIG_PARISC)          += parisc/
- obj-$(CONFIG_RAPIDIO)         += rapidio/
-@@ -57,7 +58,6 @@ obj-$(CONFIG_GAMEPORT)               += input/gamepor
- obj-$(CONFIG_INPUT)           += input/
- obj-$(CONFIG_I2O)             += message/
- obj-$(CONFIG_RTC_LIB)         += rtc/
--obj-$(CONFIG_I2C)             += i2c/
- obj-$(CONFIG_W1)              += w1/
- obj-$(CONFIG_HWMON)           += hwmon/
- obj-$(CONFIG_PHONE)           += telephony/
-diff -Nauprw linux-2.6.20/drivers/media/Kconfig ../new/linux-2.6.20/drivers/media/Kconfig
---- linux-2.6.20/drivers/media/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/Kconfig  2008-08-12 22:56:04.000000000 +0530
-@@ -65,6 +65,8 @@ source "drivers/media/dvb/Kconfig"
+ source "drivers/media/dvb/Kconfig"
  
  source "drivers/media/common/Kconfig"
  
@@ -34856,10 +35686,13 @@ diff -Nauprw linux-2.6.20/drivers/media/Kconfig ../new/linux-2.6.20/drivers/medi
  config VIDEO_TUNER
        tristate
        depends on I2C
-diff -Nauprw linux-2.6.20/drivers/media/Makefile ../new/linux-2.6.20/drivers/media/Makefile
---- linux-2.6.20/drivers/media/Makefile        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/Makefile 2008-10-06 12:06:20.000000000 +0530
-@@ -6,3 +6,7 @@ obj-y := common/
+ config VIDEO_BUF
+--- linux-2.6.20.orig/drivers/media/Makefile
++++ linux-2.6.20/drivers/media/Makefile
+@@ -4,5 +4,9 @@
+ obj-y := common/
  obj-$(CONFIG_VIDEO_DEV) += video/
  obj-$(CONFIG_VIDEO_DEV) += radio/
  obj-$(CONFIG_DVB)       += dvb/
@@ -34867,9 +35700,45 @@ diff -Nauprw linux-2.6.20/drivers/media/Makefile ../new/linux-2.6.20/drivers/med
 +obj-$(CONFIG_NOMADIK_SVA)     += nomadik_mm/sva/
 +obj-$(CONFIG_NOMADIK_SAA)     += nomadik_mm/saa/
 +obj-$(CONFIG_NOMADIK_OGL)     += nomadik_mm/opengl/
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c 2008-07-17 16:43:06.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/Kconfig
+@@ -0,0 +1,23 @@
++#
++# Nomadik Multimedia Audio/Video device configuration
++#
++
++menu "NOMADIK Audio Video Graphic Drivers(SAA SVA and OPENGL) "
++
++config NOMADIK_SAA
++      tristate "Nomadik SAA Support"
++      depends on ARCH_NOMADIK && NOMADIK_MSP && I2C_NOMADIK
++      ---help---
++      Support for Nomadik SAA DSP
++
++config NOMADIK_SVA
++      tristate "Nomadik SVA Support"
++      depends on ARCH_NOMADIK && VIDEO_V4L2 && I2C_NOMADIK
++      ---help---
++      Support for Nomadik SVA DSP
++
++config NOMADIK_OGL
++      tristate "Nomadik OGL Support"
++      ---help---
++      Support for Nomadik OGL DSP
++endmenu
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/Makefile
+@@ -0,0 +1,8 @@
++#
++# Makefile for the kernel multimedia device drivers.
++#kefile for the kernel multimedia device drivers.
++#
++
++obj-$(CONFIG_NOMADIK_SAA) += saa/
++obj-$(CONFIG_NOMADIK_SVA) += sva/
++obj-$(CONFIG_NOMADIK_OGL) += opengl/
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c
 @@ -0,0 +1,3632 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -38503,9 +39372,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.c ../new/
 +
 +/* End of file - hloader.c */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h 2008-07-17 16:43:07.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h
 @@ -0,0 +1,170 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -38677,9 +39545,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader.h ../new/
 +
 +/* End of file - hloader.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h       2008-07-17 16:43:08.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h
 @@ -0,0 +1,451 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -39132,9 +39999,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/hloader/hloader_p.h ../ne
 +
 +/* End of file - hloader_p.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h   2008-07-17 16:43:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h
 @@ -0,0 +1,316 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -39452,16 +40318,15 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/debug.h ../new/li
 +/* End of file - debug.h */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h        2008-07-17 16:43:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h
 @@ -0,0 +1,290 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
 +/* information, STMicroelectronics reserves the right to license this        */
 +/*  software concurrently under separate license conditions.                 */
 +/*                                                                           */
-+/* This program is free software; you can redistribute it and/or modify it   */ 
++/* This program 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.                                     */
@@ -39484,7 +40349,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +#include "platform_os.h"
 +
 +/*-----------------------------------------------------------------------------
-+ * Type definition                                                               
++ * Type definition
 + *---------------------------------------------------------------------------*/
 +typedef unsigned char t_uint8;
 +typedef signed char t_sint8;
@@ -39503,7 +40368,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +
 +typedef unsigned int t_bitfield;
 +
-+#if !defined(FALSE) &&  !defined(TRUE)   
++#if !defined(FALSE) &&  !defined(TRUE)
 +typedef enum {FALSE, TRUE} t_bool;
 +#else /* FALSE & TRUE already defined */
 +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool;
@@ -39520,10 +40385,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +
 +/*
 + * Global frequency enumuration
-+ * Added to avoid frequency conversion function which is required to convert one HCL 
++ * Added to avoid frequency conversion function which is required to convert one HCL
 + * frequency enumuration values to another HCL frequency enumuration values.
 + */
-+ 
++
 +typedef enum {
 +      HCL_FREQ_NOT_SUPPORTED=-1,
 +      HCL_FREQ_8KHZ ,
@@ -39557,7 +40422,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +      HCL_FREQ_22MHZ,
 +      HCL_FREQ_24MHZ,
 +      HCL_FREQ_48MHZ
-+} t_frequency; 
++} t_frequency;
 +
 +
 +
@@ -39582,7 +40447,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +
 +
 +/*-----------------------------------------------------------------------------
-+ * Keyword definition 
++ * Keyword definition
 + *---------------------------------------------------------------------------*/
 +#define PUBLIC        /* Extern by default */
 +#define PRIVATE      static
@@ -39634,42 +40499,42 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +#define MASK_NULL8    0x00
 +#define MASK_NULL16   0x0000
 +#define MASK_NULL32   0x00000000
-+#define MASK_ALL8     0xFF 
-+#define MASK_ALL16    0xFFFF 
++#define MASK_ALL8     0xFF
++#define MASK_ALL16    0xFFFF
 +#define MASK_ALL32    0xFFFFFFFF
 +
 +#define MASK_BIT0     (1UL<<0)
-+#define MASK_BIT1     (1UL<<1) 
-+#define MASK_BIT2     (1UL<<2) 
-+#define MASK_BIT3     (1UL<<3) 
-+#define MASK_BIT4     (1UL<<4) 
-+#define MASK_BIT5     (1UL<<5) 
-+#define MASK_BIT6     (1UL<<6) 
-+#define MASK_BIT7     (1UL<<7) 
-+#define MASK_BIT8     (1UL<<8) 
-+#define MASK_BIT9     (1UL<<9) 
-+#define MASK_BIT10    (1UL<<10) 
-+#define MASK_BIT11    (1UL<<11) 
-+#define MASK_BIT12    (1UL<<12) 
-+#define MASK_BIT13    (1UL<<13) 
-+#define MASK_BIT14    (1UL<<14) 
-+#define MASK_BIT15    (1UL<<15) 
-+#define MASK_BIT16    (1UL<<16) 
-+#define MASK_BIT17    (1UL<<17) 
-+#define MASK_BIT18    (1UL<<18) 
-+#define MASK_BIT19    (1UL<<19) 
-+#define MASK_BIT20    (1UL<<20) 
++#define MASK_BIT1     (1UL<<1)
++#define MASK_BIT2     (1UL<<2)
++#define MASK_BIT3     (1UL<<3)
++#define MASK_BIT4     (1UL<<4)
++#define MASK_BIT5     (1UL<<5)
++#define MASK_BIT6     (1UL<<6)
++#define MASK_BIT7     (1UL<<7)
++#define MASK_BIT8     (1UL<<8)
++#define MASK_BIT9     (1UL<<9)
++#define MASK_BIT10    (1UL<<10)
++#define MASK_BIT11    (1UL<<11)
++#define MASK_BIT12    (1UL<<12)
++#define MASK_BIT13    (1UL<<13)
++#define MASK_BIT14    (1UL<<14)
++#define MASK_BIT15    (1UL<<15)
++#define MASK_BIT16    (1UL<<16)
++#define MASK_BIT17    (1UL<<17)
++#define MASK_BIT18    (1UL<<18)
++#define MASK_BIT19    (1UL<<19)
++#define MASK_BIT20    (1UL<<20)
 +#define MASK_BIT21    (1UL<<21)
-+#define MASK_BIT22    (1UL<<22) 
-+#define MASK_BIT23    (1UL<<23) 
-+#define MASK_BIT24    (1UL<<24) 
-+#define MASK_BIT25    (1UL<<25) 
-+#define MASK_BIT26    (1UL<<26) 
-+#define MASK_BIT27    (1UL<<27) 
-+#define MASK_BIT28    (1UL<<28) 
-+#define MASK_BIT29    (1UL<<29) 
++#define MASK_BIT22    (1UL<<22)
++#define MASK_BIT23    (1UL<<23)
++#define MASK_BIT24    (1UL<<24)
++#define MASK_BIT25    (1UL<<25)
++#define MASK_BIT26    (1UL<<26)
++#define MASK_BIT27    (1UL<<27)
++#define MASK_BIT28    (1UL<<28)
++#define MASK_BIT29    (1UL<<29)
 +#define MASK_BIT30    (1UL<<30)
-+#define MASK_BIT31    (1UL<<31) 
++#define MASK_BIT31    (1UL<<31)
 +
 +/*-----------------------------------------------------------------------------
 + * quartet shift definition
@@ -39704,7 +40569,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +#define MASK_BYTE1      (MASK_BYTE << SHIFT_BYTE1)
 +#define MASK_BYTE2      (MASK_BYTE << SHIFT_BYTE2)
 +#define MASK_BYTE3      (MASK_BYTE << SHIFT_BYTE3)
-+ 
++
 +/*-----------------------------------------------------------------------------
 + * Halfword shift definition
 + *---------------------------------------------------------------------------*/
@@ -39719,8 +40584,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 + *---------------------------------------------------------------------------*/
 + #define ONE_KB        (1024)
 + #define ONE_MB        (ONE_KB * ONE_KB)
-+ 
-+ 
++
++
 +/*-----------------------------------------------------------------------------
 + * Address translation macros declaration
 + *---------------------------------------------------------------------------*/
@@ -39746,16 +40611,15 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hcl_defs.h ../new
 +
 +/* End of file hcl_defs.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h 2008-07-17 16:43:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h
 @@ -0,0 +1,170 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
 +/* information, STMicroelectronics reserves the right to license this        */
 +/*  software concurrently under separate license conditions.                 */
 +/*                                                                           */
-+/* This program is free software; you can redistribute it and/or modify it   */ 
++/* This program 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.                                     */
@@ -39920,16 +40784,15 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/hloader.h ../new/
 +
 +/* End of file - hloader.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h   2008-07-17 16:43:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h
 @@ -0,0 +1,1761 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
 +/* information, STMicroelectronics reserves the right to license this        */
 +/*  software concurrently under separate license conditions.                 */
 +/*                                                                           */
-+/* This program is free software; you can redistribute it and/or modify it   */ 
++/* This program 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.                                     */
@@ -40249,7 +41112,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +
 +
 +/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8800) 
++#if defined(__STN_8800)
 +
 +/* SDRAM bank 0 */
 +#define SDRAM_BANK_0_BASE_ADDR                    0x00000000
@@ -40433,7 +41296,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#endif  /*  defined(__STN_8800)   */
 +
 +/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8810) 
++#if defined(__STN_8810)
 +
 +/* SDRAM bank 0 */
 +#define SDRAM_BANK_0_BASE_ADDR                    0x00000000
@@ -40789,7 +41652,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#endif
 +
 +/* TSP configuration registers */
-+#define TSP_CFG_REG_BASE_ADDR             0xD2000000 
++#define TSP_CFG_REG_BASE_ADDR             0xD2000000
 +//#define TSP_CFG_REG_END_ADDR                    0x101AFFFF
 +
 +/* LM1 Control registers */
@@ -40848,7 +41711,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +//#define USB_REG_END_ADDR                    0x1017FFFF
 +
 +/* Static Memory Controller configuration registers */
-+#define SMC_CTRL_REG_BASE_ADDR                    0xE7100000  
++#define SMC_CTRL_REG_BASE_ADDR                    0xE7100000
 +#define SMC_CTRL_REG_END_ADDR             0xE7FFFFFF
 +
 +/* (PC-Card)/NAND Flash Controller Bank 0 */
@@ -40959,7 +41822,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#define HSI_TX_REG_END_ADDR                   0xD11FFFFF
 +
 +/* TSP configuration registers */
-+#define TSP_CFG_REG_BASE_ADDR             0xD2000000 
++#define TSP_CFG_REG_BASE_ADDR             0xD2000000
 +#define TSP_CFG_REG_END_ADDR              0xD2FFFFFF
 +
 +/* LM1 Control registers */
@@ -41017,7 +41880,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#define USB_REG_END_ADDR                      0xE70FFFFF
 +
 +/* Static Memory Controller configuration registers */
-+#define SMC_CTRL_REG_BASE_ADDR                    0xE7100000  
++#define SMC_CTRL_REG_BASE_ADDR                    0xE7100000
 +#define SMC_CTRL_REG_END_ADDR             0xE7FFFFFF
 +
 +/* (PC-Card)/NAND Flash Controller Bank 0 */
@@ -41043,7 +41906,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#endif  /*  defined(__EMUL)  */
 +
 +/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8815) 
++#if defined(__STN_8815)
 +
 +/* SDRAM bank 0 */
 +#define SDRAM_BANK_0_BASE_ADDR                    0x00000000
@@ -41327,7 +42190,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#endif  /*  defined(__STN_8815)   */
 +
 +/*--------------------------------------------------------------------------*/
-+#if defined(__STN_8820) 
++#if defined(__STN_8820)
 +
 +/* SDRAM bank 0 */
 +#define SDRAM_BANK_0_BASE_ADDR                    0x00000000
@@ -41685,16 +42548,15 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/mupoc_mapping.h .
 +#endif /*__INC_MUPOC_MAPPING_H */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h     2008-07-17 16:43:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h
 @@ -0,0 +1,72 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
 +/* information, STMicroelectronics reserves the right to license this        */
 +/*  software concurrently under separate license conditions.                 */
 +/*                                                                           */
-+/* This program is free software; you can redistribute it and/or modify it   */ 
++/* This program 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.                                     */
@@ -41761,9 +42623,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/platform_os.h ../
 +typedef signed long long t_sint64;
 +
 +#endif /* __INC_PLATFORM_OS_H */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h     2008-07-17 16:43:44.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h
 @@ -0,0 +1,2148 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -43913,9 +44774,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/include/sva.h ../new/linu
 +
 +#endif /* __INC_SVA_H */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.c      2008-07-17 16:42:52.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.c
 @@ -0,0 +1,142 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -44059,9 +44919,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.c ../n
 +      if (vic_error != VIC_OK)
 +              PRINT("FATAL: Unable to uninstall IRQ handler 1 (error %u)! ", vic_error);
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h      2008-07-17 16:42:53.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h
 @@ -0,0 +1,39 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -44102,9 +44961,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/audio_services.h ../n
 +
 +#endif /* _SERVICES_AUDIO_H */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h       2008-07-17 16:42:53.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h
 @@ -0,0 +1,1064 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -45170,9 +46028,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_api_params.h ../ne
 +} t_saa_event_map;
 +
 +#endif // _ha_api_params_h_
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h       2008-07-17 16:42:54.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h
 @@ -0,0 +1,204 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -45378,9 +46235,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_info.h ../ne
 +} t_saa_codec_info;
 +
 +#endif // _ha_codec_info_h_
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h     2008-07-17 16:42:54.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h
 @@ -0,0 +1,686 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -46068,9 +46924,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_codec_params.h ../
 +} t_saa_codec_params;
 +
 +#endif // _ha_codec_params_h_
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h      2008-07-17 16:42:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h
 @@ -0,0 +1,122 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -46194,9 +47049,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_info.h ../n
 +} t_saa_aep_component_info;
 +
 +#endif // _ha_effect_info_h_
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h    2008-07-17 16:42:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h
 @@ -0,0 +1,1342 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -47540,9 +48394,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_effect_params.h ..
 +} t_saa_component_dynamic_params;
 +
 +#endif // _ha_effect_params_h_
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h 2008-07-17 16:42:56.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h
 @@ -0,0 +1,163 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -47707,9 +48560,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/ha_hcl_fw_interface.h
 +} t_ha_command_id;
 +
 +#endif /* _ha_hcl_fw_interface_h_ */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c 2008-07-17 16:42:57.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c
 @@ -0,0 +1,271 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -47982,9 +48834,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.c ../new/linux-2.
 +}
 +#endif
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h 2008-07-17 16:42:57.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h
 @@ -0,0 +1,159 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -48145,9 +48996,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti.h ../new/linux-2.
 +
 +#endif // _HTI_H
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h        2008-07-17 16:42:58.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h
 @@ -0,0 +1,134 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -48283,570 +49133,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/hti_protocol.h ../new
 +    #define HTI_PROTOCOL_STT
 +
 +#endif //_STT_PROTOCOL_H
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c    2008-07-17 16:43:00.000000000 +0530
-@@ -0,0 +1,557 @@
-+/*---------------------------------------------------------------------------*/
-+/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
-+/* information, STMicroelectronics reserves the right to license this        */
-+/*  software concurrently under separate license conditions.                 */
-+/*                                                                           */
-+/* This program 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.                                     */
-+/*                                                                           */
-+/* 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 Lesser General Public License for more details.                   */
-+/*                                                                           */
-+/* You should have received a copy of the GNU Lesser General Public License  */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
-+/*---------------------------------------------------------------------------*/
-+
-+/*--------------------------------------------------------------------------*
-+ * Includes                                                                                                                                   *
-+ *--------------------------------------------------------------------------*/
-+#include "saa_hwp.h"
-+#include "saap.h"
-+#include "hti.h"
-+#include "hti_protocol.h"
-+
-+
-+/*--------------------------------------------------------------------------*
-+ *  Global variables                                                                                                          *
-+ *--------------------------------------------------------------------------*/
-+t_saa_system saa_system;
-+t_bool                 saa_hcl_hti_trace = FALSE;
-+
-+
-+/*--------------------------------------------------------------------------*
-+ *  Private data                                                                                                                      *
-+ *--------------------------------------------------------------------------*/
-+
-+/*--------------------------------------------------------------------------*
-+ *  Public functions                                                                                                          *
-+ *--------------------------------------------------------------------------*/
-+
-+/****************************************************************************/
-+/* NAME:              SAA_InitSharedMailboxes                                                                         */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Set the address of the shared uplink & downlink mailboxes.    */
-+/*                            Called once when the first interrupt is received.                       */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:               -                                                                                                                       */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            None                                                                                                            */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC void SAA_InitSharedMailboxes(void) {
-+
-+      volatile t_uint16* ptr;
-+      t_uint32 offset;
-+      t_uint32 host_address = (t_uint32)&saa_system.pSAA_HW->host_reg;
-+      t_uint32 ram_address =  (t_uint32)saa_system.pSAA_HW->ram;
-+
-+      // build the uplink shared mailbox address
-+      ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_1);
-+      offset = (t_uint32)(*ptr) & 0xFF;
-+      ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_2);
-+      offset <<= 8;
-+      offset |= (t_uint32)(*ptr) & 0xFF;
-+      ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_3);
-+      offset <<= 8;
-+      offset |= (t_uint32)(*ptr) & 0xFF;
-+      offset <<= 1;
-+      saa_system.mailbox_ul.pMsg = (t_saa_message*)(ram_address + offset);
-+
-+      // build the downlink shared mailbox address
-+      ptr = (t_uint16*)(host_address  + 2*HOST_HA_MBX_DOWN_ADD_1);
-+      offset = (t_uint32)(*ptr) & 0xFF;
-+      ptr = (t_uint16*)(host_address  + 2*HOST_HA_MBX_DOWN_ADD_2);
-+      offset <<= 8;
-+      offset |= (t_uint32)(*ptr) & 0xFF;
-+      ptr = (t_uint16*)(host_address  + 2*HOST_HA_MBX_DOWN_ADD_3);
-+      offset <<= 8;
-+      offset |= (t_uint32)(*ptr) & 0xFF;
-+      offset <<= 1;
-+      saa_system.mailbox_dl.pMsg = (t_saa_message*)(ram_address + offset);
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_SendCommand                                                                                         */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Send a command to the SAA/MMDSP.                                                      */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:               pCmd: pointer to the command description                                        */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            command number>0 if successful, 0 otherwise                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd) {
-+
-+      t_saa_message new_message;
-+      #ifdef SAA_USE_DOUBLE_IT
-+      t_saa_message message;
-+    int nb_msg_sent = 0;
-+      #endif
-+      int i;
-+
-+      new_message.command_number = (t_uint16)(saa_system.command_number + 1);
-+      new_message.command_id = pCmd->command_id;
-+      new_message.server_id = pCmd->server_id;
-+
-+      for (i=0; i<SAA_MSG_NB_PARAM; i++) {
-+              new_message.params[i] = pCmd->params[i];
-+      }
-+
-+      if (++saa_system.command_number == 0xFFFF)
-+              saa_system.command_number = 0;  // avoid 16-bit roll-over of next command number (answer/alert mismatch)
-+
-+      #ifndef SAA_USE_DOUBLE_IT
-+      if (SAA_PutMessage(&new_message))
-+      {
-+              // send the write finished interrupt to SAA/MMDSP
-+              saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
-+
-+              return new_message.command_number;
-+      }
-+      #else
-+    SAA_DisableIRQSrc(ESAA_SRC_IRQ_1);
-+    // check if ARM is waiting for a read finished interrupt
-+    if(saa_system.rf_it_received){
-+              // copy all messages from ARM downlink local FIFO to downlink shared mailbox
-+        while ((nb_msg_sent < SAA_MBX_DOWN_SIZE)&&(SAA_PopFromLocalFifoDL(&message))){
-+                      (void)SAA_PutMessage(&message);
-+            nb_msg_sent ++;
-+              }
-+
-+        if (SAA_PutMessage(&new_message)){
-+            // a read finished interrupt will be received
-+            saa_system.rf_it_received = FALSE;
-+
-+            // send the write finished interrupt to SAA/MMDSP
-+            saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
-+                SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
-+            return new_message.command_number;
-+        }
-+
-+              if(nb_msg_sent != 0){
-+            // a read finished interrupt will be received
-+            saa_system.rf_it_received = FALSE;
-+
-+            // send the write finished interrupt to SAA/MMDSP
-+            saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
-+        }
-+    }
-+
-+    // write new message to ARM downlink local FIFO
-+    if (SAA_PushToLocalFifoDL(&new_message)){
-+        SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
-+        return new_message.command_number;
-+    }
-+    SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
-+      #endif
-+
-+      return 0;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_PutMessage                                                                                          */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Put a message in the shared downlink mailbox.                         */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:               pMsg: pointer to the message description                                        */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            TRUE if successful, FALSE otherwise                                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PutMessage(t_saa_message* pMsg) {
-+
-+      t_saa_message* pNewMsg;
-+      int i;
-+      #ifndef SAA_USE_DOUBLE_IT
-+      volatile t_uint32 *host_address = (t_uint32 *)&saa_system.pSAA_HW->host_reg;
-+      #endif
-+
-+      if (saa_system.mailbox_dl.pMsg == NULL)
-+              return FALSE;
-+
-+      pNewMsg = saa_system.mailbox_dl.pMsg + saa_system.mailbox_dl.index;
-+
-+      if ((pNewMsg->semaphore & 0x00FF) == 0) {
-+              pNewMsg->command_number = pMsg->command_number;
-+              pNewMsg->command_id = pMsg->command_id;
-+              pNewMsg->server_id = pMsg->server_id;
-+
-+              for (i=0; i<SAA_MSG_NB_PARAM; i++) {
-+                      pNewMsg->params[i] = pMsg->params[i];
-+              }
-+
-+              if (++saa_system.mailbox_dl.index == SAA_MBX_DOWN_SIZE)
-+                      saa_system.mailbox_dl.index = 0;
-+
-+              #ifndef SAA_USE_DOUBLE_IT
-+              while (host_address[HOST_HA_CMD1_SEM] != 0)     {}
-+              host_address[HOST_HA_CMD1_SEM] = 1;
-+              #endif
-+
-+              pNewMsg->semaphore |= 0x0001;
-+
-+        if (saa_hcl_hti_trace)
-+                  SAA_HtiTraceMsg(ESAA_DOWN_MSG, pMsg);
-+
-+              return TRUE;
-+      }
-+
-+      return FALSE;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_GetMessage                                                                                          */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Get a message from the shared uplink mailbox.                         */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       -                                                                                                                       */
-+/*  OUT:              pMsg: pointer to the message description                                        */
-+/* RETURN:                                                                                                                                    */
-+/*                            TRUE if successful, FALSE otherwise                                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_GetMessage(t_saa_message* pMsg) {
-+
-+      t_saa_message* pNextMsg;
-+      int i;
-+
-+      if (saa_system.mailbox_ul.pMsg == NULL)
-+              return FALSE;
-+
-+      pNextMsg = saa_system.mailbox_ul.pMsg + saa_system.mailbox_ul.index;
-+
-+      if ((pNextMsg->semaphore & 0x00FF) == 0)
-+              return FALSE;
-+
-+      if (++saa_system.mailbox_ul.index == SAA_MBX_UP_SIZE)
-+              saa_system.mailbox_ul.index = 0;
-+
-+      pMsg->command_number = pNextMsg->command_number;
-+      pMsg->command_id = pNextMsg->command_id;
-+      pMsg->semaphore = pNextMsg->semaphore;
-+      pMsg->server_id = pNextMsg->server_id;
-+
-+      for (i=0; i<SAA_MSG_NB_PARAM; i++) {
-+              pMsg->params[i] = pNextMsg->params[i];
-+      }
-+
-+      pNextMsg->semaphore &= 0xFF00;
-+
-+      return TRUE;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_PushToLocalFifoUL                                                                           */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Push a message to the ARM uplink local FIFO.                          */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:               pMsg: pointer to the message description                                        */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            TRUE if successful, FALSE otherwise                                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PushToLocalFifoUL(t_saa_message* pMsg) {
-+
-+      t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
-+
-+      // check if FIFO is not full
-+      if (pFifoUL->unread_msg_counter < SAA_FIFO_UL_SIZE) {
-+              pFifoUL->message[pFifoUL->wr_position] = *pMsg;
-+
-+              pFifoUL->unread_msg_counter++;
-+
-+              if (++pFifoUL->wr_position == SAA_FIFO_UL_SIZE)
-+                      pFifoUL->wr_position = 0;
-+
-+              return TRUE;
-+      }
-+
-+      return FALSE;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_PopFromLocalFifoUL                                                                          */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Pop a message from the ARM uplink local FIFO.                         */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       -                                                                                                                       */
-+/*  OUT:              pMsg: pointer to the message description                                        */
-+/* RETURN:                                                                                                                                    */
-+/*                            TRUE if successful, FALSE otherwise                                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PopFromLocalFifoUL(t_saa_message* pMsg) {
-+
-+      t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
-+
-+      // check if FIFO is not empty
-+      if (pFifoUL->unread_msg_counter) {
-+              *pMsg = pFifoUL->message[pFifoUL->rd_position];
-+
-+              pFifoUL->unread_msg_counter--;
-+
-+              if (++pFifoUL->rd_position == SAA_FIFO_UL_SIZE)
-+                      pFifoUL->rd_position = 0;
-+
-+              if (saa_hcl_hti_trace)
-+                      SAA_HtiTraceMsg(ESAA_UP_MSG, pMsg);
-+
-+              return TRUE;
-+      }
-+
-+      return FALSE;
-+}
-+
-+#ifdef SAA_USE_DOUBLE_IT
-+/****************************************************************************/
-+/* NAME:              SAA_PushToLocalFifoDL                                                                           */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Push a message to the ARM local downlink FIFO.                                */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:               pMsg: pointer to the message description                                        */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            TRUE if successful, FALSE otherwise                                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PushToLocalFifoDL(t_saa_message* pMsg) {
-+
-+      t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
-+
-+      // check if FIFO is not full
-+      if (pFifoDL->unsent_msg_counter < SAA_FIFO_DL_SIZE) {
-+              pFifoDL->message[pFifoDL->wr_position] = *pMsg;
-+
-+              pFifoDL->unsent_msg_counter++;
-+
-+              if (++pFifoDL->wr_position == SAA_FIFO_DL_SIZE)
-+                      pFifoDL->wr_position = 0;
-+
-+              return TRUE;
-+      }
-+
-+      return FALSE;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_PopFromLocalFifoDL                                                                          */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Pop a message from the ARM local downlink FIFO.                               */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       -                                                                                                                       */
-+/*  OUT:              pMsg: pointer to the message description                                        */
-+/* RETURN:                                                                                                                                    */
-+/*                            TRUE if successful, FALSE otherwise                                                     */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_bool SAA_PopFromLocalFifoDL(t_saa_message* pMsg) {
-+
-+      t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
-+
-+      // check if FIFO is not empty
-+      if (pFifoDL->unsent_msg_counter) {
-+              *pMsg = pFifoDL->message[pFifoDL->rd_position];
-+
-+              pFifoDL->unsent_msg_counter--;
-+
-+              if (++pFifoDL->rd_position == SAA_FIFO_DL_SIZE)
-+                      pFifoDL->rd_position = 0;
-+
-+              return TRUE;
-+      }
-+
-+      return FALSE;
-+}
-+#endif
-+
-+/****************************************************************************/
-+/* NAME:              SAA_NewComponent                                                                                        */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Find a new entry in the component table.                                      */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       -                                                                                                                       */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            pointer to new entry if successful, NULL otherwise                      */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_saa_component_entry* SAA_NewComponent(void) {
-+
-+      t_saa_component_entry* pComponent = saa_system.component;
-+      int i;
-+
-+      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+      {
-+              if (pComponent->block_id == 0)
-+                      return pComponent;
-+      }
-+
-+      return NULL;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_FindComponent                                                                                       */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Find a given component.                                                                               */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       block_id: identifier of the block                                                       */
-+/*                            component_id: identifier of the component                                       */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            pointer to entry if successful, NULL otherwise                          */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_saa_component_entry* SAA_FindComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
-+
-+      t_saa_component_entry* pComponent = saa_system.component;
-+      int i;
-+
-+      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+      {
-+              if (pComponent->block_id == block_id && pComponent->component_id == component_id)
-+              {
-+                      return pComponent;
-+              }
-+      }
-+
-+      return NULL;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_FreeComponent                                                                                       */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Free an existing component.                                                                   */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       block_id: identifier of the block                                                       */
-+/*                            component_id: identifier of the component                                       */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            pointer to old entry if successful, NULL otherwise                      */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_saa_component_entry* SAA_FreeComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
-+
-+      t_saa_component_entry* pComponent = saa_system.component;
-+      int i;
-+
-+      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+      {
-+              if (pComponent->block_id == block_id && pComponent->component_id == component_id)
-+              {
-+                      pComponent->block_id = 0;
-+                      return pComponent;
-+              }
-+      }
-+
-+      return NULL;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_FreeAllComponents                                                                           */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Free all components of an existing block.                                     */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:                       block_id: identifier of the block                                                       */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:                                                                                                                                    */
-+/*                            Number of components freed                                                                      */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+PUBLIC t_uint16 SAA_FreeAllComponents(t_saa_block_id block_id) {
-+
-+      t_saa_component_entry* pComponent = saa_system.component;
-+      t_uint16 nb_components = 0;
-+      int i;
-+
-+      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
-+      {
-+              if (pComponent->block_id == block_id)
-+              {
-+                      pComponent->block_id = 0;
-+                      nb_components++;
-+              }
-+      }
-+
-+      return nb_components;
-+}
-+
-+/****************************************************************************/
-+/* NAME:              SAA_HtiTraceMsg                                                                                         */
-+/*--------------------------------------------------------------------------*/
-+/* DESCRIPTION: Sends a message to the HTI debug port.                                                */
-+/*                                                                                                                                                    */
-+/* PARAMETERS:                                                                                                                                */
-+/*  IN:               msg_dir: direction of message (uplink/downlink)                         */
-+/*                            pMsg:    pointer to the message to be sent                                      */
-+/*  OUT:              -                                                                                                                       */
-+/* RETURN:            void                                                                                                            */
-+/*--------------------------------------------------------------------------*/
-+/* REENTRANCY: NA                                                                                                                     */
-+/****************************************************************************/
-+
-+
-+PUBLIC void SAA_HtiTraceMsg(t_saa_msg_dir msg_dir, t_saa_message* pMsg)
-+{
-+      t_uint16* pDynParams;
-+
-+    HTI_CMD_SAA_HCL(SAA_HCL_HTI_CHANNEL);
-+
-+    if ((pMsg->command_id==HA_CMD_CONFIG_COMPONENT) && (msg_dir==ESAA_DOWN_MSG)){
-+        HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir + 0XF0); // specify not standart message
-+        HtiSendn_32(SAA_HCL_HTI_CHANNEL,(const HTI_U32 *)pMsg, 3); //semaphore command_number server_id  command_id params[0] params[1]
-+              pDynParams = (t_uint16*)(((t_uint32)pMsg->params[3])<<16 | pMsg->params[2]); // param address
-+        HtiSend_16(SAA_HCL_HTI_CHANNEL, pMsg->params[4]); // nb param
-+        HtiSendn_16(SAA_HCL_HTI_CHANNEL, pDynParams, pMsg->params[4]);
-+    }
-+    else{
-+        HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir);
-+        HtiSendn_32(SAA_HCL_HTI_CHANNEL, (const HTI_U32 *)pMsg, sizeof(t_saa_message)/ sizeof(int));
-+
-+    }
-+    HTI_CMD_END_OF_CHANNEL(SAA_HCL_HTI_CHANNEL);
-+
-+
-+}
-+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c 2008-07-17 16:42:58.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c
 @@ -0,0 +1,2538 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -51386,9 +51674,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.c ../new/linux-2.
 +
 +      return error;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.h 2008-07-17 16:42:59.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.h
 @@ -0,0 +1,306 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -51696,9 +51983,568 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa.h ../new/linux-2.
 +#endif        // __cplusplus
 +
 +#endif        // __INC_SAA_H
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h     2008-07-17 16:43:00.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_base.c
+@@ -0,0 +1,557 @@
++/*---------------------------------------------------------------------------*/
++/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
++/* information, STMicroelectronics reserves the right to license this        */
++/*  software concurrently under separate license conditions.                 */
++/*                                                                           */
++/* This program 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.                                     */
++/*                                                                           */
++/* 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 Lesser General Public License for more details.                   */
++/*                                                                           */
++/* You should have received a copy of the GNU Lesser General Public License  */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
++/*---------------------------------------------------------------------------*/
++
++/*--------------------------------------------------------------------------*
++ * Includes                                                                                                                                   *
++ *--------------------------------------------------------------------------*/
++#include "saa_hwp.h"
++#include "saap.h"
++#include "hti.h"
++#include "hti_protocol.h"
++
++
++/*--------------------------------------------------------------------------*
++ *  Global variables                                                                                                          *
++ *--------------------------------------------------------------------------*/
++t_saa_system saa_system;
++t_bool                 saa_hcl_hti_trace = FALSE;
++
++
++/*--------------------------------------------------------------------------*
++ *  Private data                                                                                                                      *
++ *--------------------------------------------------------------------------*/
++
++/*--------------------------------------------------------------------------*
++ *  Public functions                                                                                                          *
++ *--------------------------------------------------------------------------*/
++
++/****************************************************************************/
++/* NAME:              SAA_InitSharedMailboxes                                                                         */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Set the address of the shared uplink & downlink mailboxes.    */
++/*                            Called once when the first interrupt is received.                       */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:               -                                                                                                                       */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            None                                                                                                            */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC void SAA_InitSharedMailboxes(void) {
++
++      volatile t_uint16* ptr;
++      t_uint32 offset;
++      t_uint32 host_address = (t_uint32)&saa_system.pSAA_HW->host_reg;
++      t_uint32 ram_address =  (t_uint32)saa_system.pSAA_HW->ram;
++
++      // build the uplink shared mailbox address
++      ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_1);
++      offset = (t_uint32)(*ptr) & 0xFF;
++      ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_2);
++      offset <<= 8;
++      offset |= (t_uint32)(*ptr) & 0xFF;
++      ptr = (t_uint16*)(host_address + 2*HOST_HA_MBX_UP_ADD_3);
++      offset <<= 8;
++      offset |= (t_uint32)(*ptr) & 0xFF;
++      offset <<= 1;
++      saa_system.mailbox_ul.pMsg = (t_saa_message*)(ram_address + offset);
++
++      // build the downlink shared mailbox address
++      ptr = (t_uint16*)(host_address  + 2*HOST_HA_MBX_DOWN_ADD_1);
++      offset = (t_uint32)(*ptr) & 0xFF;
++      ptr = (t_uint16*)(host_address  + 2*HOST_HA_MBX_DOWN_ADD_2);
++      offset <<= 8;
++      offset |= (t_uint32)(*ptr) & 0xFF;
++      ptr = (t_uint16*)(host_address  + 2*HOST_HA_MBX_DOWN_ADD_3);
++      offset <<= 8;
++      offset |= (t_uint32)(*ptr) & 0xFF;
++      offset <<= 1;
++      saa_system.mailbox_dl.pMsg = (t_saa_message*)(ram_address + offset);
++}
++
++/****************************************************************************/
++/* NAME:              SAA_SendCommand                                                                                         */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Send a command to the SAA/MMDSP.                                                      */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:               pCmd: pointer to the command description                                        */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            command number>0 if successful, 0 otherwise                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_uint16 SAA_SendCommand(t_saa_cmd_desc* pCmd) {
++
++      t_saa_message new_message;
++      #ifdef SAA_USE_DOUBLE_IT
++      t_saa_message message;
++    int nb_msg_sent = 0;
++      #endif
++      int i;
++
++      new_message.command_number = (t_uint16)(saa_system.command_number + 1);
++      new_message.command_id = pCmd->command_id;
++      new_message.server_id = pCmd->server_id;
++
++      for (i=0; i<SAA_MSG_NB_PARAM; i++) {
++              new_message.params[i] = pCmd->params[i];
++      }
++
++      if (++saa_system.command_number == 0xFFFF)
++              saa_system.command_number = 0;  // avoid 16-bit roll-over of next command number (answer/alert mismatch)
++
++      #ifndef SAA_USE_DOUBLE_IT
++      if (SAA_PutMessage(&new_message))
++      {
++              // send the write finished interrupt to SAA/MMDSP
++              saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
++
++              return new_message.command_number;
++      }
++      #else
++    SAA_DisableIRQSrc(ESAA_SRC_IRQ_1);
++    // check if ARM is waiting for a read finished interrupt
++    if(saa_system.rf_it_received){
++              // copy all messages from ARM downlink local FIFO to downlink shared mailbox
++        while ((nb_msg_sent < SAA_MBX_DOWN_SIZE)&&(SAA_PopFromLocalFifoDL(&message))){
++                      (void)SAA_PutMessage(&message);
++            nb_msg_sent ++;
++              }
++
++        if (SAA_PutMessage(&new_message)){
++            // a read finished interrupt will be received
++            saa_system.rf_it_received = FALSE;
++
++            // send the write finished interrupt to SAA/MMDSP
++            saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
++                SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
++            return new_message.command_number;
++        }
++
++              if(nb_msg_sent != 0){
++            // a read finished interrupt will be received
++            saa_system.rf_it_received = FALSE;
++
++            // send the write finished interrupt to SAA/MMDSP
++            saa_system.pSAA_HW->host_reg.cmd[1] ^= 1;
++        }
++    }
++
++    // write new message to ARM downlink local FIFO
++    if (SAA_PushToLocalFifoDL(&new_message)){
++        SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
++        return new_message.command_number;
++    }
++    SAA_EnableIRQSrc(ESAA_SRC_IRQ_1);
++      #endif
++
++      return 0;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_PutMessage                                                                                          */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Put a message in the shared downlink mailbox.                         */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:               pMsg: pointer to the message description                                        */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            TRUE if successful, FALSE otherwise                                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_bool SAA_PutMessage(t_saa_message* pMsg) {
++
++      t_saa_message* pNewMsg;
++      int i;
++      #ifndef SAA_USE_DOUBLE_IT
++      volatile t_uint32 *host_address = (t_uint32 *)&saa_system.pSAA_HW->host_reg;
++      #endif
++
++      if (saa_system.mailbox_dl.pMsg == NULL)
++              return FALSE;
++
++      pNewMsg = saa_system.mailbox_dl.pMsg + saa_system.mailbox_dl.index;
++
++      if ((pNewMsg->semaphore & 0x00FF) == 0) {
++              pNewMsg->command_number = pMsg->command_number;
++              pNewMsg->command_id = pMsg->command_id;
++              pNewMsg->server_id = pMsg->server_id;
++
++              for (i=0; i<SAA_MSG_NB_PARAM; i++) {
++                      pNewMsg->params[i] = pMsg->params[i];
++              }
++
++              if (++saa_system.mailbox_dl.index == SAA_MBX_DOWN_SIZE)
++                      saa_system.mailbox_dl.index = 0;
++
++              #ifndef SAA_USE_DOUBLE_IT
++              while (host_address[HOST_HA_CMD1_SEM] != 0)     {}
++              host_address[HOST_HA_CMD1_SEM] = 1;
++              #endif
++
++              pNewMsg->semaphore |= 0x0001;
++
++        if (saa_hcl_hti_trace)
++                  SAA_HtiTraceMsg(ESAA_DOWN_MSG, pMsg);
++
++              return TRUE;
++      }
++
++      return FALSE;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_GetMessage                                                                                          */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Get a message from the shared uplink mailbox.                         */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       -                                                                                                                       */
++/*  OUT:              pMsg: pointer to the message description                                        */
++/* RETURN:                                                                                                                                    */
++/*                            TRUE if successful, FALSE otherwise                                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_bool SAA_GetMessage(t_saa_message* pMsg) {
++
++      t_saa_message* pNextMsg;
++      int i;
++
++      if (saa_system.mailbox_ul.pMsg == NULL)
++              return FALSE;
++
++      pNextMsg = saa_system.mailbox_ul.pMsg + saa_system.mailbox_ul.index;
++
++      if ((pNextMsg->semaphore & 0x00FF) == 0)
++              return FALSE;
++
++      if (++saa_system.mailbox_ul.index == SAA_MBX_UP_SIZE)
++              saa_system.mailbox_ul.index = 0;
++
++      pMsg->command_number = pNextMsg->command_number;
++      pMsg->command_id = pNextMsg->command_id;
++      pMsg->semaphore = pNextMsg->semaphore;
++      pMsg->server_id = pNextMsg->server_id;
++
++      for (i=0; i<SAA_MSG_NB_PARAM; i++) {
++              pMsg->params[i] = pNextMsg->params[i];
++      }
++
++      pNextMsg->semaphore &= 0xFF00;
++
++      return TRUE;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_PushToLocalFifoUL                                                                           */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Push a message to the ARM uplink local FIFO.                          */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:               pMsg: pointer to the message description                                        */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            TRUE if successful, FALSE otherwise                                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_bool SAA_PushToLocalFifoUL(t_saa_message* pMsg) {
++
++      t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
++
++      // check if FIFO is not full
++      if (pFifoUL->unread_msg_counter < SAA_FIFO_UL_SIZE) {
++              pFifoUL->message[pFifoUL->wr_position] = *pMsg;
++
++              pFifoUL->unread_msg_counter++;
++
++              if (++pFifoUL->wr_position == SAA_FIFO_UL_SIZE)
++                      pFifoUL->wr_position = 0;
++
++              return TRUE;
++      }
++
++      return FALSE;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_PopFromLocalFifoUL                                                                          */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Pop a message from the ARM uplink local FIFO.                         */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       -                                                                                                                       */
++/*  OUT:              pMsg: pointer to the message description                                        */
++/* RETURN:                                                                                                                                    */
++/*                            TRUE if successful, FALSE otherwise                                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_bool SAA_PopFromLocalFifoUL(t_saa_message* pMsg) {
++
++      t_saa_fifo_ul* pFifoUL = &saa_system.fifo_ul;
++
++      // check if FIFO is not empty
++      if (pFifoUL->unread_msg_counter) {
++              *pMsg = pFifoUL->message[pFifoUL->rd_position];
++
++              pFifoUL->unread_msg_counter--;
++
++              if (++pFifoUL->rd_position == SAA_FIFO_UL_SIZE)
++                      pFifoUL->rd_position = 0;
++
++              if (saa_hcl_hti_trace)
++                      SAA_HtiTraceMsg(ESAA_UP_MSG, pMsg);
++
++              return TRUE;
++      }
++
++      return FALSE;
++}
++
++#ifdef SAA_USE_DOUBLE_IT
++/****************************************************************************/
++/* NAME:              SAA_PushToLocalFifoDL                                                                           */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Push a message to the ARM local downlink FIFO.                                */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:               pMsg: pointer to the message description                                        */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            TRUE if successful, FALSE otherwise                                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_bool SAA_PushToLocalFifoDL(t_saa_message* pMsg) {
++
++      t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
++
++      // check if FIFO is not full
++      if (pFifoDL->unsent_msg_counter < SAA_FIFO_DL_SIZE) {
++              pFifoDL->message[pFifoDL->wr_position] = *pMsg;
++
++              pFifoDL->unsent_msg_counter++;
++
++              if (++pFifoDL->wr_position == SAA_FIFO_DL_SIZE)
++                      pFifoDL->wr_position = 0;
++
++              return TRUE;
++      }
++
++      return FALSE;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_PopFromLocalFifoDL                                                                          */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Pop a message from the ARM local downlink FIFO.                               */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       -                                                                                                                       */
++/*  OUT:              pMsg: pointer to the message description                                        */
++/* RETURN:                                                                                                                                    */
++/*                            TRUE if successful, FALSE otherwise                                                     */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_bool SAA_PopFromLocalFifoDL(t_saa_message* pMsg) {
++
++      t_saa_fifo_dl* pFifoDL = &saa_system.fifo_dl;
++
++      // check if FIFO is not empty
++      if (pFifoDL->unsent_msg_counter) {
++              *pMsg = pFifoDL->message[pFifoDL->rd_position];
++
++              pFifoDL->unsent_msg_counter--;
++
++              if (++pFifoDL->rd_position == SAA_FIFO_DL_SIZE)
++                      pFifoDL->rd_position = 0;
++
++              return TRUE;
++      }
++
++      return FALSE;
++}
++#endif
++
++/****************************************************************************/
++/* NAME:              SAA_NewComponent                                                                                        */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Find a new entry in the component table.                                      */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       -                                                                                                                       */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            pointer to new entry if successful, NULL otherwise                      */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_saa_component_entry* SAA_NewComponent(void) {
++
++      t_saa_component_entry* pComponent = saa_system.component;
++      int i;
++
++      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++      {
++              if (pComponent->block_id == 0)
++                      return pComponent;
++      }
++
++      return NULL;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_FindComponent                                                                                       */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Find a given component.                                                                               */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       block_id: identifier of the block                                                       */
++/*                            component_id: identifier of the component                                       */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            pointer to entry if successful, NULL otherwise                          */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_saa_component_entry* SAA_FindComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
++
++      t_saa_component_entry* pComponent = saa_system.component;
++      int i;
++
++      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++      {
++              if (pComponent->block_id == block_id && pComponent->component_id == component_id)
++              {
++                      return pComponent;
++              }
++      }
++
++      return NULL;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_FreeComponent                                                                                       */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Free an existing component.                                                                   */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       block_id: identifier of the block                                                       */
++/*                            component_id: identifier of the component                                       */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            pointer to old entry if successful, NULL otherwise                      */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_saa_component_entry* SAA_FreeComponent(t_saa_block_id block_id, t_saa_component_id component_id) {
++
++      t_saa_component_entry* pComponent = saa_system.component;
++      int i;
++
++      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++      {
++              if (pComponent->block_id == block_id && pComponent->component_id == component_id)
++              {
++                      pComponent->block_id = 0;
++                      return pComponent;
++              }
++      }
++
++      return NULL;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_FreeAllComponents                                                                           */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Free all components of an existing block.                                     */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:                       block_id: identifier of the block                                                       */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:                                                                                                                                    */
++/*                            Number of components freed                                                                      */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++PUBLIC t_uint16 SAA_FreeAllComponents(t_saa_block_id block_id) {
++
++      t_saa_component_entry* pComponent = saa_system.component;
++      t_uint16 nb_components = 0;
++      int i;
++
++      for (i=0; i<SAA_NB_MAX_COMPONENT; i++, pComponent++)
++      {
++              if (pComponent->block_id == block_id)
++              {
++                      pComponent->block_id = 0;
++                      nb_components++;
++              }
++      }
++
++      return nb_components;
++}
++
++/****************************************************************************/
++/* NAME:              SAA_HtiTraceMsg                                                                                         */
++/*--------------------------------------------------------------------------*/
++/* DESCRIPTION: Sends a message to the HTI debug port.                                                */
++/*                                                                                                                                                    */
++/* PARAMETERS:                                                                                                                                */
++/*  IN:               msg_dir: direction of message (uplink/downlink)                         */
++/*                            pMsg:    pointer to the message to be sent                                      */
++/*  OUT:              -                                                                                                                       */
++/* RETURN:            void                                                                                                            */
++/*--------------------------------------------------------------------------*/
++/* REENTRANCY: NA                                                                                                                     */
++/****************************************************************************/
++
++
++PUBLIC void SAA_HtiTraceMsg(t_saa_msg_dir msg_dir, t_saa_message* pMsg)
++{
++      t_uint16* pDynParams;
++
++    HTI_CMD_SAA_HCL(SAA_HCL_HTI_CHANNEL);
++
++    if ((pMsg->command_id==HA_CMD_CONFIG_COMPONENT) && (msg_dir==ESAA_DOWN_MSG)){
++        HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir + 0XF0); // specify not standart message
++        HtiSendn_32(SAA_HCL_HTI_CHANNEL,(const HTI_U32 *)pMsg, 3); //semaphore command_number server_id  command_id params[0] params[1]
++              pDynParams = (t_uint16*)(((t_uint32)pMsg->params[3])<<16 | pMsg->params[2]); // param address
++        HtiSend_16(SAA_HCL_HTI_CHANNEL, pMsg->params[4]); // nb param
++        HtiSendn_16(SAA_HCL_HTI_CHANNEL, pDynParams, pMsg->params[4]);
++    }
++    else{
++        HtiSend_8(SAA_HCL_HTI_CHANNEL, msg_dir);
++        HtiSendn_32(SAA_HCL_HTI_CHANNEL, (const HTI_U32 *)pMsg, sizeof(t_saa_message)/ sizeof(int));
++
++    }
++    HTI_CMD_END_OF_CHANNEL(SAA_HCL_HTI_CHANNEL);
++
++
++}
++
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h
 @@ -0,0 +1,275 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -51975,9 +52821,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_hwp.h ../new/linu
 +#endif        // __cplusplus
 +
 +#endif        // __INC_SAA_HWP_H
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c     2008-07-17 16:43:01.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c
 @@ -0,0 +1,432 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -52411,9 +53256,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saa_irq.c ../new/linu
 +
 +      return error;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saap.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saap.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saap.h        2008-07-17 16:43:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saap.h
 @@ -0,0 +1,160 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -52575,9 +53419,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/saa/saap.h ../new/linux-2
 +#endif        // __cplusplus
 +
 +#endif        // __INC_SAAP_H
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c     2008-07-17 16:45:14.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.c
 @@ -0,0 +1,63 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -52642,9 +53485,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabiliti
 +}
 +
 +// End of file - sva_capabilities.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h     2008-07-17 16:45:14.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabilities.h
 @@ -0,0 +1,46 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -52692,9 +53534,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_capabiliti
 +
 +#endif /* __INC_HV_CAPABILITIES_H */
 +/* End of file - sva_capabilities.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h     2008-07-17 16:45:15.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h
 @@ -0,0 +1,335 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -53031,9 +53872,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_fifo.h ../
 +
 +#endif /* __INC_SVA_FIFO_H */
 +/* End of file - sva_fifo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h      2008-07-17 16:45:16.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h
 @@ -0,0 +1,646 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -53681,9 +54521,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_hwp.h ../n
 +#endif /* __INC_SVA_HWP_H */
 +
 +// End of file - sva_hwP.h
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c    2008-07-17 16:45:16.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.c
 @@ -0,0 +1,131 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -53816,9 +54655,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalne
 +
 + return SVA_IN_OK;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h    2008-07-17 16:45:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalneeds.h
 @@ -0,0 +1,61 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -53881,201 +54719,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_internalne
 +
 +#endif /* __INC_SVA_IN_H */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h 2008-07-17 16:45:19.000000000 +0530
-@@ -0,0 +1,188 @@
-+/*---------------------------------------------------------------------------*/
-+/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
-+/* information, STMicroelectronics reserves the right to license this        */
-+/*  software concurrently under separate license conditions.                 */
-+/*                                                                           */
-+/* This program 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.                                     */
-+/*                                                                           */
-+/* 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 Lesser General Public License for more details.                   */
-+/*                                                                           */
-+/* You should have received a copy of the GNU Lesser General Public License  */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVAP_H
-+#define __INC_SVAP_H
-+
-+#include "hcl_defs.h"
-+
-+/******************************************************************************/
-+/* Constants definitions                                                      */
-+/******************************************************************************/
-+/*
-+ * Define various conditonnal compilation flags in order to include or not any SW workarounds
-+ */
-+/*#define WORK_AROUND_AHB*/
-+
-+/*
-+ * Define the maximum number of error defined per module
-+ */
-+#define SVA_MODULE_ERROR_RANGE        0x20
-+
-+/*
-+ * Define an Id related to each module of the SVA HCL
-+ * The Id = 1 is reserved for SVA HCL itself
-+ */
-+typedef enum {
-+      SVA_EM_ID       = 2,    /* Events Mgt */
-+      SVA_MM_ID,              /* Memory Mgt */
-+      SVA_BM_ID,              /* Buffers Mgt */
-+      SVA_BLM_ID,             /* Buffers ListMgt */
-+      SVA_TM_ID,              /* Tasks Mgt */
-+      SVA_FM_ID,              /* Firmware Mgt */
-+      SVA_TI_ID,              /* Time Mgt */
-+      SVA_VP_ID,              /* Video Pipeline */
-+      SVA_FF_ID,               /* FIFO macros */
-+      SVA_IN_ID,               /* Internal Needs Mgt */
-+      SVA_SV_ID,               /* Common Service */
-+      SVA_DP_ID,              /* Display Service */
-+      SVA_DC_ID,              /* Decode Service */
-+      SVA_EC_ID,              /* Encode Service */
-+      SVA_GB_ID,              /* Grab Service */
-+      SVA_DC_ERC_ID,          /* Decode Error Concealment */
-+      SVA_DC_MP4_ID,          /* Decode MPEG4 Algo */
-+      SVA_DC_H263_ID,         /* Decode H263 Algo */
-+      SVA_DC_H264_ID,         /* Decode H263 Algo */
-+      SVA_EC_BRC_ID,          /* Encode Bit Rate Control */
-+      SVA_EC_MP4_ID,          /* Encode MPEG4 Algo */
-+      SVA_EC_H263_ID,         /* Encode H263 Algo */
-+      SVA_EC_H264_ID,         /* Encode H264 Algo */
-+      SVA_EC_STAB_ID,         /* Encode Stabilization */
-+      SVA_SEC_JPEG_ID,                /* Still Encode JPEG ALgo */
-+      SVA_SEC_ID,                             /* still Encode service */
-+      SVA_TV_ID           /* TVO Service */
-+} sva_module_id;
-+
-+/* ************************** CONFIGURATION PART ************************** */
-+typedef struct {
-+      t_uint32 cfg_psa;       /* Subtask parameter Start Address register */
-+      t_uint32 cfg_pea;       /* Subtask parameter Stop Address register */
-+      t_uint32 cfg_ice;       /* Idle Cycle Enable register */
-+      t_uint32 cfg_csc;   /* CCP synchronization codes register */
-+      t_uint32 cfg_cgc;   /* clock gating control register */
-+      t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
-+      t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
-+      t_uint32 cfg_irp_rw; /* status of the current rw operation */
-+      t_uint32 cfg_irp_error; /* error code */
-+      t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
-+      t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
-+      t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
-+      t_uint32 cfg_clk;       /* Clock generation register */
-+      t_uint32 ckg_cken; /* added*/
-+      t_uint32 cfg_tim;       /* Timer Initialization value register */
-+      t_uint32 cfg_iis;       /* IRQ1 Interrupt Status register */
-+      t_uint32 cfg_isr;       /* Global Interrupt status register */
-+      t_uint32 cfg_imr;       /* Global Interrupt mask register */
-+//    t_uint32 wasDeepSleepEntered;
-+      t_uint32 temp_idn_frv;
-+      t_sva_fw_id fwId;
-+      t_uint32 sva_context_magic_number;
-+} t_sva_config_regs_mapping1;
-+
-+#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
-+
-+#define SVA_EM_LAST_ERROR     (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EM_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_MM_LAST_ERROR     (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_MM_FIRST_INFO     (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BM_LAST_ERROR     (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BM_FIRST_INFO     (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BLM_LAST_ERROR    (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BLM_FIRST_INFO    (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TM_LAST_ERROR     (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TM_FIRST_INFO     (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FM_LAST_ERROR     (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FM_FIRST_INFO     (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TI_LAST_ERROR     (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TI_FIRST_INFO     (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FF_LAST_ERROR     (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FF_FIRST_INFO     (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_IN_LAST_ERROR     (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_IN_FIRST_INFO     (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SV_LAST_ERROR     (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SV_FIRST_INFO     (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DP_LAST_ERROR     (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DP_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_LAST_ERROR     (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_FIRST_INFO     (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_LAST_ERROR     (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_FIRST_INFO     (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_GB_LAST_ERROR     (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_GB_FIRST_INFO     (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H263_LAST_ERROR        (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H263_FIRST_INFO        (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H264_LAST_ERROR        (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H264_FIRST_INFO        (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+
-+#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H263_LAST_ERROR        (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H263_FIRST_INFO        (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H264_LAST_ERROR        (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H264_FIRST_INFO        (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_STAB_LAST_ERROR        (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_STAB_FIRST_INFO        (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_JPEG_LAST_ERROR       (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_JPEG_FIRST_INFO       (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_LAST_ERROR    (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_FIRST_INFO    (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TV_LAST_ERROR     (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TV_FIRST_ERROR    (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+/******************************************************************************/
-+/* Types definitions */
-+/******************************************************************************/
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif        /* __cplusplus */
-+
-+#endif /* __INC_SVAP_H */
-+/* End of file - hvP.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h  2008-07-17 16:45:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h
 @@ -0,0 +1,337 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -54414,9 +55059,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_service.h
 +
 +#endif /* __INC_SVA_SERVICE_H */
 +/* End of file - SVA.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c  2008-07-17 16:45:18.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c
 @@ -0,0 +1,486 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -54904,9 +55548,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.c
 +
 +
 +/* End of sva_timemgt.c */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h  2008-07-17 16:45:18.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h
 @@ -0,0 +1,80 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -54988,9 +55631,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgt.h
 +
 +#endif /* __INC_SVA_TI_H */
 +/* End of file - sva_timemgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h 2008-07-17 16:45:19.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h
 @@ -0,0 +1,49 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -55041,9 +55683,199 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/sva_timemgtp.h
 +#endif /* __INC_SVA_TIP_H */
 +/* End of file - sva_timemgt.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c     2008-08-12 22:56:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/common/svap.h
+@@ -0,0 +1,188 @@
++/*---------------------------------------------------------------------------*/
++/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
++/* information, STMicroelectronics reserves the right to license this        */
++/*  software concurrently under separate license conditions.                 */
++/*                                                                           */
++/* This program 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.                                     */
++/*                                                                           */
++/* 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 Lesser General Public License for more details.                   */
++/*                                                                           */
++/* You should have received a copy of the GNU Lesser General Public License  */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVAP_H
++#define __INC_SVAP_H
++
++#include "hcl_defs.h"
++
++/******************************************************************************/
++/* Constants definitions                                                      */
++/******************************************************************************/
++/*
++ * Define various conditonnal compilation flags in order to include or not any SW workarounds
++ */
++/*#define WORK_AROUND_AHB*/
++
++/*
++ * Define the maximum number of error defined per module
++ */
++#define SVA_MODULE_ERROR_RANGE        0x20
++
++/*
++ * Define an Id related to each module of the SVA HCL
++ * The Id = 1 is reserved for SVA HCL itself
++ */
++typedef enum {
++      SVA_EM_ID       = 2,    /* Events Mgt */
++      SVA_MM_ID,              /* Memory Mgt */
++      SVA_BM_ID,              /* Buffers Mgt */
++      SVA_BLM_ID,             /* Buffers ListMgt */
++      SVA_TM_ID,              /* Tasks Mgt */
++      SVA_FM_ID,              /* Firmware Mgt */
++      SVA_TI_ID,              /* Time Mgt */
++      SVA_VP_ID,              /* Video Pipeline */
++      SVA_FF_ID,               /* FIFO macros */
++      SVA_IN_ID,               /* Internal Needs Mgt */
++      SVA_SV_ID,               /* Common Service */
++      SVA_DP_ID,              /* Display Service */
++      SVA_DC_ID,              /* Decode Service */
++      SVA_EC_ID,              /* Encode Service */
++      SVA_GB_ID,              /* Grab Service */
++      SVA_DC_ERC_ID,          /* Decode Error Concealment */
++      SVA_DC_MP4_ID,          /* Decode MPEG4 Algo */
++      SVA_DC_H263_ID,         /* Decode H263 Algo */
++      SVA_DC_H264_ID,         /* Decode H263 Algo */
++      SVA_EC_BRC_ID,          /* Encode Bit Rate Control */
++      SVA_EC_MP4_ID,          /* Encode MPEG4 Algo */
++      SVA_EC_H263_ID,         /* Encode H263 Algo */
++      SVA_EC_H264_ID,         /* Encode H264 Algo */
++      SVA_EC_STAB_ID,         /* Encode Stabilization */
++      SVA_SEC_JPEG_ID,                /* Still Encode JPEG ALgo */
++      SVA_SEC_ID,                             /* still Encode service */
++      SVA_TV_ID           /* TVO Service */
++} sva_module_id;
++
++/* ************************** CONFIGURATION PART ************************** */
++typedef struct {
++      t_uint32 cfg_psa;       /* Subtask parameter Start Address register */
++      t_uint32 cfg_pea;       /* Subtask parameter Stop Address register */
++      t_uint32 cfg_ice;       /* Idle Cycle Enable register */
++      t_uint32 cfg_csc;   /* CCP synchronization codes register */
++      t_uint32 cfg_cgc;   /* clock gating control register */
++      t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
++      t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
++      t_uint32 cfg_irp_rw; /* status of the current rw operation */
++      t_uint32 cfg_irp_error; /* error code */
++      t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
++      t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
++      t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
++      t_uint32 cfg_clk;       /* Clock generation register */
++      t_uint32 ckg_cken; /* added*/
++      t_uint32 cfg_tim;       /* Timer Initialization value register */
++      t_uint32 cfg_iis;       /* IRQ1 Interrupt Status register */
++      t_uint32 cfg_isr;       /* Global Interrupt status register */
++      t_uint32 cfg_imr;       /* Global Interrupt mask register */
++//    t_uint32 wasDeepSleepEntered;
++      t_uint32 temp_idn_frv;
++      t_sva_fw_id fwId;
++      t_uint32 sva_context_magic_number;
++} t_sva_config_regs_mapping1;
++
++#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
++
++#define SVA_EM_LAST_ERROR     (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EM_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_MM_LAST_ERROR     (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_MM_FIRST_INFO     (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BM_LAST_ERROR     (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BM_FIRST_INFO     (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BLM_LAST_ERROR    (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BLM_FIRST_INFO    (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TM_LAST_ERROR     (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TM_FIRST_INFO     (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FM_LAST_ERROR     (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FM_FIRST_INFO     (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TI_LAST_ERROR     (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TI_FIRST_INFO     (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FF_LAST_ERROR     (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FF_FIRST_INFO     (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_IN_LAST_ERROR     (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_IN_FIRST_INFO     (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SV_LAST_ERROR     (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SV_FIRST_INFO     (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DP_LAST_ERROR     (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DP_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_LAST_ERROR     (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_FIRST_INFO     (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_LAST_ERROR     (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_FIRST_INFO     (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_GB_LAST_ERROR     (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_GB_FIRST_INFO     (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H263_LAST_ERROR        (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H263_FIRST_INFO        (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H264_LAST_ERROR        (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H264_FIRST_INFO        (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++
++#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H263_LAST_ERROR        (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H263_FIRST_INFO        (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H264_LAST_ERROR        (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H264_FIRST_INFO        (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_STAB_LAST_ERROR        (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_STAB_FIRST_INFO        (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_JPEG_LAST_ERROR       (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_JPEG_FIRST_INFO       (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_LAST_ERROR    (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_FIRST_INFO    (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TV_LAST_ERROR     (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TV_FIRST_ERROR    (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++/******************************************************************************/
++/* Types definitions */
++/******************************************************************************/
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif        /* __cplusplus */
++
++#endif /* __INC_SVAP_H */
++/* End of file - hvP.h */
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.c
 @@ -0,0 +1,3030 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -58075,9 +58907,121 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h2
 +}
 +
 +// End of file - sva_dc_h264.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c 2008-08-12 22:56:11.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h
+@@ -0,0 +1,110 @@
++/*---------------------------------------------------------------------------*/
++/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
++/* information, STMicroelectronics reserves the right to license this        */
++/*  software concurrently under separate license conditions.                 */
++/*                                                                           */
++/* This program 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.                                     */
++/*                                                                           */
++/* 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 Lesser General Public License for more details.                   */
++/*                                                                           */
++/* You should have received a copy of the GNU Lesser General Public License  */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVA_DC_H264_H
++#define __INC_SVA_DC_H264_H
++
++#include "hcl_defs.h"
++#include "sva_service.h"
++#include "sva_dc_h264_dpb.h"
++#include "sva_dc_h264_slicemap.h"
++
++
++
++#ifdef        __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#ifdef __DEBUG
++#define SVA_DC_H264_MAX_DBG_DEPTH 30
++#define SVA_DC_H264_MAX_DBG_SLICESPERFRAME 9
++#define SVA_DC_H264_MAX_DBG_EVENTS    12
++#endif
++
++/* macros */
++#define H264MIN(a,b)     (((a)<(b))?a:b)
++#define H264MAX(a,b)     (((a)>(b))?a:b)
++#define H264_MAX_UINT_16     65535
++#define H264_MAX_SINT_32     2147483647
++#define H264_MIN_SINT_32    -H264_MAX_SINT_32-1
++#define H264_MAX_UINT_32     4294967295
++
++/* extracted from each slice headers of the frame and required to program vdc_h264_slice */
++typedef t_sva_h264_dpb_params_slice t_sva_h264_params_slice;
++
++
++/* used as parameter for SetHeaderInfo */
++typedef struct
++{     /* from active PPS */
++      t_uint16 chromaQpIndex;
++      t_uint16 constrIntraPredFlag;
++      t_uint16 numRefIdxl0ActiveMinus1;
++}t_sva_h264_active_pps;
++
++
++/* extracted from active PPS and first slice Header, used to compute sliceMap */
++typedef t_sva_h264_slicemap t_sva_h264_slicemap_info;
++
++
++
++/* public fonctions */
++PUBLIC t_sva_error    sva_DC_H264_Init( t_sva_service_instance_num , t_sva_codec_mode , t_sva_image_desc , const t_sva_dc_algo_configuration_params *);
++PUBLIC t_sva_error    sva_DC_H264_GetMemoryNeeds( t_sva_service_instance_num , t_size *);
++PUBLIC t_sva_error    sva_DC_H264_ProvideMemoryNeeds(t_sva_service_instance_num );
++PUBLIC t_sva_error  sva_DC_H264_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id);
++PUBLIC t_sva_error    sva_DC_H264_Close(t_sva_service_instance_num );
++PUBLIC t_sva_error    sva_DC_H264_InitHeaderInfos(t_sva_service_instance_num );
++PUBLIC t_sva_error    sva_DC_H264_SetHeaderInfos(t_sva_service_instance_num , t_sva_service_id ,t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *) ;
++PUBLIC t_sva_error    sva_DC_H264_AssertEndOfBitstream(t_sva_service_instance_num , t_sva_service_id ) ;
++PUBLIC t_sva_error    sva_DC_H264_Push(t_sva_service_instance_num , t_sva_buffer_type , t_sva_buffer_id ) ;
++PUBLIC t_sva_error    sva_DC_H264_DispatchEOT(t_sva_service_instance_num ,t_sva_tm_subtask_id , t_sva_event_desc* ,t_sva_service_id ,t_uint32 , t_uint32 ,t_uint32 *,t_uint32 ,t_sva_buffer_list_id);
++PUBLIC t_sva_error    sva_DC_H264_HandleFakeEvent(    t_sva_tm_virtual_hw_event_id ,
++                                                                                          t_sva_service_id ,
++                                                                                          t_sva_tm_subtask_id ,
++                                                                                          t_uint32 ,
++                                                                                          t_uint32 ,
++                                                                                          t_uint8 ,
++                                                                                          t_uint32 *,
++                                                                                          t_sva_event_desc *);
++PUBLIC t_sva_error    sva_DC_H264_ResolveDependencies(t_sva_service_instance_num  );
++PUBLIC t_bool sva_DC_H264_CheckInputDep(t_sva_service_instance_num);
++PUBLIC t_bool sva_DC_H264_CheckOutputDep(t_sva_service_instance_num);
++
++
++/* not usefull but needed to be existing */
++
++PUBLIC t_sva_error sva_DC_H264_FlushBitstreams(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_GetLastErrorType (t_sva_service_instance_num, t_uint16 *);
++PUBLIC t_sva_error sva_DC_H264_FlushFifos(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_DeleteFake(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *);
++PUBLIC t_size sva_DC_H264_GetOutputParamsSize(t_sva_service_instance_num);
++PUBLIC t_sva_error sva_DC_H264_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *);
++PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitInstance(t_sva_service_instance_num instanceNum);
++
++
++
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif        /* __cplusplus */
++
++
++
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.c
 @@ -0,0 +1,3101 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -61180,9 +62124,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h2
 +      return SVA_DC_H264_DPB_OK;
 +}
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h 2008-08-12 22:56:12.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpb.h
 @@ -0,0 +1,232 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -61416,9 +62359,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h2
 +
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h        2008-07-17 16:45:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_dpbp.h
 @@ -0,0 +1,98 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -61518,283 +62460,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h2
 +
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264.h     2008-07-17 16:45:00.000000000 +0530
-@@ -0,0 +1,110 @@
-+/*---------------------------------------------------------------------------*/
-+/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
-+/* information, STMicroelectronics reserves the right to license this        */
-+/*  software concurrently under separate license conditions.                 */
-+/*                                                                           */
-+/* This program 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.                                     */
-+/*                                                                           */
-+/* 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 Lesser General Public License for more details.                   */
-+/*                                                                           */
-+/* You should have received a copy of the GNU Lesser General Public License  */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVA_DC_H264_H
-+#define __INC_SVA_DC_H264_H
-+
-+#include "hcl_defs.h"
-+#include "sva_service.h"
-+#include "sva_dc_h264_dpb.h"
-+#include "sva_dc_h264_slicemap.h"
-+
-+
-+
-+#ifdef        __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+#ifdef __DEBUG
-+#define SVA_DC_H264_MAX_DBG_DEPTH 30
-+#define SVA_DC_H264_MAX_DBG_SLICESPERFRAME 9
-+#define SVA_DC_H264_MAX_DBG_EVENTS    12
-+#endif
-+
-+/* macros */
-+#define H264MIN(a,b)     (((a)<(b))?a:b)
-+#define H264MAX(a,b)     (((a)>(b))?a:b)
-+#define H264_MAX_UINT_16     65535
-+#define H264_MAX_SINT_32     2147483647
-+#define H264_MIN_SINT_32    -H264_MAX_SINT_32-1
-+#define H264_MAX_UINT_32     4294967295
-+
-+/* extracted from each slice headers of the frame and required to program vdc_h264_slice */
-+typedef t_sva_h264_dpb_params_slice t_sva_h264_params_slice;
-+
-+
-+/* used as parameter for SetHeaderInfo */
-+typedef struct
-+{     /* from active PPS */
-+      t_uint16 chromaQpIndex;
-+      t_uint16 constrIntraPredFlag;
-+      t_uint16 numRefIdxl0ActiveMinus1;
-+}t_sva_h264_active_pps;
-+
-+
-+/* extracted from active PPS and first slice Header, used to compute sliceMap */
-+typedef t_sva_h264_slicemap t_sva_h264_slicemap_info;
-+
-+
-+
-+/* public fonctions */
-+PUBLIC t_sva_error    sva_DC_H264_Init( t_sva_service_instance_num , t_sva_codec_mode , t_sva_image_desc , const t_sva_dc_algo_configuration_params *);
-+PUBLIC t_sva_error    sva_DC_H264_GetMemoryNeeds( t_sva_service_instance_num , t_size *);
-+PUBLIC t_sva_error    sva_DC_H264_ProvideMemoryNeeds(t_sva_service_instance_num );
-+PUBLIC t_sva_error  sva_DC_H264_CreateAndConfigSubtasksList(t_sva_service_instance_num, t_sva_service_id);
-+PUBLIC t_sva_error    sva_DC_H264_Close(t_sva_service_instance_num );
-+PUBLIC t_sva_error    sva_DC_H264_InitHeaderInfos(t_sva_service_instance_num );
-+PUBLIC t_sva_error    sva_DC_H264_SetHeaderInfos(t_sva_service_instance_num , t_sva_service_id ,t_sva_buffer_id, t_uint32, t_uint32, const t_sva_header_infos *) ;
-+PUBLIC t_sva_error    sva_DC_H264_AssertEndOfBitstream(t_sva_service_instance_num , t_sva_service_id ) ;
-+PUBLIC t_sva_error    sva_DC_H264_Push(t_sva_service_instance_num , t_sva_buffer_type , t_sva_buffer_id ) ;
-+PUBLIC t_sva_error    sva_DC_H264_DispatchEOT(t_sva_service_instance_num ,t_sva_tm_subtask_id , t_sva_event_desc* ,t_sva_service_id ,t_uint32 , t_uint32 ,t_uint32 *,t_uint32 ,t_sva_buffer_list_id);
-+PUBLIC t_sva_error    sva_DC_H264_HandleFakeEvent(    t_sva_tm_virtual_hw_event_id ,
-+                                                                                          t_sva_service_id ,
-+                                                                                          t_sva_tm_subtask_id ,
-+                                                                                          t_uint32 ,
-+                                                                                          t_uint32 ,
-+                                                                                          t_uint8 ,
-+                                                                                          t_uint32 *,
-+                                                                                          t_sva_event_desc *);
-+PUBLIC t_sva_error    sva_DC_H264_ResolveDependencies(t_sva_service_instance_num  );
-+PUBLIC t_bool sva_DC_H264_CheckInputDep(t_sva_service_instance_num);
-+PUBLIC t_bool sva_DC_H264_CheckOutputDep(t_sva_service_instance_num);
-+
-+
-+/* not usefull but needed to be existing */
-+
-+PUBLIC t_sva_error sva_DC_H264_FlushBitstreams(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_GetLastErrorType (t_sva_service_instance_num, t_uint16 *);
-+PUBLIC t_sva_error sva_DC_H264_FlushFifos(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_DeleteFake(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_SetOutputParams(t_sva_service_instance_num, const t_sva_dc_algo_params_out *);
-+PUBLIC t_size sva_DC_H264_GetOutputParamsSize(t_sva_service_instance_num);
-+PUBLIC t_sva_error sva_DC_H264_GetParamsBufferSize(t_sva_service_instance_num, t_sva_push_mode, t_sva_filter_mode, t_uint32, t_uint32, t_size *);
-+PUBLIC t_sva_h264_dpb_error sva_DC_H264_DPB_InitInstance(t_sva_service_instance_num instanceNum);
-+
-+
-+
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif        /* __cplusplus */
-+
-+
-+
-+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h    2008-07-17 16:45:04.000000000 +0530
-@@ -0,0 +1,156 @@
-+/*---------------------------------------------------------------------------*/
-+/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
-+/* information, STMicroelectronics reserves the right to license this        */
-+/*  software concurrently under separate license conditions.                 */
-+/*                                                                           */
-+/* This program 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.                                     */
-+/*                                                                           */
-+/* 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 Lesser General Public License for more details.                   */
-+/*                                                                           */
-+/* You should have received a copy of the GNU Lesser General Public License  */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVA_DC_H264_P_H
-+#define __INC_SVA_DC_H264_P_H
-+
-+#include "hcl_defs.h"
-+#include "sva_service.h"
-+#include "sva.h"
-+
-+#ifdef        __cplusplus
-+extern "C" {
-+#endif /* __cplusplus */
-+
-+
-+/* enum error : remains internal, used for debug */
-+typedef enum
-+{
-+      SVA_DC_H264_DPB_START_PICTURELOSS_NOT_SUPPORTED,
-+      SVA_DC_H264_DPB_START_MISSING_BUFFER_ERROR,
-+      SVA_DC_H264_DPB_START_ERROR,
-+      SVA_DC_H264_DPB_END_ERROR,
-+      SVA_DC_H264_DPB_PUSH_ERROR,
-+      SVA_DC_H264_PARAMIN_ERROR,
-+      SVA_DC_H264_LIST0_ERROR
-+}t_sva_dc_h264_error;
-+
-+
-+
-+typedef struct
-+{
-+      t_uint16 non_zero;
-+      t_uint16 BKType;
-+      t_sint16 mv[2];
-+}t_sva_h264_block4x4_info;
-+/* from t_block_info structure from ref code */
-+
-+typedef struct
-+{
-+    t_sint16 nslice;  /* -1 not decoded */
-+    t_uint16 concealed;
-+    t_uint16 QP[2];
-+    t_uint16 reserved1;
-+    t_uint16 reserved2;
-+    t_uint16 reserved3;
-+    t_uint16 reserved4;
-+    t_sva_h264_block4x4_info block4x4Info[16];
-+} t_sva_h264_mblock_info;
-+
-+
-+/* from tps_h4d_param structure from ref code: */
-+typedef struct
-+{
-+    unsigned _0 : 2;  unsigned A_l : 6;
-+    unsigned _1 : 2;  unsigned B_l : 6;
-+    unsigned _2 : 2;  unsigned A_c : 6;
-+    unsigned _3 : 2;  unsigned B_c : 6;
-+
-+} t_sva_h264_ab_index;
-+
-+
-+
-+typedef struct
-+{
-+    unsigned _0 : 2;  unsigned h0 : 3; unsigned v0 : 3;
-+    unsigned _1 : 2;  unsigned h1 : 3; unsigned v1 : 3;
-+    unsigned _2 : 2;  unsigned h2 : 3; unsigned v2 : 3;
-+    unsigned _3 : 2;  unsigned h3 : 3; unsigned v3 : 3;
-+
-+} t_sva_h264_strength;
-+
-+
-+
-+typedef struct
-+{
-+    t_sva_h264_ab_index     index[3];
-+    t_uint32                  loc;
-+    t_sva_h264_strength     bs[4];
-+
-+} t_sva_h264_h4d_param;
-+
-+
-+
-+
-+/* descriptor of internal variable*/
-+typedef struct{
-+      t_sva_codec_mode codecMode;
-+      t_uint16 picWidthInMbsMinus1;
-+      t_uint16 picHeightInMapUnitsMinus1;
-+      t_sva_video_decoder_algo_h264_configuration_params staticParams;
-+
-+      t_sva_dc_fifo_dep slicesDescBlockIdFifo; //BlockId Fifo
-+      t_sva_dc_fifo_dep sliceMapFifo; //Fifo of t_sva_h264_slicemap
-+
-+      /* vdc_internal_buf */
-+      t_size blockInfoSize;
-+      t_sva_block_id blockInfoId[SUBTASK_DEFAULT_NUMBER];
-+      t_system_address blockInfoAddr[SUBTASK_DEFAULT_NUMBER];
-+      t_sva_block_id blockSliceMapId[SUBTASK_DEFAULT_NUMBER];
-+      t_system_address blockSliceMapAddr[SUBTASK_DEFAULT_NUMBER];
-+      t_sva_block_id blockH4DId[SUBTASK_DEFAULT_NUMBER];
-+      t_system_address blockH4DAddr[SUBTASK_DEFAULT_NUMBER];
-+      /* vdc_frame_buf_out : addr_deblocking_param_buffer */
-+      t_sva_block_id blockDeblockId;
-+      t_system_address blockDeblockAddr;
-+
-+
-+      /* vdc_h264_slice */
-+      t_sva_block_id blockSlicesId[SUBTASK_DEFAULT_NUMBER];
-+      t_system_address blockSlicesAddr[SUBTASK_DEFAULT_NUMBER];
-+      t_uint32 currentNbSlices;
-+      t_sva_dc_h264_error h264Error;
-+
-+
-+      t_sva_h264_dpb_sps_utils spsForDpb;
-+      t_sva_h264_dpb_slice0_utils slice0ForDpb;
-+
-+
-+
-+#ifdef __DEBUG
-+      t_uint32 dbgSliceCounter;
-+      t_uint32 dbgSliceIndex;
-+      //t_sva_vdc_h264_slice slicesTrace[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_SLICESPERFRAME];
-+      t_uint32 dbgNbEvent;
-+      t_sva_event_desc eventTraces[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_EVENTS];
-+#endif
-+
-+      t_bool isToDo;
-+      t_sva_h264_slicemap_info sliceMap;
-+}t_sva_h264_desc;
-+
-+
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif        /* __cplusplus */
-+
-+
-+
-+#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c    2008-07-17 16:45:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.c
 @@ -0,0 +1,312 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -62108,9 +62775,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h2
 +        p_mb_slice_map[i] = pSliceMapBuildInfo->sliceGroupId[i];
 +
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h    2008-07-17 16:45:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264_slicemap.h
 @@ -0,0 +1,53 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -62165,9 +62831,167 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h2
 +#endif        /* __cplusplus */
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c   2008-07-17 16:45:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/h264/sva_dc_h264p.h
+@@ -0,0 +1,156 @@
++/*---------------------------------------------------------------------------*/
++/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
++/* information, STMicroelectronics reserves the right to license this        */
++/*  software concurrently under separate license conditions.                 */
++/*                                                                           */
++/* This program 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.                                     */
++/*                                                                           */
++/* 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 Lesser General Public License for more details.                   */
++/*                                                                           */
++/* You should have received a copy of the GNU Lesser General Public License  */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVA_DC_H264_P_H
++#define __INC_SVA_DC_H264_P_H
++
++#include "hcl_defs.h"
++#include "sva_service.h"
++#include "sva.h"
++
++#ifdef        __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++
++/* enum error : remains internal, used for debug */
++typedef enum
++{
++      SVA_DC_H264_DPB_START_PICTURELOSS_NOT_SUPPORTED,
++      SVA_DC_H264_DPB_START_MISSING_BUFFER_ERROR,
++      SVA_DC_H264_DPB_START_ERROR,
++      SVA_DC_H264_DPB_END_ERROR,
++      SVA_DC_H264_DPB_PUSH_ERROR,
++      SVA_DC_H264_PARAMIN_ERROR,
++      SVA_DC_H264_LIST0_ERROR
++}t_sva_dc_h264_error;
++
++
++
++typedef struct
++{
++      t_uint16 non_zero;
++      t_uint16 BKType;
++      t_sint16 mv[2];
++}t_sva_h264_block4x4_info;
++/* from t_block_info structure from ref code */
++
++typedef struct
++{
++    t_sint16 nslice;  /* -1 not decoded */
++    t_uint16 concealed;
++    t_uint16 QP[2];
++    t_uint16 reserved1;
++    t_uint16 reserved2;
++    t_uint16 reserved3;
++    t_uint16 reserved4;
++    t_sva_h264_block4x4_info block4x4Info[16];
++} t_sva_h264_mblock_info;
++
++
++/* from tps_h4d_param structure from ref code: */
++typedef struct
++{
++    unsigned _0 : 2;  unsigned A_l : 6;
++    unsigned _1 : 2;  unsigned B_l : 6;
++    unsigned _2 : 2;  unsigned A_c : 6;
++    unsigned _3 : 2;  unsigned B_c : 6;
++
++} t_sva_h264_ab_index;
++
++
++
++typedef struct
++{
++    unsigned _0 : 2;  unsigned h0 : 3; unsigned v0 : 3;
++    unsigned _1 : 2;  unsigned h1 : 3; unsigned v1 : 3;
++    unsigned _2 : 2;  unsigned h2 : 3; unsigned v2 : 3;
++    unsigned _3 : 2;  unsigned h3 : 3; unsigned v3 : 3;
++
++} t_sva_h264_strength;
++
++
++
++typedef struct
++{
++    t_sva_h264_ab_index     index[3];
++    t_uint32                  loc;
++    t_sva_h264_strength     bs[4];
++
++} t_sva_h264_h4d_param;
++
++
++
++
++/* descriptor of internal variable*/
++typedef struct{
++      t_sva_codec_mode codecMode;
++      t_uint16 picWidthInMbsMinus1;
++      t_uint16 picHeightInMapUnitsMinus1;
++      t_sva_video_decoder_algo_h264_configuration_params staticParams;
++
++      t_sva_dc_fifo_dep slicesDescBlockIdFifo; //BlockId Fifo
++      t_sva_dc_fifo_dep sliceMapFifo; //Fifo of t_sva_h264_slicemap
++
++      /* vdc_internal_buf */
++      t_size blockInfoSize;
++      t_sva_block_id blockInfoId[SUBTASK_DEFAULT_NUMBER];
++      t_system_address blockInfoAddr[SUBTASK_DEFAULT_NUMBER];
++      t_sva_block_id blockSliceMapId[SUBTASK_DEFAULT_NUMBER];
++      t_system_address blockSliceMapAddr[SUBTASK_DEFAULT_NUMBER];
++      t_sva_block_id blockH4DId[SUBTASK_DEFAULT_NUMBER];
++      t_system_address blockH4DAddr[SUBTASK_DEFAULT_NUMBER];
++      /* vdc_frame_buf_out : addr_deblocking_param_buffer */
++      t_sva_block_id blockDeblockId;
++      t_system_address blockDeblockAddr;
++
++
++      /* vdc_h264_slice */
++      t_sva_block_id blockSlicesId[SUBTASK_DEFAULT_NUMBER];
++      t_system_address blockSlicesAddr[SUBTASK_DEFAULT_NUMBER];
++      t_uint32 currentNbSlices;
++      t_sva_dc_h264_error h264Error;
++
++
++      t_sva_h264_dpb_sps_utils spsForDpb;
++      t_sva_h264_dpb_slice0_utils slice0ForDpb;
++
++
++
++#ifdef __DEBUG
++      t_uint32 dbgSliceCounter;
++      t_uint32 dbgSliceIndex;
++      //t_sva_vdc_h264_slice slicesTrace[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_SLICESPERFRAME];
++      t_uint32 dbgNbEvent;
++      t_sva_event_desc eventTraces[SVA_DC_H264_MAX_DBG_DEPTH][SVA_DC_H264_MAX_DBG_EVENTS];
++#endif
++
++      t_bool isToDo;
++      t_sva_h264_slicemap_info sliceMap;
++}t_sva_h264_desc;
++
++
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif        /* __cplusplus */
++
++
++
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.c
 @@ -0,0 +1,2126 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -64295,9 +65119,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_m
 +}
 +
 +// End of file - sva_dc_Mpeg2.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h   2008-07-17 16:45:06.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2.h
 @@ -0,0 +1,181 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -64480,9 +65303,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_m
 +
 +#endif /* __INC_sva_DC_Mpeg2_H */
 +/* End of file - sva_dc_mpeg2.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c  2008-07-17 16:45:07.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.c
 @@ -0,0 +1,789 @@
 +//*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -65273,9 +66095,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_m
 +    return SVA_OK;
 +}
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h  2008-07-17 16:45:08.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_mpeg2p.h
 @@ -0,0 +1,35 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -65312,9 +66133,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg2/sva_dc_m
 +PUBLIC t_sva_error sva_DC_Mpeg2_GetStartCodeValue ( t_uint32 * );
 +PUBLIC t_sva_error sva_DC_Mpeg2_SetupParamInOut(t_sva_service_instance_num,t_sva_tm_subtask_id);
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c   2008-11-24 14:06:25.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.c
 @@ -0,0 +1,2211 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -66180,7 +67000,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_m
 +    }
 +
 +    SVA_FreeBuffer(mp4Desc[instanceNum].lastFwdRefImageBufferId);
-+      
++
 +    DELETE_FIFO(mp4Desc[instanceNum].fakeBitstreamFifo);
 +
 +      return SVA_OK;
@@ -67527,9 +68347,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_m
 +}
 +
 +// End of file - sva_dc_mpeg4.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h   2008-07-17 16:45:09.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4.h
 @@ -0,0 +1,170 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -67701,9 +68520,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_m
 +
 +#endif /* __INC_sva_DC_MP4_H */
 +/* End of file - sva_dc_mpeg4.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c  2008-07-17 16:45:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.c
 @@ -0,0 +1,686 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -68391,9 +69209,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_m
 +
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h  2008-07-17 16:45:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_mpeg4p.h
 @@ -0,0 +1,35 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -68430,9 +69247,30 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/mpeg4/sva_dc_m
 +
 +#endif
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h  2008-07-17 16:44:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h
+@@ -0,0 +1,18 @@
++/*---------------------------------------------------------------------------*/
++/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
++/* information, STMicroelectronics reserves the right to license this        */
++/*  software concurrently under separate license conditions.                 */
++/*                                                                           */
++/* This program 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.                                     */
++/*                                                                           */
++/* 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 Lesser General Public License for more details.                   */
++/*                                                                           */
++/* You should have received a copy of the GNU Lesser General Public License  */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
++/*---------------------------------------------------------------------------*/
+\ No newline at end of file
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h
 @@ -0,0 +1,135 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -68569,9 +69407,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_dc_algo.h
 +
 +#endif /* __INC_SVA_DC_ALGO_H */
 +/* End of file - sva_dc_algo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c   2008-07-17 16:44:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c
 @@ -0,0 +1,2357 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -70930,9 +71767,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.c .
 +
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h   2008-07-17 16:44:56.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h
 @@ -0,0 +1,97 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -71031,9 +71867,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decode.h .
 +
 +#endif /* __INC_SVA_DECODE_H */
 +/* End of file - sva_decode.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c  2008-07-17 16:44:57.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c
 @@ -0,0 +1,655 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -71690,9 +72525,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.c
 +    return SVA_DC_OK;
 +
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h  2008-07-17 16:44:57.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h
 @@ -0,0 +1,364 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -72058,9 +72892,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodep.h
 +
 +#endif /* __INC_SVA_DECODEP_H */
 +/* End of file - sva_decodeP.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h 2008-07-17 16:44:58.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h
 @@ -0,0 +1,40 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -72102,32 +72935,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva_decodepp.h
 +#endif        /* __cplusplus */
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/sva.h  2008-07-17 16:44:54.000000000 +0530
-@@ -0,0 +1,18 @@
-+/*---------------------------------------------------------------------------*/
-+/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
-+/* information, STMicroelectronics reserves the right to license this        */
-+/*  software concurrently under separate license conditions.                 */
-+/*                                                                           */
-+/* This program 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.                                     */
-+/*                                                                           */
-+/* 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 Lesser General Public License for more details.                   */
-+/*                                                                           */
-+/* You should have received a copy of the GNU Lesser General Public License  */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
-+/*---------------------------------------------------------------------------*/
-\ No newline at end of file
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c       2008-07-17 16:45:11.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.c
 @@ -0,0 +1,2044 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -74173,9 +74982,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1
 +}
 +
 +// End of file - sva_dc_vc1.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h       2008-07-17 16:45:12.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1.h
 @@ -0,0 +1,194 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -74371,9 +75179,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1
 +
 +#endif /* __INC_sva_DC_VC1_H */
 +/* End of file - sva_dc_mpeg4.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c      2008-07-17 16:45:13.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.c
 @@ -0,0 +1,714 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -75089,9 +75896,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1
 +    return SVA_OK;
 +}
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h      2008-07-17 16:45:13.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1p.h
 @@ -0,0 +1,37 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -75130,9 +75936,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/decode/vc1/sva_dc_vc1
 +//PUBLIC t_sva_error sva_DC_VC1_SubTaskFieldsFullUpdate (t_sva_service_instance_num , t_sva_buffer_id *);
 +//PUBLIC t_sva_error     sva_DC_VC1_TryToInitBitstreamFields(t_uint8 ,t_sva_buffer_id *);
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c 2008-07-17 16:44:51.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c
 @@ -0,0 +1,5661 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -80795,9 +81600,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.c
 +      sva_MM_GetBlockSystemAddress(pDesc->tempBlockId, pAddr);
 +
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h 2008-07-17 16:44:53.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h
 @@ -0,0 +1,99 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -80898,9 +81702,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_display.h
 +#endif        /* __cplusplus */
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h        2008-07-17 16:44:54.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.h
 @@ -0,0 +1,424 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -81326,9 +82129,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/display/sva_displayp.
 +
 +#endif /* __INC_SVA_DISPLAYP_H */
 +/* End of file - sva_displayp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c  2008-07-17 16:44:43.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c
 @@ -0,0 +1,3648 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -84978,9 +85780,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.c
 +}
 +
 + /* End of file - sva_brc.c */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h  2008-07-17 16:44:44.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h
 @@ -0,0 +1,112 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -85094,9 +85895,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brc.h
 +
 +#endif /* __INC_SVA_BRC_H */
 +/* End of file - sva_brc.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h 2008-07-17 16:44:45.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h
 @@ -0,0 +1,262 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -85360,9 +86160,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/brc/sva_brcp.h
 +
 +#endif /* __INC_SVA_BRCP_H */
 +/* End of file - sva_brcp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c     2008-07-17 16:44:46.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.c
 @@ -0,0 +1,4739 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -90103,9 +90902,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h2
 +
 +/* End of file - sva_ec_h264.c */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h     2008-07-17 16:44:47.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264.h
 @@ -0,0 +1,79 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -90186,9 +90984,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h2
 +
 +/* End of file - sva_ec_h264.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h    2008-07-17 16:44:48.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h264p.h
 @@ -0,0 +1,646 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -90836,9 +91633,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/h264/sva_ec_h2
 +
 +/* End of file - sva_ec_h264p.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c   2008-07-17 16:44:49.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.c
 @@ -0,0 +1,2556 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -93396,9 +94192,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_m
 +
 +/* End of file - sva_ec_mpeg4.c */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h   2008-07-17 16:44:50.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4.h
 @@ -0,0 +1,69 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -93469,9 +94264,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_m
 +
 +#endif /* __INC_SVA_EC_MP4_H */
 +/* End of file - sva_ec_mpeg4.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h  2008-07-17 16:44:50.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_mpeg4p.h
 @@ -0,0 +1,246 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -93719,9 +94513,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/mpeg4/sva_ec_m
 +#endif /* __INC_SVA_EC_MP4P_H */
 +/* End of file - sva_ec_mpeg4p.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h  2008-07-17 16:44:39.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h
 @@ -0,0 +1,187 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -93910,9 +94703,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_ec_algo.h
 +
 +#endif /* __INC_SVA_EC_ALGO_H */
 +/* End of file - sva_ec_algo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c   2008-07-17 16:44:40.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c
 @@ -0,0 +1,4594 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -98508,9 +99300,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.c .
 +
 +    return TRUE;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h   2008-07-17 16:44:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h
 @@ -0,0 +1,90 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -98602,9 +99393,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encode.h .
 +
 +#endif /* __INC_SVA_ENCODE_H */
 +/* End of file - sva_encode.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h  2008-07-17 16:44:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h
 @@ -0,0 +1,340 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -98946,9 +99736,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/encode/sva_encodep.h
 +#endif /* __INC_SVA_ENCODEP_H */
 +/* End of file - sva_encodep.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c      2008-07-17 16:44:36.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.c
 @@ -0,0 +1,896 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -99846,9 +100635,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva
 +
 +    return SVA_OK;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h      2008-07-17 16:44:37.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgt.h
 @@ -0,0 +1,97 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -99947,9 +100735,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva
 +
 +#endif /* __INC_SVA_EM_H */
 +/* End of file - sva_eventmgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h     2008-07-17 16:44:38.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_eventmgtp.h
 @@ -0,0 +1,84 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -100035,9 +100822,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva
 +#endif /* __INC_SVA_EMP_H */
 +/* End of file - sva_eventmgtp.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c        2008-07-17 16:44:38.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.c
 @@ -0,0 +1,225 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -100264,9 +101050,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva
 +
 +
 +/* End of irqMgt.c */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h        2008-07-17 16:44:39.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva_irqmgt.h
 @@ -0,0 +1,42 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -100310,9 +101095,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/events_management/sva
 +#endif /* __INC_SVA_IM_H */
 +/* End of file - sva_irqmgt.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c       2008-07-17 16:44:34.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.c
 @@ -0,0 +1,1907 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -102221,9 +103005,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/s
 +
 +/* END of sva_fwmgt.c */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h       2008-07-17 16:44:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgt.h
 @@ -0,0 +1,180 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -102405,9 +103188,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/s
 +
 +#endif /* __INC_SVA_FM_H */
 +/* End of file - sva_fwmgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h      2008-07-17 16:44:36.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/sva_fwmgtp.h
 @@ -0,0 +1,304 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -102713,9 +103495,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/firmware_management/s
 +
 +#endif /* __INC_SVA_FM_P_H */
 +/* End of file - sva_fwmgtp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c       2008-07-17 16:44:31.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c
 @@ -0,0 +1,3810 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -106527,9 +107308,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.c ../ne
 +}
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h       2008-07-17 16:44:33.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h
 @@ -0,0 +1,88 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -106619,9 +107399,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grab.h ../ne
 +
 +#endif /* __INC_SVA_GRAB_H */
 +/* End of file - sva_grab.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h      2008-07-17 16:44:34.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h
 @@ -0,0 +1,411 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107034,9 +107813,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/grab/sva_grabp.h ../n
 +
 +#endif /* __INC_SVA_GRABP_H */
 +/* End of file - sva_grabP.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h   2008-07-17 16:44:18.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlistmgt.h
 @@ -0,0 +1,87 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107125,9 +107903,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_bufferlis
 +#endif /* __INC_SVA_BUFFERLISTMGT_H */
 +// End of file - sva_bufferlistmgt.h
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h       2008-07-17 16:44:18.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt.h
 @@ -0,0 +1,111 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107240,9 +108017,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_buffermgt
 +
 +#endif /* __INC_SVA_BM_H */
 +/* End of file - sva_bufferMgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h    2008-07-17 16:44:19.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilities.h
 @@ -0,0 +1,46 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107290,9 +108066,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_capabilit
 +
 +#endif /* __INC_HV_CAPABILITIES_H */
 +/* End of file - sva_capabilities.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h        2008-07-17 16:44:19.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.h
 @@ -0,0 +1,181 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107475,9 +108250,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_dc_mpeg2.
 +
 +#endif /* __INC_sva_DC_Mpeg2_H */
 +/* End of file - sva_dc_mpeg2.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h  2008-07-17 16:44:20.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h
 @@ -0,0 +1,97 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107576,9 +108350,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_decode.h
 +
 +#endif /* __INC_SVA_DECODE_H */
 +/* End of file - sva_decode.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h 2008-07-17 16:44:20.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h
 @@ -0,0 +1,99 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107679,9 +108452,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_display.h
 +#endif        /* __cplusplus */
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h  2008-07-17 16:44:20.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h
 @@ -0,0 +1,90 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107773,9 +108545,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_encode.h
 +
 +#endif /* __INC_SVA_ENCODE_H */
 +/* End of file - sva_encode.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h        2008-07-17 16:44:21.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.h
 @@ -0,0 +1,97 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -107874,9 +108645,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_eventmgt.
 +
 +#endif /* __INC_SVA_EM_H */
 +/* End of file - sva_eventmgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h    2008-07-17 16:44:21.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h
 @@ -0,0 +1,335 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -108213,9 +108983,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fifo.h ..
 +
 +#endif /* __INC_SVA_FIFO_H */
 +/* End of file - sva_fifo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h   2008-07-17 16:44:22.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h
 @@ -0,0 +1,180 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -108397,9 +109166,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_fwmgt.h .
 +
 +#endif /* __INC_SVA_FM_H */
 +/* End of file - sva_fwmgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h    2008-07-17 16:44:22.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h
 @@ -0,0 +1,89 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -108490,9 +109258,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_grab.h ..
 +
 +#endif /* __INC_SVA_GRAB_H */
 +/* End of file - sva_grab.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h  2008-07-17 16:44:23.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_interface.h
 @@ -0,0 +1,290 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -108784,9 +109551,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_host_inte
 +#endif /* _SVA_HOST_INTERFACE_H_ */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h   2008-07-17 16:44:23.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internalneeds.h
 @@ -0,0 +1,60 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -108848,9 +109614,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_internaln
 +
 +#endif /* __INC_SVA_IN_H */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h  2008-07-17 16:44:24.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h
 @@ -0,0 +1,42 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -108894,9 +109659,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_irqmgt.h
 +#endif /* __INC_SVA_IM_H */
 +/* End of file - sva_irqmgt.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h       2008-07-17 16:44:24.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt.h
 @@ -0,0 +1,163 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -109061,9 +109825,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_memorymgt
 +
 +#endif /* __INC_HV_MM_H */
 +/* End of file - sva_memorymgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h     2008-07-17 16:44:25.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservice.h
 @@ -0,0 +1,62 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -109127,9 +109890,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservi
 +} t_sva_open_service_methods;
 +
 +#endif /* __INC_OPENSERVICE_H */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h  2008-07-17 16:44:25.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservicemgt.h
 @@ -0,0 +1,71 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -109202,206 +109964,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_openservi
 +
 +#endif /* __INC_HV_FM_H */
 +/* End of file - hv_fwMgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h        2008-07-17 16:44:29.000000000 +0530
-@@ -0,0 +1,193 @@
-+/*---------------------------------------------------------------------------*/
-+/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
-+/* information, STMicroelectronics reserves the right to license this        */
-+/*  software concurrently under separate license conditions.                 */
-+/*                                                                           */
-+/* This program 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.                                     */
-+/*                                                                           */
-+/* 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 Lesser General Public License for more details.                   */
-+/*                                                                           */
-+/* You should have received a copy of the GNU Lesser General Public License  */
-+/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
-+/*---------------------------------------------------------------------------*/
-+
-+#ifndef __INC_SVAP_H
-+#define __INC_SVAP_H
-+
-+#include "hcl_defs.h"
-+
-+/******************************************************************************/
-+/* Constants definitions                                                      */
-+/******************************************************************************/
-+/*
-+ * Define various conditonnal compilation flags in order to include or not any SW workarounds
-+ */
-+/*#define WORK_AROUND_AHB*/
-+
-+/*
-+ * Define the maximum number of error defined per module
-+ */
-+#define SVA_MODULE_ERROR_RANGE        0x20
-+
-+/*
-+ * Define an Id related to each module of the SVA HCL
-+ * The Id = 1 is reserved for SVA HCL itself
-+ */
-+typedef enum {
-+      SVA_EM_ID       = 2,    /* Events Mgt */
-+      SVA_MM_ID,              /* Memory Mgt */
-+      SVA_BM_ID,              /* Buffers Mgt */
-+      SVA_BLM_ID,             /* Buffers ListMgt */
-+      SVA_TM_ID,              /* Tasks Mgt */
-+      SVA_FM_ID,              /* Firmware Mgt */
-+      SVA_TI_ID,              /* Time Mgt */
-+      SVA_VP_ID,              /* Video Pipeline */
-+      SVA_FF_ID,               /* FIFO macros */
-+      SVA_IN_ID,               /* Internal Needs Mgt */
-+      SVA_SV_ID,               /* Common Service */
-+      SVA_DP_ID,              /* Display Service */
-+      SVA_DC_ID,              /* Decode Service */
-+      SVA_EC_ID,              /* Encode Service */
-+      SVA_GB_ID,              /* Grab Service */
-+      SVA_DC_ERC_ID,          /* Decode Error Concealment */
-+      SVA_DC_MP4_ID,          /* Decode MPEG4 Algo */
-+      SVA_DC_H263_ID,         /* Decode H263 Algo */
-+      SVA_DC_H264_ID,         /* Decode H263 Algo */
-+      SVA_EC_BRC_ID,          /* Encode Bit Rate Control */
-+      SVA_EC_MP4_ID,          /* Encode MPEG4 Algo */
-+      SVA_EC_H263_ID,         /* Encode H263 Algo */
-+      SVA_EC_H264_ID,         /* Encode H264 Algo */
-+      SVA_EC_STAB_ID,         /* Encode Stabilization */
-+      SVA_SEC_JPEG_ID,                /* Still Encode JPEG ALgo */
-+      SVA_SEC_ID,                             /* still Encode service */
-+      SVA_TV_ID           /* TVO Service */
-+} sva_module_id;
-+
-+/* ************************** CONFIGURATION PART ************************** */
-+
-+
-+//typedef t_uint32 t_sva_fw_id;
-+
-+
-+typedef struct {
-+      t_uint32 cfg_psa;       /* Subtask parameter Start Address register */
-+      t_uint32 cfg_pea;       /* Subtask parameter Stop Address register */
-+      t_uint32 cfg_ice;       /* Idle Cycle Enable register */
-+      t_uint32 cfg_csc;   /* CCP synchronization codes register */
-+      t_uint32 cfg_cgc;   /* clock gating control register */
-+      t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
-+      t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
-+      t_uint32 cfg_irp_rw; /* status of the current rw operation */
-+      t_uint32 cfg_irp_error; /* error code */
-+      t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
-+      t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
-+      t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
-+      t_uint32 cfg_clk;       /* Clock generation register */
-+      t_uint32 ckg_cken; /* added*/
-+      t_uint32 cfg_tim;       /* Timer Initialization value register */
-+      t_uint32 cfg_iis;       /* IRQ1 Interrupt Status register */
-+      t_uint32 cfg_isr;       /* Global Interrupt status register */
-+      t_uint32 cfg_imr;       /* Global Interrupt mask register */
-+//    t_uint32 wasDeepSleepEntered;
-+      t_uint32 temp_idn_frv;
-+      t_uint32 fwId;
-+      t_uint32 sva_context_magic_number;
-+} t_sva_config_regs_mapping1;
-+
-+#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
-+
-+#define SVA_EM_LAST_ERROR     (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EM_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_MM_LAST_ERROR     (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_MM_FIRST_INFO     (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BM_LAST_ERROR     (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BM_FIRST_INFO     (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_BLM_LAST_ERROR    (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_BLM_FIRST_INFO    (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TM_LAST_ERROR     (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TM_FIRST_INFO     (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FM_LAST_ERROR     (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FM_FIRST_INFO     (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TI_LAST_ERROR     (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TI_FIRST_INFO     (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_FF_LAST_ERROR     (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_FF_FIRST_INFO     (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_IN_LAST_ERROR     (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_IN_FIRST_INFO     (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SV_LAST_ERROR     (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SV_FIRST_INFO     (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DP_LAST_ERROR     (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DP_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_LAST_ERROR     (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_FIRST_INFO     (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_LAST_ERROR     (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_FIRST_INFO     (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_GB_LAST_ERROR     (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_GB_FIRST_INFO     (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H263_LAST_ERROR        (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H263_FIRST_INFO        (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_DC_H264_LAST_ERROR        (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_DC_H264_FIRST_INFO        (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+
-+#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H263_LAST_ERROR        (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H263_FIRST_INFO        (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_H264_LAST_ERROR        (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_H264_FIRST_INFO        (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_EC_STAB_LAST_ERROR        (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_EC_STAB_FIRST_INFO        (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_JPEG_LAST_ERROR       (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_JPEG_FIRST_INFO       (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_SEC_LAST_ERROR    (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_SEC_FIRST_INFO    (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+#define SVA_TV_LAST_ERROR     (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
-+#define SVA_TV_FIRST_ERROR    (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
-+
-+/******************************************************************************/
-+/* Types definitions */
-+/******************************************************************************/
-+
-+#ifdef __cplusplus
-+} /* allow C++ to use these headers */
-+#endif        /* __cplusplus */
-+
-+#endif /* __INC_SVAP_H */
-+/* End of file - hvP.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h 2008-07-17 16:44:26.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h
 @@ -0,0 +1,337 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -109740,9 +110304,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_service.h
 +
 +#endif /* __INC_SVA_SERVICE_H */
 +/* End of file - SVA.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h    2008-07-17 16:44:26.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h
 @@ -0,0 +1,89 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -109833,9 +110396,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_stab.h ..
 +
 +#endif /* __INC_SVA_STAB_H */
 +/* End of file - sva_stab.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h    2008-07-17 16:44:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_decode.h
 @@ -0,0 +1,111 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -109948,9 +110510,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_dec
 +
 +#endif/* __INC_SVA_STILLDECODE_H */
 +/* End of file - sva_still_decode.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h    2008-07-17 16:44:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_encode.h
 @@ -0,0 +1,96 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -110048,9 +110609,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_still_enc
 +#endif        /* __cplusplus */
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h 2008-07-17 16:44:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h
 @@ -0,0 +1,403 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -110455,9 +111015,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_taskmgt.h
 +#endif /* __INC_SVA_TASKMGT_H */
 +/* End of file - sva_taskmgt.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h 2008-07-17 16:44:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h
 @@ -0,0 +1,80 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -110539,9 +111098,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_timemgt.h
 +
 +#endif /* __INC_SVA_TI_H */
 +/* End of file - sva_timemgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h     2008-07-17 16:44:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h
 @@ -0,0 +1,89 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -110632,9 +111190,204 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/sva_tvo.h ../
 +
 +#endif /* __INC_SVA_TVO_H */
 +/* End of file - sva_tvo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h        2008-07-17 16:44:29.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/svap.h
+@@ -0,0 +1,193 @@
++/*---------------------------------------------------------------------------*/
++/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
++/* information, STMicroelectronics reserves the right to license this        */
++/*  software concurrently under separate license conditions.                 */
++/*                                                                           */
++/* This program 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.                                     */
++/*                                                                           */
++/* 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 Lesser General Public License for more details.                   */
++/*                                                                           */
++/* You should have received a copy of the GNU Lesser General Public License  */
++/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
++/*---------------------------------------------------------------------------*/
++
++#ifndef __INC_SVAP_H
++#define __INC_SVAP_H
++
++#include "hcl_defs.h"
++
++/******************************************************************************/
++/* Constants definitions                                                      */
++/******************************************************************************/
++/*
++ * Define various conditonnal compilation flags in order to include or not any SW workarounds
++ */
++/*#define WORK_AROUND_AHB*/
++
++/*
++ * Define the maximum number of error defined per module
++ */
++#define SVA_MODULE_ERROR_RANGE        0x20
++
++/*
++ * Define an Id related to each module of the SVA HCL
++ * The Id = 1 is reserved for SVA HCL itself
++ */
++typedef enum {
++      SVA_EM_ID       = 2,    /* Events Mgt */
++      SVA_MM_ID,              /* Memory Mgt */
++      SVA_BM_ID,              /* Buffers Mgt */
++      SVA_BLM_ID,             /* Buffers ListMgt */
++      SVA_TM_ID,              /* Tasks Mgt */
++      SVA_FM_ID,              /* Firmware Mgt */
++      SVA_TI_ID,              /* Time Mgt */
++      SVA_VP_ID,              /* Video Pipeline */
++      SVA_FF_ID,               /* FIFO macros */
++      SVA_IN_ID,               /* Internal Needs Mgt */
++      SVA_SV_ID,               /* Common Service */
++      SVA_DP_ID,              /* Display Service */
++      SVA_DC_ID,              /* Decode Service */
++      SVA_EC_ID,              /* Encode Service */
++      SVA_GB_ID,              /* Grab Service */
++      SVA_DC_ERC_ID,          /* Decode Error Concealment */
++      SVA_DC_MP4_ID,          /* Decode MPEG4 Algo */
++      SVA_DC_H263_ID,         /* Decode H263 Algo */
++      SVA_DC_H264_ID,         /* Decode H263 Algo */
++      SVA_EC_BRC_ID,          /* Encode Bit Rate Control */
++      SVA_EC_MP4_ID,          /* Encode MPEG4 Algo */
++      SVA_EC_H263_ID,         /* Encode H263 Algo */
++      SVA_EC_H264_ID,         /* Encode H264 Algo */
++      SVA_EC_STAB_ID,         /* Encode Stabilization */
++      SVA_SEC_JPEG_ID,                /* Still Encode JPEG ALgo */
++      SVA_SEC_ID,                             /* still Encode service */
++      SVA_TV_ID           /* TVO Service */
++} sva_module_id;
++
++/* ************************** CONFIGURATION PART ************************** */
++
++
++//typedef t_uint32 t_sva_fw_id;
++
++
++typedef struct {
++      t_uint32 cfg_psa;       /* Subtask parameter Start Address register */
++      t_uint32 cfg_pea;       /* Subtask parameter Stop Address register */
++      t_uint32 cfg_ice;       /* Idle Cycle Enable register */
++      t_uint32 cfg_csc;   /* CCP synchronization codes register */
++      t_uint32 cfg_cgc;   /* clock gating control register */
++      t_uint32 cfg_irp_fw_addr; /* start address eWarp firmware */
++      t_uint32 cfg_irp_fw_size; /* size in bytes of eWarp firmware */
++      t_uint32 cfg_irp_rw; /* status of the current rw operation */
++      t_uint32 cfg_irp_error; /* error code */
++      t_uint32 cfg_irp_bs; /* start of circular buffer for rw packet */
++      t_uint32 cfg_irp_be; /* end of circular buffer for rw packet */
++      t_uint32 cfg_irp_ptr; /* ptr of circular buffer for rw packet */
++      t_uint32 cfg_clk;       /* Clock generation register */
++      t_uint32 ckg_cken; /* added*/
++      t_uint32 cfg_tim;       /* Timer Initialization value register */
++      t_uint32 cfg_iis;       /* IRQ1 Interrupt Status register */
++      t_uint32 cfg_isr;       /* Global Interrupt status register */
++      t_uint32 cfg_imr;       /* Global Interrupt mask register */
++//    t_uint32 wasDeepSleepEntered;
++      t_uint32 temp_idn_frv;
++      t_uint32 fwId;
++      t_uint32 sva_context_magic_number;
++} t_sva_config_regs_mapping1;
++
++#define SVA_CONTEXT_MAGIC_NUMBER 0x53415645UL
++
++#define SVA_EM_LAST_ERROR     (-(SVA_EM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EM_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_MM_LAST_ERROR     (-(SVA_MM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_MM_FIRST_INFO     (+((SVA_MM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BM_LAST_ERROR     (-(SVA_BM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BM_FIRST_INFO     (+((SVA_BM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_BLM_LAST_ERROR    (-(SVA_BLM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_BLM_FIRST_INFO    (+((SVA_BLM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TM_LAST_ERROR     (-(SVA_TM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TM_FIRST_INFO     (+((SVA_TM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FM_LAST_ERROR     (-(SVA_FM_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FM_FIRST_INFO     (+((SVA_FM_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TI_LAST_ERROR     (-(SVA_TI_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TI_FIRST_INFO     (+((SVA_TI_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_FF_LAST_ERROR     (-(SVA_FF_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_FF_FIRST_INFO     (+((SVA_FF_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_IN_LAST_ERROR     (-(SVA_IN_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_IN_FIRST_INFO     (+((SVA_IN_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SV_LAST_ERROR     (-(SVA_SV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SV_FIRST_INFO     (+((SVA_SV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DP_LAST_ERROR     (-(SVA_DP_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DP_FIRST_INFO     (+((SVA_DP_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_LAST_ERROR     (-(SVA_DC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_FIRST_INFO     (+((SVA_DC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_LAST_ERROR     (-(SVA_EC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_FIRST_INFO     (+((SVA_EC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_GB_LAST_ERROR     (-(SVA_GB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_GB_FIRST_INFO     (+((SVA_GB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_ERC_LAST_ERROR (-(SVA_DC_ERC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_ERC_FIRST_INFO (+((SVA_DC_ERC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_MP4_LAST_ERROR (-(SVA_DC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_MP4_FIRST_INFO (+((SVA_DC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H263_LAST_ERROR        (-(SVA_DC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H263_FIRST_INFO        (+((SVA_DC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_DC_H264_LAST_ERROR        (-(SVA_DC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_DC_H264_FIRST_INFO        (+((SVA_DC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++
++#define SVA_EC_BRC_LAST_ERROR (-(SVA_EC_BRC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_BRC_FIRST_INFO (+((SVA_EC_BRC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_MP4_LAST_ERROR (-(SVA_EC_MP4_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_MP4_FIRST_INFO (+((SVA_EC_MP4_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H263_LAST_ERROR        (-(SVA_EC_H263_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H263_FIRST_INFO        (+((SVA_EC_H263_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_H264_LAST_ERROR        (-(SVA_EC_H264_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_H264_FIRST_INFO        (+((SVA_EC_H264_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_EC_STAB_LAST_ERROR        (-(SVA_EC_STAB_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_EC_STAB_FIRST_INFO        (+((SVA_EC_STAB_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_JPEG_LAST_ERROR       (-(SVA_SEC_JPEG_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_JPEG_FIRST_INFO       (+((SVA_SEC_JPEG_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_SEC_LAST_ERROR    (-(SVA_SEC_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_SEC_FIRST_INFO    (+((SVA_SEC_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++#define SVA_TV_LAST_ERROR     (-(SVA_TV_ID * SVA_MODULE_ERROR_RANGE))
++#define SVA_TV_FIRST_ERROR    (+((SVA_TV_ID - 1) * SVA_MODULE_ERROR_RANGE))
++
++/******************************************************************************/
++/* Types definitions */
++/******************************************************************************/
++
++#ifdef __cplusplus
++} /* allow C++ to use these headers */
++#endif        /* __cplusplus */
++
++#endif /* __INC_SVAP_H */
++/* End of file - hvP.h */
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_interface.h
 @@ -0,0 +1,1725 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -112361,9 +113114,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_host_in
 +#endif /* _T1XHV_HOST_INTERFACE_H_ */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h      2008-07-17 16:44:31.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarget.h
 @@ -0,0 +1,41 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -112406,9 +113158,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/include/t1xhv_retarge
 +#endif /* _T1XSVA_RETARGET_H_ */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c 2008-07-17 16:44:12.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.c
 @@ -0,0 +1,541 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -112951,9 +113702,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +
 +
 +// End of file - sva_bufferlistmgt.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h 2008-07-17 16:44:13.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgt.h
 @@ -0,0 +1,87 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -113042,9 +113792,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +#endif /* __INC_SVA_BUFFERLISTMGT_H */
 +// End of file - sva_bufferlistmgt.h
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h        2008-07-17 16:44:13.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_bufferlistmgtp.h
 @@ -0,0 +1,73 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -113119,9 +113868,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +
 +#endif /* __INC_SVA_BLM_P_H */
 +/* End of file - sva_bufferlistmgtp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c     2008-07-17 16:44:14.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.c
 @@ -0,0 +1,1212 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -114335,9 +115083,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +} /* End of sva_BM_SetBuferLinkInformation() function. */
 +
 +/* End of file - sva_buffermgt.c */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h     2008-07-17 16:44:15.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgt.h
 @@ -0,0 +1,111 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -114450,9 +115197,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +
 +#endif /* __INC_SVA_BM_H */
 +/* End of file - sva_bufferMgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h    2008-07-17 16:44:15.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_buffermgtp.h
 @@ -0,0 +1,83 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -114537,9 +115283,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +
 +#endif /* __INC_SVA_BM_P_H */
 +/* End of file - sva_buffermgtp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c     2008-07-17 16:44:16.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.c
 @@ -0,0 +1,1578 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -116119,9 +116864,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +/* End of file: sva_memoryMgt.c */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h     2008-07-17 16:44:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgt.h
 @@ -0,0 +1,163 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -116286,9 +117030,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +
 +#endif /* __INC_HV_MM_H */
 +/* End of file - sva_memorymgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h    2008-07-17 16:44:17.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva_memorymgtp.h
 @@ -0,0 +1,105 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -116395,9 +117138,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/memory_management/sva
 +
 +#endif /* __INC_SVA_MM_P_H */
 +/* End of file - sva_memorymgtp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h      2008-07-17 16:44:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservice.h
 @@ -0,0 +1,62 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -116461,9 +117203,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_managemen
 +} t_sva_open_service_methods;
 +
 +#endif /* __INC_OPENSERVICE_H */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c   2008-07-17 16:44:10.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.c
 @@ -0,0 +1,620 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -117085,9 +117826,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_managemen
 +}
 +
 +// End of file - sva_openservicemgt.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h   2008-07-17 16:44:11.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgt.h
 @@ -0,0 +1,71 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -117160,9 +117900,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_managemen
 +
 +#endif /* __INC_HV_FM_H */
 +/* End of file - hv_fwMgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h  2008-07-17 16:44:11.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_management/sva_openservicemgtp.h
 @@ -0,0 +1,56 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -117220,9 +117959,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/openservice_managemen
 +
 +#endif /* __INC_SVA_ENCODEP_H */
 +/* End of file - sva_encodep.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c       2008-07-17 16:44:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c
 @@ -0,0 +1,2855 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -120079,9 +120817,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.c ../ne
 +
 +    return SVA_OK;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h       2008-07-17 16:44:06.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h
 @@ -0,0 +1,89 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -120172,9 +120909,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stab.h ../ne
 +
 +#endif /* __INC_SVA_STAB_H */
 +/* End of file - sva_stab.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h      2008-07-17 16:44:07.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h
 @@ -0,0 +1,284 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -120460,9 +121196,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/stab/sva_stabp.h ../n
 +
 +#endif /* __INC_SVA_STABP_H */
 +/* End of file - sva_stabp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c      2008-07-17 16:44:08.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.c
 @@ -0,0 +1,1047 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -121511,9 +122246,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva
 +}
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h      2008-07-17 16:44:08.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpeg.h
 @@ -0,0 +1,70 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -121585,9 +122319,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva
 +
 +#endif /* __INC_SVA_SEC_JPEG_H */
 +/* End of file - sva_sec_jpeg.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h     2008-07-17 16:44:09.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva_sdc_jpegp.h
 @@ -0,0 +1,74 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -121663,9 +122396,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/jpeg/sva
 +
 +#endif /* __INC_SVA_SDC_JPEGP_H */
 +/* End of file - sva_sdc_jpegp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h   2008-07-17 16:44:01.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_algo.h
 @@ -0,0 +1,96 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -121763,9 +122495,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_sdc_
 +
 +#endif /* __INC_SVA_SEC_ALGO_H */
 +/* End of file - sva_sec_algo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c       2008-07-17 16:44:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.c
 @@ -0,0 +1,3174 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -124941,9 +125672,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_stil
 +}
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h       2008-07-17 16:44:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decode.h
 @@ -0,0 +1,111 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -125056,9 +125786,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_stil
 +
 +#endif/* __INC_SVA_STILLDECODE_H */
 +/* End of file - sva_still_decode.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h      2008-07-17 16:44:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_still_decodep.h
 @@ -0,0 +1,267 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -125327,9 +126056,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_decode/sva_stil
 +
 +#endif /* __INC_SVA_STILLDECODEP_H */
 +/* End of file - sva_still_decodep.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c      2008-07-17 16:43:59.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.c
 @@ -0,0 +1,682 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -126013,9 +126741,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva
 +
 +/* End of file - sva_sec_jpeg.c */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h      2008-07-17 16:44:00.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpeg.h
 @@ -0,0 +1,63 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -126080,9 +126807,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva
 +
 +#endif /* __INC_SVA_SEC_JPEG_H */
 +/* End of file - sva_sec_jpeg.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h     2008-07-17 16:44:00.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva_sec_jpegp.h
 @@ -0,0 +1,62 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -126146,9 +126872,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/jpeg/sva
 +
 +#endif /* __INC_SVA_SEC_JPEGP_H */
 +/* End of file - sva_sec_jpegp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h   2008-07-17 16:43:56.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_algo.h
 @@ -0,0 +1,152 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -126302,9 +127027,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_sec_
 +
 +#endif /* __INC_SVA_SEC_ALGO_H */
 +/* End of file - sva_sec_algo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c       2008-07-17 16:43:56.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.c
 @@ -0,0 +1,3752 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -130058,9 +130782,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_stil
 +      return SVA_SEC_OK;
 +}
 +*/
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h       2008-07-17 16:43:58.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encode.h
 @@ -0,0 +1,96 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -130158,9 +130881,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_stil
 +#endif        /* __cplusplus */
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h      2008-07-17 16:43:58.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_still_encodep.h
 @@ -0,0 +1,248 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -130410,9 +131132,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/still_encode/sva_stil
 +
 +#endif /* __INC_SVA_STILLENCODEP_H */
 +/* End of file - sva_stillencodep.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c 2008-07-17 16:43:46.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c
 @@ -0,0 +1,1827 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -132241,9 +132962,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.c ../new/linux-2.
 +      return status;
 +}
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h 2008-07-17 16:43:47.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h
 @@ -0,0 +1,2148 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -134393,9 +135113,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/sva.h ../new/linux-2.
 +
 +#endif /* __INC_SVA_H */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c      2008-07-17 16:43:50.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.c
 @@ -0,0 +1,1701 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -136098,9 +136817,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +
 +
 +// End of file - sva_hwtaskmgt.c
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h      2008-07-17 16:43:51.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgt.h
 @@ -0,0 +1,93 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -136195,9 +136913,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +
 +#endif /* __INC_SVA_HW_TASKMGT_H */
 +/* End of file - sva_hwtaskmgt.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h     2008-07-17 16:43:52.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_hwtaskmgtp.h
 @@ -0,0 +1,134 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -136333,9 +137050,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +
 +#endif /* __INC_SVA_HW_TASKMGTP_H */
 +/* End of file - sva_hwtaskmgtp.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c        2008-07-17 16:43:52.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.c
 @@ -0,0 +1,3573 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -139910,9 +140626,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +
 +// End of file - sva_taskmgt.c
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h        2008-07-17 16:43:54.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgt.h
 @@ -0,0 +1,403 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -140317,9 +141032,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +#endif /* __INC_SVA_TASKMGT_H */
 +/* End of file - sva_taskmgt.h */
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h       2008-07-17 16:43:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskmgtp.h
 @@ -0,0 +1,359 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -140680,9 +141394,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +
 +#endif /* __INC_SVA_TASKMGTP_H */
 +/* End of file - hv.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c       2008-07-17 16:43:55.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_taskschl.c
 @@ -0,0 +1,19 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -140703,9 +141416,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tasks_management/sva_
 +/* along with this program. If not, see <http://www.gnu.org/licenses/>.      */
 +/*---------------------------------------------------------------------------*/
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c 2008-07-17 16:43:48.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c
 @@ -0,0 +1,2478 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -143185,9 +143897,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.c ../new/
 +
 +    return SVA_OK;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h 2008-07-17 16:43:49.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h
 @@ -0,0 +1,89 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -143278,9 +143989,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvo.h ../new/
 +
 +#endif /* __INC_SVA_TVO_H */
 +/* End of file - sva_tvo.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h
---- linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h        2008-07-17 16:43:50.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h
 @@ -0,0 +1,278 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -143560,48 +144270,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/hcl/sva/tvo/sva_tvop.h ../new
 +
 +#endif /* __INC_SVA_TVOP_H */
 +/* End of file - sva_tvop.h */
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/Kconfig ../new/linux-2.6.20/drivers/media/nomadik_mm/Kconfig
---- linux-2.6.20/drivers/media/nomadik_mm/Kconfig      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/Kconfig       2008-10-06 12:06:22.000000000 +0530
-@@ -0,0 +1,23 @@
-+#
-+# Nomadik Multimedia Audio/Video device configuration
-+#
-+
-+menu "NOMADIK Audio Video Graphic Drivers(SAA SVA and OPENGL) "
-+
-+config NOMADIK_SAA
-+      tristate "Nomadik SAA Support"
-+      depends on ARCH_NOMADIK && NOMADIK_MSP && I2C_NOMADIK
-+      ---help---
-+      Support for Nomadik SAA DSP
-+
-+config NOMADIK_SVA
-+      tristate "Nomadik SVA Support"
-+      depends on ARCH_NOMADIK && VIDEO_V4L2 && I2C_NOMADIK
-+      ---help---
-+      Support for Nomadik SVA DSP
-+
-+config NOMADIK_OGL
-+      tristate "Nomadik OGL Support"
-+      ---help---
-+      Support for Nomadik OGL DSP     
-+endmenu
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/Makefile
---- linux-2.6.20/drivers/media/nomadik_mm/Makefile     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/Makefile      2008-10-06 12:06:21.000000000 +0530
-@@ -0,0 +1,8 @@
-+#
-+# Makefile for the kernel multimedia device drivers.
-+#kefile for the kernel multimedia device drivers.
-+#
-+
-+obj-$(CONFIG_NOMADIK_SAA) += saa/
-+obj-$(CONFIG_NOMADIK_SVA) += sva/
-+obj-$(CONFIG_NOMADIK_OGL) += opengl/
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile       2008-10-07 12:20:08.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile
 @@ -0,0 +1,18 @@
 +KERNEL_PATH=./../../linux-2.6.20
 +EXTRA_CFLAGS_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
@@ -143621,9 +144291,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/Makefile ../new/linux-
 +
 +clean :
 +      $(MAKE) -C ../../linux-2.6.20 M=`pwd` clean; rm -f $(hloader_obj)
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c  2008-11-24 14:06:32.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c
 @@ -0,0 +1,565 @@
 +/*---------------------------------------------------------------------------*/\r
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */\r
@@ -144190,9 +144859,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c ../new/linux-2.6
 +\r
 +module_init(nomadik_ogles_init);\r
 +module_exit(nomadik_ogles_exit);\r
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h  2008-10-07 12:20:09.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h
 @@ -0,0 +1,65 @@
 +/*---------------------------------------------------------------------------*/\r
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */\r
@@ -144259,9 +144927,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h ../new/linux-2.6
 +MODULE_LICENSE("GPL");\r
 +MODULE_AUTHOR("Jayarami reddy <jayarami.reddy@stnwireless.com>");\r
 +MODULE_DESCRIPTION(" This module is a OGLES module !!");\r
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h
---- linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h    2008-10-07 12:20:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h
 @@ -0,0 +1,56 @@
 +/*---------------------------------------------------------------------------*/\r
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */\r
@@ -144319,17 +144986,16 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl_ioctl.h ../new/lin
 +MODULE_DESCRIPTION(" This module is a OGLES module !!");\r
 +\r
 +#endif //OGL_IOCTL_H\r
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile
---- linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile  2008-08-12 22:56:07.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile
 @@ -0,0 +1,20 @@
 +#KERNEL_PATH := ../../../../../linux-2.6.20
 +EXTRA_CFLAGS_NAME = $(shell echo $(CONFIG_NOMADIK_TARGET_EXTRA_CFLAGS))
 +EXTRA_CFLAGS  := $(EXTRA_CFLAGS_NAME) -D__arm  -I$(src)/ -I$(src)/../hcl/include/ -I$(src)/../hcl/saa/ -I$(src)/../hcl/hloader/
 +#
 +#all:
-+#     $(MAKE) -C $(KERNEL_PATH) M=`pwd` 
-+#     
++#     $(MAKE) -C $(KERNEL_PATH) M=`pwd`
++#
 +#
 +obj-$(CONFIG_NOMADIK_SAA)     += nmdkmod_SAA.o nmdkmod_fwload.o
 +
@@ -144343,9 +145009,83 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/Makefile ../new/linux-2.6
 +
 +#clean :
 +#     $(MAKE) -C $(KERNEL_PATH) M=`pwd` clean; rm ../hcl/saa/*.o ../hcl/hloader/*.o
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c
---- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c  2008-07-17 16:42:49.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/README
+@@ -0,0 +1,72 @@
++SAA driver Build
++*************************************************************
++
++SAA driver is built only as the external module.
++
++Path is : /vobs/ATS_8815_LINUX/Baseline/linux-2.6.20/drivers/media/nomadik_mm/saa
++do make in this folder. it will generate the nmdkmod_SAA.ko, nmdkmod_fwload.ko
++
++SAA driver depends on DMA, SSP, AUDIOCODEC , FWLOAD(to load firmware file) driver.
++Audiocodec driver depends on MSP and I2C.
++These driver should be compiled with kernel either as module or static as the case may be.
++These driver should be present at run time before inserting SAA driver.
++
++Audiocodec file is added as the sepearte entity in the
++kernel. Path is : "/vobs/ATS_8815_LINUX/Baseline/linux-2.6.20/sound/"
++for nhk15 file is "nomadik_stw5095.c"
++
++This module will export the functionality of nomadik stw5095 audiocodec
++to be used by the other drivers in the kernel. Presently both SAA and ALSA
++driver will use this module. To enable this module through make menuconfig, choose
++
++Device Drivers
++     -----> Sound
++        ------> Nomadik stw5095 audioc codec generic module
++
++This will make the module : $TOPDIR/sound/nmdkmod_acodec.ko
++
++
++Firmware file
++**************************************************************
++
++The firmware file required for SAA driver can be found at the path :
++/vobs/ATS_8815_LINUX/Baseline/firmware/saa/saa.mmf ( for NHK15 )
++
++This file must be put in the ramdisk at the path specified in the fwload application "exe_fwload"
++ that is "/modules/" etc.
++
++How to load SAA Driver
++**************************************************************
++
++One can use the following commands to load SAA driver:
++
++1) mkdir -p /dev/misc
++2) mknod /dev/misc/hamaca c 10 230 ( this will create the device node - SAA )
++3) mknod /dev/misc/fw_load c 10 231 ( this will create the device node - FWLOAD )
++4) insmod /modules/nmdkmod_fwload.ko
++5) insmod /modules/nmdkmod_SAA.ko
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c
 @@ -0,0 +1,229 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -144490,7 +145230,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c ../new/l
 +      fw_desc->fw_ptr = vmalloc(size);
 +      if(!fw_desc->fw_ptr) {
 +              printk("Error in vmalloc\n");
-+              return 0;       /*Zero bytes written*/  
++              return 0;       /*Zero bytes written*/
 +      }
 +      else
 +              DBG(1, "Success: vmalloc\n");
@@ -144504,7 +145244,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c ../new/l
 +
 +      up(&fw_desc->sem);
 +      complete(&fw_desc->completion);
-+      
++
 +      return fw_desc->fw_size;
 +}
 +
@@ -144538,13 +145278,13 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c ../new/l
 +              retval = -EINVAL;
 +              goto out;
 +      }
-+      
++
 +      down(&fw_desc->sem);
 +      firmware->data = fw_desc->fw_ptr;
 +      firmware->size = fw_desc->fw_size;
 +      up(&fw_desc->sem);
 +      kobject_put(&(fwload_miscdev.this_device->kobj));
-+              
++
 +      return 0;
 +out:
 +      if (firmware) {
@@ -144576,9 +145316,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.c ../new/l
 +
 +module_init(nomadik_fwload_init);
 +module_exit(nomadik_fwload_exit);
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h
---- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h  2008-07-17 16:42:49.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h
 @@ -0,0 +1,47 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -144597,7 +145336,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h ../new/l
 +/*along with this program. If not, see <http://www.gnu.org/licenses/>.                            */
 +/*--------------------------------------------------------------------------------------------------*/
 +
-+#ifndef _NOMADIK_FWLOAD_H 
++#ifndef _NOMADIK_FWLOAD_H
 +#define _NOMADIK_FWLOAD_H
 +
 +/* Debugging stuff */
@@ -144615,10 +145354,10 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h ../new/l
 +#define DBG(n, args...) do { } while (0)
 +#endif
 +
-+struct fwload_descriptor 
++struct fwload_descriptor
 +{
 +      struct semaphore        sem;
-+      char *fw_ptr;   
++      char *fw_ptr;
 +      size_t fw_size;
 +      struct completion completion;
 +};
@@ -144627,9 +145366,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-fwload.h ../new/l
 +int relfw_pointer(const struct firmware *fw_p);
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c
---- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c     2008-11-24 14:06:25.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c
 @@ -0,0 +1,4406 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -144718,7 +145456,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linu
 +#define SAA_HCL_UNLOCK(flags)   spin_unlock_irqrestore(&saa_hcl_lock,flags)
 +
 +//warning removal
-+extern void l210_flush_range(unsigned long, unsigned long); 
++extern void l210_flush_range(unsigned long, unsigned long);
 +
 +static t_uint32 saa_convert_dsptoarm_address(t_uint32 dsp_address)
 +{
@@ -148354,8 +149092,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linu
 +      logical_addr = (t_uint32) saa_get_logical_address();
 +      physical_addr = (t_uint32) saa_get_physical_address();
 +#else
-+#ifndef NOMADIK_MM_STATIC_MEM 
-+      /* allocate memory for Program + Data16 static & dynamic + Data24 static & dynamic*/    
++#ifndef NOMADIK_MM_STATIC_MEM
++      /* allocate memory for Program + Data16 static & dynamic + Data24 static & dynamic*/
 +      //printk("\nKernel Allocating Memory for Firmware");
 +      logical_addr = (t_uint32) dma_alloc_coherent(NULL, FWM_SDRAM_ALLOCATED_SIZE ,
 +                                      &physical_addr,GFP_KERNEL | GFP_DMA);
@@ -148894,14 +149632,14 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linu
 +
 +#ifndef CONFIG_NOMADIK_SAA_INIT_MEM
 +#ifndef NOMADIK_MM_STATIC_MEM
-+      //printk("\nFreeing FW Memory"); 
++      //printk("\nFreeing FW Memory");
 +      if(dram_logical_addr)
 +              dma_free_coherent(NULL,FWM_SDRAM_ALLOCATED_SIZE,(void*)dram_logical_addr,dram_physical_addr);
 +#else
 +      //printk("\n Unmappping FW Memory");
 +      if(saa_desc->fw_logical_addr)
 +              iounmap((void*)saa_desc->fw_logical_addr);
-+      
++
 +#endif
 +#endif
 +
@@ -149037,9 +149775,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.c ../new/linu
 +
 +module_init(nomadik_saa_init);
 +module_exit(nomadik_saa_exit);
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h
---- linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h     2008-10-06 12:06:21.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h
 @@ -0,0 +1,204 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -149245,85 +149982,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/nomadik-saa.h ../new/linu
 +#endif                /* _NOMADIK-SAA_H_*/
 +
 +/* End of file nomadik-saa.h*/
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/README ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/README
---- linux-2.6.20/drivers/media/nomadik_mm/saa/README   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/README    2008-07-17 16:43:15.000000000 +0530
-@@ -0,0 +1,72 @@
-+SAA driver Build
-+*************************************************************
-+
-+SAA driver is built only as the external module.
-+
-+Path is : /vobs/ATS_8815_LINUX/Baseline/linux-2.6.20/drivers/media/nomadik_mm/saa
-+do make in this folder. it will generate the nmdkmod_SAA.ko, nmdkmod_fwload.ko
-+
-+SAA driver depends on DMA, SSP, AUDIOCODEC , FWLOAD(to load firmware file) driver.
-+Audiocodec driver depends on MSP and I2C.
-+These driver should be compiled with kernel either as module or static as the case may be.
-+These driver should be present at run time before inserting SAA driver.
-+
-+Audiocodec file is added as the sepearte entity in the 
-+kernel. Path is : "/vobs/ATS_8815_LINUX/Baseline/linux-2.6.20/sound/"
-+for nhk15 file is "nomadik_stw5095.c"
-+
-+This module will export the functionality of nomadik stw5095 audiocodec
-+to be used by the other drivers in the kernel. Presently both SAA and ALSA
-+driver will use this module. To enable this module through make menuconfig, choose
-+
-+Device Drivers
-+     -----> Sound
-+        ------> Nomadik stw5095 audioc codec generic module
-+
-+This will make the module : $TOPDIR/sound/nmdkmod_acodec.ko
-+
-+
-+Firmware file
-+**************************************************************
-+
-+The firmware file required for SAA driver can be found at the path :
-+/vobs/ATS_8815_LINUX/Baseline/firmware/saa/saa.mmf ( for NHK15 )
-+
-+This file must be put in the ramdisk at the path specified in the fwload application "exe_fwload" 
-+ that is "/modules/" etc.
-+
-+How to load SAA Driver 
-+**************************************************************
-+
-+One can use the following commands to load SAA driver:
-+
-+1) mkdir -p /dev/misc
-+2) mknod /dev/misc/hamaca c 10 230 ( this will create the device node - SAA )
-+3) mknod /dev/misc/fw_load c 10 231 ( this will create the device node - FWLOAD )
-+4) insmod /modules/nmdkmod_fwload.ko
-+5) insmod /modules/nmdkmod_SAA.ko
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h
---- linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h        2008-07-17 16:42:51.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h
 @@ -0,0 +1,498 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -149380,9 +150040,9 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +*******************************************************************/
 +
 +typedef t_saa_block_id                        saa_block_id;
-+typedef t_saa_block_type              saa_block_type; 
++typedef t_saa_block_type              saa_block_type;
 +typedef t_saa_port_type               saa_port_type;
-+typedef t_saa_port_data_type          saa_port_data_type ; 
++typedef t_saa_port_data_type          saa_port_data_type ;
 +typedef t_saa_endianess_type          saa_endianess_type;
 +typedef t_saa_sample_channel_nb       saa_sample_channel_nb;
 +typedef t_saa_sample_interleaving_type        saa_sample_interleaving_type;
@@ -149431,7 +150091,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +              unsigned char           mix_with_playback;
 +              saa_codec_tone_wave     waveShape;
 +              unsigned long*          reserved2;
-+              
++
 +} saa_codec_tonegenerator_struct;
 +
 +/* audiocodec frequnecy setting structure */
@@ -149477,7 +150137,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +              t_uint16                buffer_size;
 +              t_uint32                buffer_address;
 +              t_uint32                avzone_address;
-+              saa_dma_config          dma_conf;       
++              saa_dma_config          dma_conf;
 +} saa_dma_configuration_struct;
 +
 +typedef struct {
@@ -149540,7 +150200,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +              codec_msp_srg_clock_sel_type    msp_clock_sel;
 +              codec_msp_in_clock_freq_type    msp_clock_freq;
 +              saa_block_id                    block_id;
-+                      
++
 +} saa_msp_connect_struct ;
 +
 +/* SSP hierarchy (master/slave) */
@@ -149688,7 +150348,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +              t_uint32                count;
 +              t_uint32                address;
 +              saa_sample_freq         freq;
-+              
++
 +} saa_samplecount_struct ;
 +
 +/* Version strcut of saa and saa-hcl */
@@ -149765,7 +150425,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +/* SAA IOCTL */
 +
 +#define       SAAIOCTL_SERVERBLOCKCREATE              _IOWR('S', 1, saa_create_block_struct)
-+#define       SAAIOCTL_SERVERBLOCKDELETE              _IOR('S', 2, saa_block_id)      
++#define       SAAIOCTL_SERVERBLOCKDELETE              _IOR('S', 2, saa_block_id)
 +#define       SAAIOCTL_SERVERPORTCREATE               _IOWR('S', 3, saa_create_port_struct)
 +#define       SAAIOCTL_SERVERPORTDELETE               _IOR('S', 4, saa_create_port_struct)
 +#define       SAAIOCTL_SERVERBLOCKFREEZE              _IOR('S', 5, saa_block_id)
@@ -149780,7 +150440,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +#define       SAAIOCTL_AEPINIT                        _IOR('S', 14, saa_aep_init)
 +#define       SAAIOCTL_AEPCOMPONENTCREATE             _IOWR('S', 15, saa_AEP_Component_struct)
 +#define       SAAIOCTL_AEPCOMPONENTDELETE             _IOR('S', 16, saa_AEP_Component_struct)
-+#define       SAAIOCTL_AEPCOMPONENTCONNECT            _IOR('S', 17, saa_AEP_Component_Connect_struct) 
++#define       SAAIOCTL_AEPCOMPONENTCONNECT            _IOR('S', 17, saa_AEP_Component_Connect_struct)
 +#define       SAAIOCTL_AEPCOMPONENTDISCONNECT         _IOR('S', 18, saa_AEP_Component_Connect_struct)
 +#define       SAAIOCTL_AEPCOMPONENTCONFIG             _IOR('S', 19, saa_component_config)
 +#define       SAAIOCTL_SET_EOFSIZE                    _IOWR('S', 20, saa_set_eofsize)
@@ -149792,7 +150452,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +#define       SAAIOCTL_TRANSFER_IO_BUFFER             _IOR('S', 26, saa_xfer_iobuff_struct)
 +#define       SAAIOCTL_FLUSH_IO_BUFFER                _IO('S', 27)  /* not needed */
 +#define       SAAIOCTL_GET_TRANSFER_STATUS            _IOWR('S', 28, saa_xfer_status_struct)
-+#define       SAAIOCTL_UPDATE_NETWORK                 _IO('S', 29) 
++#define       SAAIOCTL_UPDATE_NETWORK                 _IO('S', 29)
 +#define       SAAIOCTL_START_NETWORK                  _IOR('S', 30, saa_flow_control_struct)
 +#define       SAAIOCTL_PAUSE_NETWORK                  _IOR('S', 31, saa_flow_control_struct)
 +#define       SAAIOCTL_UNPAUSE_NETWORK                _IOR('S', 32, saa_flow_control_struct)
@@ -149823,17 +150483,16 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/saa/saaioctl.h ../new/linux-2
 +
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile
---- linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile  2008-10-06 12:06:21.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile
 @@ -0,0 +1,58 @@
 +#KERNEL_PATH = /home/preetham/lastestlinux/linux-2.6.20
 +#KERNEL_PATH:=../../../../../linux-2.6.20
 +#NMDK_HCLDIR = /home/preetham/lastestlinux/linux-2.6.20/drivers/media/nomadik_mm/hcl
 +#NMDK_HCLDIR:=../hcl
 +OBJ_HCLDIR = ../hcl
-+#CC=arm-926ejs-linux-gnueabi-gcc  
-+#LD=arm-926ejs-linux-gnueabi-ld  
++#CC=arm-926ejs-linux-gnueabi-gcc
++#LD=arm-926ejs-linux-gnueabi-ld
 +#AR=arm-926ejs-linux-gnueabi-ar
 +ifeq ($(CONFIG_NOMADIK_NDK10),y)
 +ifeq ($(CONFIG_NOMADIK_NDK10_CUTA),y)
@@ -149843,12 +150502,12 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile ../new/linux-2.6
 +endif
 +else
 +ifeq ($(CONFIG_NOMADIK_NDK15_REV2_B_06),y)
-+HCL_CFLAGS := -D__arm -D__STN_8815=20 -D__RELEASE   -D__CC_ARM 
-+else 
++HCL_CFLAGS := -D__arm -D__STN_8815=20 -D__RELEASE   -D__CC_ARM
++else
 +ifeq ($(CONFIG_NOMADIK_NHK15),y)
-+HCL_CFLAGS := -D__arm -D__STN_8815=20 -D__RELEASE   -D__CC_ARM 
++HCL_CFLAGS := -D__arm -D__STN_8815=20 -D__RELEASE   -D__CC_ARM
 +else
-+HCL_CFLAGS := -D__arm -D__STN_8815=10 -D__RELEASE   -D__CC_ARM 
++HCL_CFLAGS := -D__arm -D__STN_8815=10 -D__RELEASE   -D__CC_ARM
 +endif
 +endif
 +endif
@@ -149869,8 +150528,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile ../new/linux-2.6
 +
 +#cam_obj := nomadik_pepperpot.o
 +
-+#obj-m = nmdkmod_pepperpot.o nmdkmod_SVA.o 
-+obj-$(CONFIG_NOMADIK_SVA) +=  nmdkmod_SVA.o 
++#obj-m = nmdkmod_pepperpot.o nmdkmod_SVA.o
++obj-$(CONFIG_NOMADIK_SVA) +=  nmdkmod_SVA.o
 +
 +#nmdkmod_pepperpot-objs := $(cam_obj)
 +
@@ -149882,12 +150541,11 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/Makefile ../new/linux-2.6
 +EXTRA_CFLAGS += $(COMMON_CFLAGS)
 +#
 +#clean:
-+#     $(MAKE) -C $(KERNEL_PATH) M=`pwd` clean; rm -f $(hcl_obj) 
++#     $(MAKE) -C $(KERNEL_PATH) M=`pwd` clean; rm -f $(hcl_obj)
 +#
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h  2008-07-17 16:43:36.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h
 @@ -0,0 +1,206 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -150095,9 +150753,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_camera.h ../new/l
 +
 +
 +#endif /*__CAMERA_H__*/
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h    2008-07-17 16:43:37.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h
 @@ -0,0 +1,76 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -150175,9 +150832,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_defs.h ../new/lin
 +
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c       2008-07-17 16:43:37.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c
 @@ -0,0 +1,1189 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -151368,9 +152024,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.c ../ne
 +MODULE_AUTHOR ("Melwyn LOBO <melwyn.lobo@st.com>");
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h       2008-07-17 16:43:38.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h
 @@ -0,0 +1,153 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -151525,9 +152180,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_pepperpot.h ../ne
 +      static int sva_set_pepperpot_whitebalancemode(__u8);
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c     2008-11-24 14:06:25.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c
 @@ -0,0 +1,4951 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -153488,14 +154142,14 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c ../new/linu
 +                                              ,qbuf->service_id, qbuf->buffer.buffer_id);
 +                      up(&open->open_lock);
 +                      return -EINVAL;
-+                      
++
 +              }
 +              shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags &= ~BUF_FLAG_DONE;
-+              
++
 +//            printk("sq_buff %d cnt %d\n",qbuf->buffer.buffer_id, shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.count);
-+              
++
 +              if(shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.count == 0) {
-+                      
++
 +              if(srv->type == SVA_VIDEO_ENCODER || srv->type == SVA_POSTPROCESSOR) {
 +                              shared_open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags &= BUF_FLAG_QUEUED_RO;
 +                      } else {
@@ -153512,14 +154166,14 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c ../new/linu
 +                      up(&open->open_lock);
 +                      return -EINVAL;
 +              }
-+                              
++
 +              }else{
 +                      dbgprintk(3,"shared queue_buffer fails for SERVICE %d, buffer %d already queued\n"
 +                                              ,qbuf->service_id, qbuf->buffer.buffer_id);
 +                      up(&open->open_lock);
 +                      return -EINVAL;
 +              }
-+              
++
 +              }
 +              buf_info = shared_open->buffer_info[qbuf->buffer.buffer_id];
 +      } else {
@@ -153527,7 +154181,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c ../new/linu
 +              buf_info = open->buffer_info[qbuf->buffer.buffer_id];
 +
 +//            printk("q_buff %d cnt %d\n", qbuf->buffer.buffer_id, buf_info->buffer.count);
-+              
++
 +              if(!open->buffer_info[qbuf->buffer.buffer_id] ||
 +                      (open->buffer_info[qbuf->buffer.buffer_id]->buffer.flags & BUF_FLAG_QUEUED)
 +                                                                              == BUF_FLAG_QUEUED) {
@@ -156480,9 +157134,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.c ../new/linu
 +EXPORT_SYMBOL(camera_register_device);
 +EXPORT_SYMBOL(camera_unregister_device);
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h     2008-07-17 16:43:40.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h
 @@ -0,0 +1,225 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -156569,7 +157222,7 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h ../new/linu
 +      __u16 sensor_aoi_x;
 +      __u16 sensor_aoi_y;
 +      __u16 prescale_factor;
-+      
++
 +};
 +
 +struct sva_videodecoder_info {
@@ -156709,9 +157362,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva.h ../new/linu
 +#endif /* __SVA_SERVICE_INFO_H__ */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c       2008-07-17 16:43:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c
 @@ -0,0 +1,432 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -157145,9 +157797,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_mpeg4.c ../ne
 +      return 0;
 +}
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h    2008-11-24 14:06:26.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h
 @@ -0,0 +1,3826 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -160975,9 +161626,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_services.h ..
 +
 +
 +#endif /* __SVA_SERVICES_H__*/
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c       2008-07-17 16:43:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c
 @@ -0,0 +1,964 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -161943,9 +162593,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.c ../ne
 +}
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h       2008-07-17 16:43:43.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h
 @@ -0,0 +1,49 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -161996,9 +162645,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_utils.h ../ne
 +extern int   sva_q_last(struct sva_queue *q);
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c        2008-11-24 14:06:26.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c
 @@ -0,0 +1,6984 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -168984,9 +169632,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.c ../new
 +        kfree(irp_fw_ptr);
 +    return 0;
 +}
-diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h
---- linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h        2008-11-24 14:06:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h
 @@ -0,0 +1,589 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -169577,14 +170224,68 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/sva/nomadik_sva_vpip.h ../new
 +t_sva_error irp_start_ewarp_hq(struct sva_service_open *srv_open);
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/drivers/media/video/hcl_defs.h
---- linux-2.6.20/drivers/media/video/hcl_defs.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/hcl_defs.h 2007-11-21 11:51:42.000000000 +0530
+--- linux-2.6.20.orig/drivers/media/video/Kconfig
++++ linux-2.6.20/drivers/media/video/Kconfig
+@@ -761,6 +761,13 @@ source "drivers/media/video/zc0301/Kconf
+ source "drivers/media/video/pwc/Kconfig"
+ endmenu # V4L USB devices
++config VIDEO_NOMADIK
++      boolean "V4L2 compatiblity module for Nomadik SVA"
++      depends on VIDEO_DEV
++      ---help---
++        Say Y here to compile v4l2 compatiblity module over Nomadik
++        SVA driver.
++
+ endmenu
+--- linux-2.6.20.orig/drivers/media/video/Makefile
++++ linux-2.6.20/drivers/media/video/Makefile
+@@ -7,10 +7,12 @@ zr36067-objs :=      zoran_procfs.o zoran_dev
+ tuner-objs    :=      tuner-core.o tuner-types.o tuner-simple.o \
+                       mt20xx.o tda8290.o tea5767.o tda9887.o
+ msp3400-objs  :=      msp3400-driver.o msp3400-kthreads.o
++nmdkmod_v4l2-objs:=   v4l2-nomadik.o
++
+ obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o
+ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
+   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
+ endif
+@@ -82,10 +84,14 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+ obj-$(CONFIG_VIDEO_BUF)   += video-buf.o
+ obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
+ obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
+ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
++ifeq ($(CONFIG_VIDEO_NOMADIK),y)
++      obj-m := nmdkmod_v4l2.o
++endif
++
+ obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
+ obj-$(CONFIG_VIDEO_CX25840) += cx25840/
+ obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
+ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
+@@ -110,7 +116,7 @@ obj-$(CONFIG_USB_KONICAWC)      += usbvi
+ obj-$(CONFIG_USB_VICAM)         += usbvideo/
+ obj-$(CONFIG_USB_QUICKCAM_MESSENGER)  += usbvideo/
+ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+-EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
++EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -I$(TOPDIR)/../multimedia/sva -I$(TOPDIR)/../multimedia/hcl/include -I$(TOPDIR)/../multimedia/hcl/sva
+ extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/hcl_defs.h
 @@ -0,0 +1,280 @@
 +/******************************************************************************
-+ *             C STMicroelectronics  
-+ *   Reproduction and Communication of this document is 
-+ *   strictly prohibited unless specifically autorized in 
++ *             C STMicroelectronics
++ *   Reproduction and Communication of this document is
++ *   strictly prohibited unless specifically autorized in
 + *   writing by STMicroelectronics.
 + *-----------------------------------------------------------------------------
 + *
@@ -169600,7 +170301,7 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +#include "platform_os.h"
 +
 +/*-----------------------------------------------------------------------------
-+ * Type definition                                                               
++ * Type definition
 + *---------------------------------------------------------------------------*/
 +typedef unsigned char t_uint8;
 +typedef signed char t_sint8;
@@ -169619,7 +170320,7 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +
 +typedef unsigned int t_bitfield;
 +
-+#if !defined(FALSE) &&  !defined(TRUE)   
++#if !defined(FALSE) &&  !defined(TRUE)
 +typedef enum {FALSE, TRUE} t_bool;
 +#else /* FALSE & TRUE already defined */
 +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool;
@@ -169636,10 +170337,10 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +
 +/*
 + * Global frequency enumuration
-+ * Added to avoid frequency conversion function which is required to convert one HCL 
++ * Added to avoid frequency conversion function which is required to convert one HCL
 + * frequency enumuration values to another HCL frequency enumuration values.
 + */
-+ 
++
 +typedef enum {
 +      HCL_FREQ_NOT_SUPPORTED=-1,
 +      HCL_FREQ_8KHZ ,
@@ -169651,15 +170352,15 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +      HCL_FREQ_24KHZ,
 +      HCL_FREQ_32KHZ,
 +      HCL_FREQ_44KHZ,
-+      HCL_FREQ_44_1KHZ,       
++      HCL_FREQ_44_1KHZ,
 +      HCL_FREQ_48KHZ,
 +      HCL_FREQ_64KHZ,
 +      HCL_FREQ_88KHZ,
 +      HCL_FREQ_88_2KHZ,
 +      HCL_FREQ_96KHZ,
 +      HCL_FREQ_128KHZ,
-+      HCL_FREQ_176_4KHZ,    
-+      HCL_FREQ_192KHZ,                
++      HCL_FREQ_176_4KHZ,
++      HCL_FREQ_192KHZ,
 +      HCL_FREQ_1MHZ,
 +      HCL_FREQ_2MHZ,
 +      HCL_FREQ_3MHZ,
@@ -169673,7 +170374,7 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +      HCL_FREQ_22MHZ,
 +      HCL_FREQ_24MHZ,
 +      HCL_FREQ_48MHZ
-+} t_frequency; 
++} t_frequency;
 +
 +
 +
@@ -169698,7 +170399,7 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +
 +
 +/*-----------------------------------------------------------------------------
-+ * Keyword definition 
++ * Keyword definition
 + *---------------------------------------------------------------------------*/
 +#define PUBLIC        /* Extern by default */
 +#define PRIVATE      static
@@ -169750,42 +170451,42 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +#define MASK_NULL8    0x00
 +#define MASK_NULL16   0x0000
 +#define MASK_NULL32   0x00000000
-+#define MASK_ALL8     0xFF 
-+#define MASK_ALL16    0xFFFF 
++#define MASK_ALL8     0xFF
++#define MASK_ALL16    0xFFFF
 +#define MASK_ALL32    0xFFFFFFFF
 +
 +#define MASK_BIT0     (1UL<<0)
-+#define MASK_BIT1     (1UL<<1) 
-+#define MASK_BIT2     (1UL<<2) 
-+#define MASK_BIT3     (1UL<<3) 
-+#define MASK_BIT4     (1UL<<4) 
-+#define MASK_BIT5     (1UL<<5) 
-+#define MASK_BIT6     (1UL<<6) 
-+#define MASK_BIT7     (1UL<<7) 
-+#define MASK_BIT8     (1UL<<8) 
-+#define MASK_BIT9     (1UL<<9) 
-+#define MASK_BIT10    (1UL<<10) 
-+#define MASK_BIT11    (1UL<<11) 
-+#define MASK_BIT12    (1UL<<12) 
-+#define MASK_BIT13    (1UL<<13) 
-+#define MASK_BIT14    (1UL<<14) 
-+#define MASK_BIT15    (1UL<<15) 
-+#define MASK_BIT16    (1UL<<16) 
-+#define MASK_BIT17    (1UL<<17) 
-+#define MASK_BIT18    (1UL<<18) 
-+#define MASK_BIT19    (1UL<<19) 
-+#define MASK_BIT20    (1UL<<20) 
++#define MASK_BIT1     (1UL<<1)
++#define MASK_BIT2     (1UL<<2)
++#define MASK_BIT3     (1UL<<3)
++#define MASK_BIT4     (1UL<<4)
++#define MASK_BIT5     (1UL<<5)
++#define MASK_BIT6     (1UL<<6)
++#define MASK_BIT7     (1UL<<7)
++#define MASK_BIT8     (1UL<<8)
++#define MASK_BIT9     (1UL<<9)
++#define MASK_BIT10    (1UL<<10)
++#define MASK_BIT11    (1UL<<11)
++#define MASK_BIT12    (1UL<<12)
++#define MASK_BIT13    (1UL<<13)
++#define MASK_BIT14    (1UL<<14)
++#define MASK_BIT15    (1UL<<15)
++#define MASK_BIT16    (1UL<<16)
++#define MASK_BIT17    (1UL<<17)
++#define MASK_BIT18    (1UL<<18)
++#define MASK_BIT19    (1UL<<19)
++#define MASK_BIT20    (1UL<<20)
 +#define MASK_BIT21    (1UL<<21)
-+#define MASK_BIT22    (1UL<<22) 
-+#define MASK_BIT23    (1UL<<23) 
-+#define MASK_BIT24    (1UL<<24) 
-+#define MASK_BIT25    (1UL<<25) 
-+#define MASK_BIT26    (1UL<<26) 
-+#define MASK_BIT27    (1UL<<27) 
-+#define MASK_BIT28    (1UL<<28) 
-+#define MASK_BIT29    (1UL<<29) 
++#define MASK_BIT22    (1UL<<22)
++#define MASK_BIT23    (1UL<<23)
++#define MASK_BIT24    (1UL<<24)
++#define MASK_BIT25    (1UL<<25)
++#define MASK_BIT26    (1UL<<26)
++#define MASK_BIT27    (1UL<<27)
++#define MASK_BIT28    (1UL<<28)
++#define MASK_BIT29    (1UL<<29)
 +#define MASK_BIT30    (1UL<<30)
-+#define MASK_BIT31    (1UL<<31) 
++#define MASK_BIT31    (1UL<<31)
 +
 +/*-----------------------------------------------------------------------------
 + * quartet shift definition
@@ -169820,7 +170521,7 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +#define MASK_BYTE1      (MASK_BYTE << SHIFT_BYTE1)
 +#define MASK_BYTE2      (MASK_BYTE << SHIFT_BYTE2)
 +#define MASK_BYTE3      (MASK_BYTE << SHIFT_BYTE3)
-+ 
++
 +/*-----------------------------------------------------------------------------
 + * Halfword shift definition
 + *---------------------------------------------------------------------------*/
@@ -169835,8 +170536,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 + *---------------------------------------------------------------------------*/
 + #define ONE_KB        (1024)
 + #define ONE_MB        (ONE_KB * ONE_KB)
-+ 
-+ 
++
++
 +/*-----------------------------------------------------------------------------
 + * Address translation macros declaration
 + *---------------------------------------------------------------------------*/
@@ -169861,54 +170562,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/hcl_defs.h ../new/linux-2.6.20/dri
 +#endif /* _HCL_DEFS_H */
 +
 +/* End of file hcl_defs.h */
-diff -Nauprw linux-2.6.20/drivers/media/video/Kconfig ../new/linux-2.6.20/drivers/media/video/Kconfig
---- linux-2.6.20/drivers/media/video/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/Kconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -763,4 +763,11 @@ source "drivers/media/video/pwc/Kconfig"
- endmenu # V4L USB devices
-+config VIDEO_NOMADIK
-+      boolean "V4L2 compatiblity module for Nomadik SVA"
-+      depends on VIDEO_DEV
-+      ---help---
-+        Say Y here to compile v4l2 compatiblity module over Nomadik
-+        SVA driver.
-+
- endmenu
-diff -Nauprw linux-2.6.20/drivers/media/video/Makefile ../new/linux-2.6.20/drivers/media/video/Makefile
---- linux-2.6.20/drivers/media/video/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/Makefile   2007-11-21 11:51:41.000000000 +0530
-@@ -9,6 +9,8 @@ tuner-objs     :=      tuner-core.o tuner-types.o
- msp3400-objs  :=      msp3400-driver.o msp3400-kthreads.o
-+nmdkmod_v4l2-objs:=   v4l2-nomadik.o
-+
- obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o
- ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
-@@ -84,6 +86,10 @@ obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf
- obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
- obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
-+ifeq ($(CONFIG_VIDEO_NOMADIK),y)
-+      obj-m := nmdkmod_v4l2.o
-+endif
-+
- obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
- obj-$(CONFIG_VIDEO_CX25840) += cx25840/
-@@ -112,5 +118,5 @@ obj-$(CONFIG_USB_QUICKCAM_MESSENGER)       += 
- obj-$(CONFIG_VIDEO_VIVI) += vivi.o
--EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
-+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -I$(TOPDIR)/../multimedia/sva -I$(TOPDIR)/../multimedia/hcl/include -I$(TOPDIR)/../multimedia/hcl/sva
- extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT
-diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_camera.h ../new/linux-2.6.20/drivers/media/video/nomadik_camera.h
---- linux-2.6.20/drivers/media/video/nomadik_camera.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/nomadik_camera.h   2008-07-17 16:42:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/nomadik_camera.h
 @@ -0,0 +1,206 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -170116,9 +170771,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_camera.h ../new/linux-2.6.
 +
 +
 +#endif /*__CAMERA_H__*/
-diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_defs.h ../new/linux-2.6.20/drivers/media/video/nomadik_defs.h
---- linux-2.6.20/drivers/media/video/nomadik_defs.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/nomadik_defs.h     2008-07-17 16:42:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/nomadik_defs.h
 @@ -0,0 +1,76 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -170196,9 +170850,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_defs.h ../new/linux-2.6.20
 +
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva.h ../new/linux-2.6.20/drivers/media/video/nomadik_sva.h
---- linux-2.6.20/drivers/media/video/nomadik_sva.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/nomadik_sva.h      2008-07-17 16:42:43.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/nomadik_sva.h
 @@ -0,0 +1,225 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -170285,7 +170938,7 @@ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva.h ../new/linux-2.6.20/
 +      __u16 sensor_aoi_x;
 +      __u16 sensor_aoi_y;
 +      __u16 prescale_factor;
-+      
++
 +};
 +
 +struct sva_videodecoder_info {
@@ -170425,9 +171078,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva.h ../new/linux-2.6.20/
 +#endif /* __SVA_SERVICE_INFO_H__ */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva_services.h ../new/linux-2.6.20/drivers/media/video/nomadik_sva_services.h
---- linux-2.6.20/drivers/media/video/nomadik_sva_services.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/nomadik_sva_services.h     2008-11-24 14:06:24.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/nomadik_sva_services.h
 @@ -0,0 +1,3832 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -174261,9 +174913,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva_services.h ../new/linu
 +
 +
 +#endif /* __SVA_SERVICES_H__*/
-diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva_utils.h ../new/linux-2.6.20/drivers/media/video/nomadik_sva_utils.h
---- linux-2.6.20/drivers/media/video/nomadik_sva_utils.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/nomadik_sva_utils.h        2008-07-17 16:42:44.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/nomadik_sva_utils.h
 @@ -0,0 +1,49 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -174314,9 +174965,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/nomadik_sva_utils.h ../new/linux-2
 +extern int   sva_q_last(struct sva_queue *q);
 +
 +#endif
-diff -Nauprw linux-2.6.20/drivers/media/video/platform_os.h ../new/linux-2.6.20/drivers/media/video/platform_os.h
---- linux-2.6.20/drivers/media/video/platform_os.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/platform_os.h      2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/platform_os.h
 @@ -0,0 +1,55 @@
 +/* Dummy file used to define some conditionnal compilation flags */
 +#ifndef __INC_PLATFORM_OS_H
@@ -174364,18 +175014,17 @@ diff -Nauprw linux-2.6.20/drivers/media/video/platform_os.h ../new/linux-2.6.20/
 +
 +/*
 + * Define extended ANSI C unsigned long long type
-+ * could be redefine for each OS 
-+ * ie: for WINCE: 
-+ * typedef unsigned __int64 t_uint64; 
++ * could be redefine for each OS
++ * ie: for WINCE:
++ * typedef unsigned __int64 t_uint64;
 + * typedef __int64 t_sint64;
 + */
 +typedef unsigned long long t_uint64;
 +typedef signed long long t_sint64;
 +
 +#endif /* __INC_PLATFORM_OS_H */
-diff -Nauprw linux-2.6.20/drivers/media/video/sva.h ../new/linux-2.6.20/drivers/media/video/sva.h
---- linux-2.6.20/drivers/media/video/sva.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/sva.h      2008-07-17 16:42:44.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/sva.h
 @@ -0,0 +1,2148 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -176525,9 +177174,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/sva.h ../new/linux-2.6.20/drivers/
 +
 +#endif /* __INC_SVA_H */
 +
-diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.c ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.c
---- linux-2.6.20/drivers/media/video/v4l2-nomadik.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.c     2008-11-24 14:06:24.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/v4l2-nomadik.c
 @@ -0,0 +1,1590 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -178119,9 +178767,8 @@ diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.c ../new/linux-2.6.20
 +MODULE_AUTHOR("Melwyn LOBO <melwyn.lobo@st.com>");
 +
 +
-diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.h ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.h
---- linux-2.6.20/drivers/media/video/v4l2-nomadik.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/media/video/v4l2-nomadik.h     2008-07-17 16:42:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/media/video/v4l2-nomadik.h
 @@ -0,0 +1,70 @@
 +/*---------------------------------------------------------------------------*/
 +/* Â© copyright STMicroelectronics, 2007. All rights reserved. For            */
@@ -178193,9 +178840,69 @@ diff -Nauprw linux-2.6.20/drivers/media/video/v4l2-nomadik.h ../new/linux-2.6.20
 +int sva_service_update(struct sva_device_open *open, struct sva_update_service *update);
 +
 +
-diff -Nauprw linux-2.6.20/drivers/misc/batt-nomadik.c ../new/linux-2.6.20/drivers/misc/batt-nomadik.c
---- linux-2.6.20/drivers/misc/batt-nomadik.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/batt-nomadik.c    2008-10-20 13:38:12.000000000 +0530
+--- linux-2.6.20.orig/drivers/misc/Kconfig
++++ linux-2.6.20/drivers/misc/Kconfig
+@@ -1,11 +1,33 @@
+ #
+ # Misc strange devices
+ #
++#        depends on ARCH_NOMADIK NOMADIK_SSP NOMADIK_GPIO
++
+ menu "Misc devices"
++
++config STMPE_NOMADIK
++        tristate "Port expander driver for  Nomadik board"
++        depends on NOMADIK_NHK15
++        help
++          Say Y here if you have a port expander in your platform.
++
++config SIF_NOMADIK
++        tristate "Display protocol driver for nhk15"
++        depends on NOMADIK_NHK15
++        help
++          Say Y here if you want to change the gamma, brightness and contrast values
++              for the display
++
++config ETM_NOMADIK
++        tristate "ETM support nhk15"
++        depends on NOMADIK_NHK15
++        help
++          Say Y here if you want ETM support for debugging.
++
+ config IBM_ASM
+       tristate "Device driver for IBM RSA service processor"
+       depends on X86 && PCI && EXPERIMENTAL
+       ---help---
+         This option enables device driver support for in-band access to the
+@@ -86,6 +108,11 @@ config MSI_LAPTOP
+         More information about this driver is available at
+         <http://0pointer.de/lennart/tchibo.html>.
+         If you have an MSI S270 laptop, say Y or M here.
++config BATT_NOMADIK
++        tristate "Battery charger driver for  Nomadik board"
++        depends on NOMADIK_NHK15
++        help
++          Say Y here if you have a port expander in your platform.
+ endmenu
+--- linux-2.6.20.orig/drivers/misc/Makefile
++++ linux-2.6.20/drivers/misc/Makefile
+@@ -8,5 +8,9 @@ obj-$(CONFIG_HDPU_FEATURES)    += hdpuftrs/
+ obj-$(CONFIG_MSI_LAPTOP)     += msi-laptop.o
+ obj-$(CONFIG_LKDTM)           += lkdtm.o
+ obj-$(CONFIG_TIFM_CORE)               += tifm_core.o
+ obj-$(CONFIG_TIFM_7XX1)               += tifm_7xx1.o
+ obj-$(CONFIG_SGI_IOC4)                += ioc4.o
++obj-$(CONFIG_STMPE_NOMADIK)     += pexp-nomadik.o
++obj-$(CONFIG_SIF_NOMADIK)             += sif-nomadik.o
++obj-$(CONFIG_ETM_NOMADIK)             += etm-nomadik.o
++obj-$(CONFIG_BATT_NOMADIK)      += batt-nomadik.o
+\ No newline at end of file
+--- /dev/null
++++ linux-2.6.20/drivers/misc/batt-nomadik.c
 @@ -0,0 +1,1307 @@
 +/*\r
 + * Overview:\r
@@ -179504,9 +180211,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/batt-nomadik.c ../new/linux-2.6.20/driver
 +module_init(nomadik_stcharg_init);\r
 +module_exit(nomadik_stcharg_exit);\r
 +\r
-diff -Nauprw linux-2.6.20/drivers/misc/etm-nomadik.c ../new/linux-2.6.20/drivers/misc/etm-nomadik.c
---- linux-2.6.20/drivers/misc/etm-nomadik.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/etm-nomadik.c     2008-11-19 16:47:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/misc/etm-nomadik.c
 @@ -0,0 +1,207 @@
 +/*
 + * Overview:
@@ -179715,65 +180421,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/etm-nomadik.c ../new/linux-2.6.20/drivers
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("ST Microelectronics");
 +MODULE_DESCRIPTION("ETM module for Nomadik (nhk15) Platform");
-diff -Nauprw linux-2.6.20/drivers/misc/Kconfig ../new/linux-2.6.20/drivers/misc/Kconfig
---- linux-2.6.20/drivers/misc/Kconfig  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/Kconfig   2008-10-20 13:37:45.000000000 +0530
-@@ -2,8 +2,30 @@
- # Misc strange devices
- #
-+#        depends on ARCH_NOMADIK NOMADIK_SSP NOMADIK_GPIO 
-+
- menu "Misc devices"
-+
-+config STMPE_NOMADIK
-+        tristate "Port expander driver for  Nomadik board"
-+        depends on NOMADIK_NHK15
-+        help
-+          Say Y here if you have a port expander in your platform.
-+
-+config SIF_NOMADIK
-+        tristate "Display protocol driver for nhk15"
-+        depends on NOMADIK_NHK15
-+        help
-+          Say Y here if you want to change the gamma, brightness and contrast values
-+              for the display
-+
-+config ETM_NOMADIK
-+        tristate "ETM support nhk15"
-+        depends on NOMADIK_NHK15
-+        help
-+          Say Y here if you want ETM support for debugging.
-+
- config IBM_ASM
-       tristate "Device driver for IBM RSA service processor"
-       depends on X86 && PCI && EXPERIMENTAL
-@@ -88,4 +110,9 @@ config MSI_LAPTOP
-         If you have an MSI S270 laptop, say Y or M here.
-+config BATT_NOMADIK
-+        tristate "Battery charger driver for  Nomadik board"
-+        depends on NOMADIK_NHK15
-+        help
-+          Say Y here if you have a port expander in your platform.
- endmenu
-diff -Nauprw linux-2.6.20/drivers/misc/Makefile ../new/linux-2.6.20/drivers/misc/Makefile
---- linux-2.6.20/drivers/misc/Makefile 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/Makefile  2008-10-20 13:37:45.000000000 +0530
-@@ -10,3 +10,7 @@ obj-$(CONFIG_LKDTM)          += lkdtm.o
- obj-$(CONFIG_TIFM_CORE)               += tifm_core.o
- obj-$(CONFIG_TIFM_7XX1)               += tifm_7xx1.o
- obj-$(CONFIG_SGI_IOC4)                += ioc4.o
-+obj-$(CONFIG_STMPE_NOMADIK)     += pexp-nomadik.o
-+obj-$(CONFIG_SIF_NOMADIK)             += sif-nomadik.o
-+obj-$(CONFIG_ETM_NOMADIK)             += etm-nomadik.o
-+obj-$(CONFIG_BATT_NOMADIK)      += batt-nomadik.o
-\ No newline at end of file
-diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/drivers/misc/pexp-nomadik.c
---- linux-2.6.20/drivers/misc/pexp-nomadik.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/pexp-nomadik.c    2008-09-17 13:23:32.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/misc/pexp-nomadik.c
 @@ -0,0 +1,2847 @@
 +/*
 + * Overview:
@@ -179818,7 +180467,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +#include <asm/arch/pexp.h>
 +#include <asm/arch/i2c.h>
 +
-+#define DEBUG 0 
++#define DEBUG 0
 +
 +
 +/*
@@ -179837,7 +180486,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + Internal defines
 +*/
 +
-+#define STMPE2401_WAIT_RESET_TIMEOUT  100     
++#define STMPE2401_WAIT_RESET_TIMEOUT  100
 +#define STMPE2401_I2C_TIMEOUT 1000
 +
 +/*STMP interrupt numbers*/
@@ -179852,18 +180501,18 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +#define RAMP_UP_SLOW          0x7F01
 +#define RAMP_DN_SLOW          0x7F81
 +#define RAMP_UP(step)         step
-+#define RAMP_DN(step)         (step | 0x0080)                         
++#define RAMP_DN(step)         (step | 0x0080)
 +#define BRANCH_TO(add)                (add | 0xA000)
 +#define GTS_ISTRUCTION                0x0000
 +
 +/*Register definition*/
 +
 +/*System registers Index*/
-+#define CHIP_ID_Index                 0x80  
-+#define VERSION_ID_Index              0x81 
++#define CHIP_ID_Index                 0x80
++#define VERSION_ID_Index              0x81
 +#define SYSCON_Index                  0x02
 +
-+#define GPIO_OFFSET                           
++#define GPIO_OFFSET
 +
 +/*Interrupt registers Index*/
 +#define ICR_Msb_Index     0x10  /*Interrupt Control register*/
@@ -179911,19 +180560,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +#define GPCR_Lsb_Index      0x88
 +/*GPIO Set Pin Direction register*/
 +#define GPDR_Msb_Index      0x89
-+#define GPDR_Csb_Index      0x8A  
++#define GPDR_Csb_Index      0x8A
 +#define GPDR_Lsb_Index      0x8B
 +/*GPIO Edge Detect Status register*/
 +#define GPEDR_Msb_Index      0x8C
-+#define GPEDR_Csb_Index      0x8D   
++#define GPEDR_Csb_Index      0x8D
 +#define GPEDR_Lsb_Index      0x8E
 +/*GPIO Rising Edge register*/
 +#define GPRER_Msb_Index      0x8F
-+#define GPRER_Csb_Index      0x90   
++#define GPRER_Csb_Index      0x90
 +#define GPRER_Lsb_Index      0x91
 +/*GPIO Falling Edge register*/
 +#define GPFER_Msb_Index      0x92
-+#define GPFER_Csb_Index      0x93   
++#define GPFER_Csb_Index      0x93
 +#define GPFER_Lsb_Index      0x94
 +/*GPIO Pull Up register*/
 +#define GPPUR_Msb_Index     0x95
@@ -179931,7 +180580,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +#define GPPUR_Lsb_Index     0x97
 +/*GPIO Pull Down register*/
 +#define GPPDR_Msb_Index     0x98
-+#define GPPDR_Csb_Index     0x99   
++#define GPPDR_Csb_Index     0x99
 +#define GPPDR_Lsb_Index     0x9A
 +
 +/*GPIO Alternate Function register*/
@@ -179983,8 +180632,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +static void nomadik_stmpe0_wq(void * data);
 +static void nomadik_stmpe1_wq(void * data);
 +
-+static DECLARE_WORK(work0,nomadik_stmpe0_wq); 
-+static DECLARE_WORK(work1,nomadik_stmpe1_wq); 
++static DECLARE_WORK(work0,nomadik_stmpe0_wq);
++static DECLARE_WORK(work1,nomadik_stmpe1_wq);
 +
 +/**
 + * int nomadik_stmpe_ioctl - provides a mechanism for passing control
@@ -180003,7 +180652,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      int err = 0;
 +      int bklight = 0;
 +      int __user *argp = (int __user *)arg;
-+              
++
 +      if (_IOC_DIR(cmd) & _IOC_READ)
 +              err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
 +      else if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -180012,7 +180661,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              return -EFAULT;
 +
 +      switch (cmd) {
-+      
++
 +      case STMPE_SET_BACKLIGHT:
 +              copy_from_user(&bklight ,argp, sizeof(int));
 +              if (bklight < 0 || bklight > 255 )      {
@@ -180034,7 +180683,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +/**
 + * nomadik_stmpe_open - open sys call for stmpe device
 + * @inode: pointer to the inode structure for the stmpe device
-+ * @filp: pointer to the file structure for the stmpe device 
++ * @filp: pointer to the file structure for the stmpe device
 + *
 + * This function opens the stmpe device for file operations.
 + */
@@ -180045,7 +180694,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +/**
 + * nomadik_stmpe_release - close sys call for stmpe device
-+ * @inode: pointer to the inode structure for the stmpe device 
++ * @inode: pointer to the inode structure for the stmpe device
 + * @filp: pointer to the file structure for the stmpe device
 + *
 + * This function is called when the stmpe device is closed.
@@ -180087,19 +180736,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      int ret;
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      t_STMPE2401_gpio_config PinConfigSTMPE;
-+      gpio_config PinConfig,rst_pin;  
++      gpio_config PinConfig,rst_pin;
 +      /*t_STMPE2401_key_config KeyConfig;*/
-+      
++
 +      if(!pdata->init)        {
 +              printk("STMPE ::: platform init() function is not present\n");
 +              return -1;
-+      }       
++      }
 +      /*issue hard reset to the STMPE devices*/
 +              rst_pin.mode = GPIO_MODE_SOFTWARE;
 +        rst_pin.direction = GPIO_DIR_OUTPUT;
 +        rst_pin.trig = GPIO_TRIG_DISABLE;
 +        rst_pin.debounce = GPIO_DEBOUNCE_DISABLE;
-+        rst_pin.dev_name = "stmpe";   
++        rst_pin.dev_name = "stmpe";
 +
 +      ret = nomadik_gpio_setpinconfig(GPIO_PIN_77, &rst_pin);
 +        if (ret) {
@@ -180119,7 +180768,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +        }
 +      /*probe the STMPE device*/
 +      retval = STMPE2401_Init(STMPE0);        //, I2C0,0x86 );
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              printk("STMPE2401: Error in initializing STMPE0 device\n");
 +              return retval;
@@ -180128,13 +180777,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +      //retval = STMPE2401_Init(STMPE1, I2C0,0x88 );
 +      retval = STMPE2401_Init(STMPE1);        //, I2C0,0x88 );
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              printk("STMPE2401: Error in initializing STMPE1 device\n");
 +              return retval;
 +      }else
 +              printk("STMPE2401 Device %d Initialized\n",STMPE1);
-+      
++
 +      PinConfigSTMPE.Output_State = 0x000030; /*0x000020; 0000 0000 0000 0000 0010 0000 */
 +      PinConfigSTMPE.Direction = 0x351F30;    /*0011 0101 0001 1111 0011 0000*/
 +      PinConfigSTMPE.EdgeDetect = 0;
@@ -180142,17 +180791,17 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      PinConfigSTMPE.FallingEdge = 0;
 +      PinConfigSTMPE.PullUp = 0;
 +      PinConfigSTMPE.PullDown = 0;
-+      PinConfigSTMPE.AltFunctionUpper = 0;    
-+      PinConfigSTMPE.AltFunctionLower = 0;   
-+      
-+      
++      PinConfigSTMPE.AltFunctionUpper = 0;
++      PinConfigSTMPE.AltFunctionLower = 0;
++
++
 +      retval = STMPE2401_Gpio_Configuration( STMPE0, &PinConfigSTMPE);
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              printk("STMPE2401[0]: Error in GPIO configuration\n");
 +              return retval;
 +      }
-+      
++
 +      PinConfigSTMPE.Output_State = 0x08050B;         /*0x08040B;//0000 1000 0000 0100 0000 1011*/
 +      PinConfigSTMPE.Direction    = 0x18072F;         /*0001 1000 0000 0111 0010 1111*/
 +      PinConfigSTMPE.EdgeDetect = 0;
@@ -180162,40 +180811,40 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      PinConfigSTMPE.PullDown = 0;
 +      PinConfigSTMPE.AltFunctionUpper = 0;
 +      PinConfigSTMPE.AltFunctionLower = 0;
-+      
++
 +      retval = STMPE2401_Gpio_Configuration( STMPE1, &PinConfigSTMPE);
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              printk("STMPE2401[1]: Error in GPIO configuration\n");
 +              return retval;
 +      }
-+      
++
 +      PinConfig.mode = GPIO_MODE_SOFTWARE;
 +      PinConfig.direction = GPIO_DIR_INPUT;
 +      PinConfig.trig = GPIO_TRIG_FALLING_EDGE;
 +      PinConfig.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      
++
 +      /*init PWM*/
 +      retval = STMPE2401_PwmInit(STMPE0, STMPE2401_PWM1);
-+      if(retval != STMPE2401_OK)              
-+      {       
++      if(retval != STMPE2401_OK)
++      {
 +              printk("Error in Initializing PWM controller of STMPE%d device\n",STMPE0);
 +              return retval;
 +      }
 +      /*Set the WVGA backlight to the maximum upon system boot*/
 +      retval = STMPE2401_SetPwm(STMPE0, STMPE2401_PWM1, 255);
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              printk("Error in Setting PWM controller of STMPE%d device\n",STMPE0);
 +              return retval;
 +      }
 +      retval = STMPE2401_Interrupt_Init(STMPE0, STMP0_INTR, PinConfig);
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
 +      retval = STMPE2401_Interrupt_Init(STMPE1, STMP1_INTR, PinConfig);
-+      if(retval != STMPE2401_OK)              
++      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
@@ -180206,7 +180855,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              Devices[STMPE0].Syscon = 0x0E;
 +      } else
 +              printk("Error in enabling STMPE0 device...\n");
-+      
++
 +      /*FIXME - This must happen earlier, but we need STMPE to
 +       *  to get initialized to do this
 +       */
@@ -180214,20 +180863,20 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              printk("Platform Initialization of NHK15 failed\n");
 +              return  -EIO;
 +      }
-+      
-+      /*register the device as misc device*/  
++
++      /*register the device as misc device*/
 +      ret = misc_register(&stmpe_dev);
 +      if (ret) {
 +              printk("%s: could not register stmpe erro =%d", __FILE__,
 +                         ret);
 +              return ret;
 +      }
-+      
-+      /*storing the reset configuration value for both 
++
++      /*storing the reset configuration value for both
 +       * STMP0 and STMP1 when the system enters into deepsleep*/
 +      nomadik_gpio_slpmreg_config(GPIO_PIN_77);
 +      nomadik_gpio_slpmreg_config(GPIO_PIN_79);
-+      
++
 +      return retval;
 +}
 +
@@ -180238,12 +180887,12 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +*i2cnum  = index of Nomadik i2c controller
 +*i2c_address = STMPE2401 i2c adress
 +*/
-+t_STMPE2401_error STMPE2401_Init(uint8 stmpeId)       
++t_STMPE2401_error STMPE2401_Init(uint8 stmpeId)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      t_STMPE2401_info tempInfo;
 +      uint32 maxWait;
-+      
++
 +      if(stmpeId >= MAX_STMPE2401_DEVICE)
 +      {
 +              /*number of device exeded*/
@@ -180254,10 +180903,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              /*Set the device as initialized*/
 +              DeviceInitializationCheck |= DEVICE_MASK[stmpeId];
 +      }
-+      
++
 +      /*all function disabled*/
 +      Devices[stmpeId].Syscon = 0;
-+      
++
 +      /*soft reset*/
 +      retval = STMPE2401_WriteByte( stmpeId, SYSCON_Index, 0x80 );
 +      if(retval != STMPE2401_OK)
@@ -180288,11 +180937,11 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +t_STMPE2401_error STMPE2401_Info(uint8 stmpeId, t_STMPE2401_info *info )
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
-+      
-+      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); 
++
++      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
 +      retval = STMPE2401_Read( stmpeId,CHIP_ID_Index, &info->chip_ID, 1 );
 +      if(retval == STMPE2401_OK)
@@ -180303,7 +180952,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +}
 +
 +/*
-+* This function configure the STMPE2401 gpio  
++* This function configure the STMPE2401 gpio
 +* Parameter
 +* stmpeId = index of the device (0-3)
 +* config  = configuration structure
@@ -180315,62 +180964,62 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      uint32 tempLong;
 +      uint32 nByte;
 +      uint8 tempByte;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
 +      Devices[stmpeId].Gpio = *config;
-+      
++
 +      /*fill the temp buffer in the same order of STMPE internal register
 +       "GPSR_Msb_Index" is the first,  "GPAFR_L_Lsb_Index" the last
 +      */
-+      
-+      /*Output_State 
++
++      /*Output_State
 +      based on <Output_State> and <Direction>
 +      */
 +      tempLong = config->Output_State;
 +      /*tempLong &= Direction;*/                      /*remove input pin [..TBD..]*/
 +
 +      /*I2C slave internal address*/
-+      tempBuffer[0] = GPSR_Msb_Index; 
-+      
++      tempBuffer[0] = GPSR_Msb_Index;
++
 +      tempBuffer[1] = LONG_TO_MSB(tempLong);
 +      tempBuffer[2] = LONG_TO_CSB(tempLong);
 +      tempBuffer[3] = LONG_TO_LSB(tempLong);
-+      
++
 +      tempLong = ~config->Output_State;
-+      
++
 +      tempBuffer[4] = LONG_TO_MSB(tempLong);
 +      tempBuffer[5] = LONG_TO_CSB(tempLong);
 +      tempBuffer[6] = LONG_TO_LSB(tempLong);
-+      
++
 +      /*Direction configuration*/
 +      tempBuffer[7] = LONG_TO_MSB(config->Direction);
 +      tempBuffer[8] = LONG_TO_CSB(config->Direction);
 +      tempBuffer[9] = LONG_TO_LSB(config->Direction);
-+      
++
 +      /*Edge Detect Status register*/
 +      tempBuffer[10] = LONG_TO_MSB(config->EdgeDetect);
 +      tempBuffer[11] = LONG_TO_CSB(config->EdgeDetect);
 +      tempBuffer[12] = LONG_TO_LSB(config->EdgeDetect);
-+      
++
 +      /*Rising Edge register*/
 +      tempBuffer[13] = LONG_TO_MSB(config->RisingEdge);
 +      tempBuffer[14] = LONG_TO_CSB(config->RisingEdge);
 +      tempBuffer[15] = LONG_TO_LSB(config->RisingEdge);
-+      
++
 +      /*Falling Edge register*/
 +      tempBuffer[16] = LONG_TO_MSB(config->FallingEdge);
 +      tempBuffer[17] = LONG_TO_CSB(config->FallingEdge);
 +      tempBuffer[18] = LONG_TO_LSB(config->FallingEdge);
-+      
++
 +      /*Pull Up register*/
-+      tempBuffer[19] = LONG_TO_MSB(config->PullUp);   
++      tempBuffer[19] = LONG_TO_MSB(config->PullUp);
 +      tempBuffer[20] = LONG_TO_CSB(config->PullUp);
 +      tempBuffer[21] = LONG_TO_LSB(config->PullUp);
-+              
++
 +      /*Pull Down register*/
 +      tempBuffer[22] = LONG_TO_MSB(config->PullDown);
 +      tempBuffer[23] = LONG_TO_CSB(config->PullDown);
@@ -180380,13 +181029,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      tempBuffer[25] = LONG_TO_MSB(config->AltFunctionUpper);
 +      tempBuffer[26] = LONG_TO_CSB(config->AltFunctionUpper);
 +      tempBuffer[27] = LONG_TO_LSB(config->AltFunctionUpper);
-+      
++
 +      tempBuffer[28] = LONG_TO_MSB(config->AltFunctionLower);
 +      tempBuffer[29] = LONG_TO_CSB(config->AltFunctionLower);
 +      tempBuffer[30] = LONG_TO_LSB(config->AltFunctionLower);
-+      
++
 +      nByte = 31;
-+/*            
++/*
 +      retval = STMPE2401_Write(stmpeId, tempBuffer, nByte );
 +*/
 +      for(tempByte=1; tempByte<31; tempByte++)
@@ -180401,7 +181050,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +}
 +
 +
-+/* 
++/*
 +*This function read STMPE2401 gpio configuration and save it on *config
 +* Parameter
 +* stmpeId = index of the device (0-3)
@@ -180410,11 +181059,11 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +t_STMPE2401_error STMPE2401_Get_Gpio_Configuration(uint8 stmpeId, t_STMPE2401_gpio_config* config)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
-+      
-+      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); 
++
++      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
 +      /*read back configuration - FIXME TODO - currently not used
 +      memcpy(config, &Devices[stmpeId].Gpio, sizeof(t_STMPE2401_gpio_config));*/
@@ -180433,11 +181082,11 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 offset, DataValue;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
 +      /*register selection*/
 +      if(Value == 0)
@@ -180455,10 +181104,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      else
 +      {
 +              /*invalid value*/
-+              retval = STMPE2401_BAD_PARAMETER; 
-+              return retval;          
++              retval = STMPE2401_BAD_PARAMETER;
++              return retval;
 +      }
-+      
++
 +      if(PinIndex < 8)
 +      {
 +              /*XXX_Lsb_Index*/
@@ -180493,13 +181142,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 tempBuffer[3];
 +      uint8 offset,mask;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
-+      
++
 +      if(PinIndex < 8)
 +      {
 +              offset = GPMR_Lsb_Index;
@@ -180515,13 +181164,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              offset = GPMR_Msb_Index;
 +              mask = 1 << (PinIndex-16);
 +      }
-+      
++
 +      retval = STMPE2401_Read(stmpeId, offset,tempBuffer, 1 );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
-+      
++
 +      if((tempBuffer[0] & mask) == 0)
 +      {
 +              *Value = 0;
@@ -180545,34 +181194,34 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint32 tempLong;
-+      uint8 offset, tempbyte;                 
-+      
++      uint8 offset, tempbyte;
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
-+      
++
 +      /*read STMPE2401 configuration*/
 +      tempLong = Devices[stmpeId].Gpio.Direction;
 +      offset = GPDR_Msb_Index;
-+      
++
 +      retval = STMPE2401_Bit_Calc( PinIndex, Value, &offset, &tempLong, &tempbyte);
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
-+      }       
-+      
++              return retval;
++      }
++
 +      retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
-+      }       
-+      
++              return retval;
++      }
++
 +      /*save STMPE2401 configuration*/
 +      Devices[stmpeId].Gpio.Direction = tempLong;
-+      
-+      return retval;  
++
++      return retval;
 +}
 +
 +/*
@@ -180591,13 +181240,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 offset,tempbyte,tempValueFALL,tempValueRISE;
 +      uint32 tempLong;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
-+      
++
 +      switch(OffRiseFall)
 +      {
 +              case STMPE2401_NO_EDGE:
@@ -180620,44 +181269,44 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      retval = STMPE2401_BAD_PARAMETER;
 +                      break;
 +      }
-+      
++
 +      if(retval == STMPE2401_OK)
 +      {
 +              /*read STMPE2401 configuration*/
 +              tempLong = Devices[stmpeId].Gpio.FallingEdge;
 +              offset = GPFER_Msb_Index;
-+              
++
 +              retval = STMPE2401_Bit_Calc( PinIndex, tempValueFALL, &offset, &tempLong, &tempbyte);
 +              if(retval == STMPE2401_OK)
 +              {
 +                      retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte );
-+              }       
-+              
++              }
++
 +              if(retval == STMPE2401_OK)
 +              {
 +                      /*save STMPE2401 configuration*/
-+                      Devices[stmpeId].Gpio.FallingEdge = tempLong;                   
-+              }       
++                      Devices[stmpeId].Gpio.FallingEdge = tempLong;
++              }
 +      }
 +      if(retval == STMPE2401_OK)
-+      {       
++      {
 +              /*read STMPE2401 configuration*/
 +              tempLong = Devices[stmpeId].Gpio.RisingEdge;
 +              offset = GPRER_Msb_Index;
-+              
++
 +              retval = STMPE2401_Bit_Calc( PinIndex, tempValueRISE, &offset, &tempLong, &tempbyte);
 +              if(retval == STMPE2401_OK)
 +              {
 +                      retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte );
-+              }       
-+              
++              }
++
 +              if(retval == STMPE2401_OK)
 +              {
-+                      Devices[stmpeId].Gpio.RisingEdge = tempLong;                     
-+              }       
++                      Devices[stmpeId].Gpio.RisingEdge = tempLong;
++              }
 +      }
-+      
-+      return retval;  
++
++      return retval;
 +}
 +
 +/*
@@ -180673,23 +181322,23 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 tempBuffer[5];
-+      
-+      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); 
++
++      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
-+      
++
 +      retval = STMPE2401_Read(stmpeId, GPEDR_Msb_Index,tempBuffer, 3 );
-+      
++
 +      *status = (uint32) 0;
 +      *status = tempBuffer[0];
 +      *status = *status << 8;
 +      *status |= tempBuffer[1];
 +      *status = *status << 8;
 +      *status |= tempBuffer[2];
-+              
-+      return retval;  
++
++      return retval;
 +}
 +
 +/* This function reset STMPE2401 gpio edge detection status bits
@@ -180703,19 +181352,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 tempBuffer[5];
-+      
-+      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL ); 
++
++      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, (uint8)NULL );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
 +      tempBuffer[0] = GPEDR_Msb_Index;
 +      tempBuffer[1] = (mask >> 16) & 0xFF;
 +      tempBuffer[2] = (mask >> 8) & 0xFF;
-+      tempBuffer[3] = (mask ) & 0xFF;         
-+      
++      tempBuffer[3] = (mask ) & 0xFF;
++
 +      retval = STMPE2401_Write( stmpeId, tempBuffer, 4 );
-+      return retval;  
++      return retval;
 +}
 +
 +/*
@@ -180724,7 +181373,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + Parameter
 + stmpeId   = index of the device (0-3)
 + PinIndex  = pin to be set (0-23)
-+ OffUpDown = STMPE2401_FLOATING 
++ OffUpDown = STMPE2401_FLOATING
 +             STMPE2401_PULL_UP
 +             STMPE2401_PULL_DOWN
 +*/
@@ -180733,13 +181382,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 offset,tempbyte,tempValueUP,tempValueDOWN;
 +      uint32 tempLong;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
-+      
++
 +      switch(OffUpDown)
 +      {
 +              case STMPE2401_FLOATING:
@@ -180757,42 +181406,42 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              default :
 +                      retval = STMPE2401_BAD_PARAMETER;
 +                      break;
-+      }       
-+      
++      }
++
 +      if(retval == STMPE2401_OK)
 +      {
 +              tempLong = Devices[stmpeId].Gpio.PullUp;
 +              offset = GPPUR_Msb_Index;
-+              
++
 +              retval = STMPE2401_Bit_Calc( PinIndex, tempValueUP, &offset, &tempLong, &tempbyte);
 +              if(retval == STMPE2401_OK)
 +              {
 +                      retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte );
-+              }       
-+              
++              }
++
 +              if(retval == STMPE2401_OK)
 +              {
-+                      Devices[stmpeId].Gpio.PullUp = tempLong;                        
-+              }       
++                      Devices[stmpeId].Gpio.PullUp = tempLong;
++              }
 +      }
 +      if(retval == STMPE2401_OK)
-+      {       
++      {
 +              tempLong = Devices[stmpeId].Gpio.PullDown;
 +              offset = GPPDR_Msb_Index;
-+              
++
 +              retval = STMPE2401_Bit_Calc( PinIndex, tempValueDOWN, &offset, &tempLong, &tempbyte);
 +              if(retval == STMPE2401_OK)
 +              {
 +                      retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte );
-+              }       
-+              
++              }
++
 +              if(retval == STMPE2401_OK)
 +              {
-+                      Devices[stmpeId].Gpio.PullDown = tempLong;                       
-+              }       
++                      Devices[stmpeId].Gpio.PullDown = tempLong;
++              }
 +      }
-+      
-+      return retval;  
++
++      return retval;
 +}
 +
 +/*
@@ -180801,7 +181450,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + Parameter
 + stmpeId   = index of the device (0-3)
 + PinIndex  = pin to be set (0-23)
-+ OffUpDown = STMPE2401_PRIMARY_FUNCTION 
++ OffUpDown = STMPE2401_PRIMARY_FUNCTION
 +             STMPE2401_ALT_FUNCTION_1
 +             STMPE2401_ALT_FUNCTION_2
 +             STMPE2401_ALT_FUNCTION_3
@@ -180811,11 +181460,11 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 offset,tempbyte,shift;
 +      uint32 tempLong;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId, PinIndex );
 +      if(retval != STMPE2401_OK)
 +      {
-+              return retval; 
++              return retval;
 +      }
 +      if(Function > STMPE2401_ALT_FUNCTION_3)
 +      {
@@ -180834,17 +181483,17 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              offset = GPAFR_L_Lsb_Index;
 +              tempLong = Devices[stmpeId].Gpio.AltFunctionLower;
 +      }
-+      
++
 +      offset -= (PinIndex%12) / 4;
 +      shift   = (PinIndex%12) * 2;
-+      
++
 +      tempLong &=~ ((uint32)3 << shift);
 +      tempLong |=  ((uint32)Function << shift);
-+      
++
 +      tempbyte = tempLong >> (((PinIndex%12)/4) * 8);
-+      
++
 +      retval = STMPE2401_WriteByte( stmpeId, offset, tempbyte );
-+      
++
 +      if(retval == STMPE2401_OK)
 +      {
 +              if(PinIndex >= 12)
@@ -180860,7 +181509,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +}
 +
 +
-+/* 
++/*
 + This function init selected pwm channel
 + MUST be called after GPIO initializzation.
 +
@@ -180868,12 +181517,12 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + stmpeId   = index of the device (0-3)
 + channels  = bit mask, indicate channel to be initialized
 +             use STMPE2401_PWM1, STMPE2401_PWM2 or STMPE2401_PWM3
-+ 
-+*/ 
++
++*/
 +t_STMPE2401_error STMPE2401_PwmInit(uint8 stmpeId, uint8 channels)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
 +      if(retval != STMPE2401_OK)
 +      {
@@ -180888,7 +181537,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      {
 +              if(retval == STMPE2401_OK)
 +              {
-+                      retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM1_GPIO, STMPE2401_GPIO_OUT ); 
++                      retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM1_GPIO, STMPE2401_GPIO_OUT );
 +              }
 +              if(retval == STMPE2401_OK)
 +              {
@@ -180910,7 +181559,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      {
 +              if(retval == STMPE2401_OK)
 +              {
-+                      retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM3_GPIO, STMPE2401_GPIO_OUT ); 
++                      retval = STMPE2401_SetGpioDir( stmpeId, STMPE2401_PWM3_GPIO, STMPE2401_GPIO_OUT );
 +              }
 +              if(retval == STMPE2401_OK)
 +              {
@@ -180937,8 +181586,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + Parameter
 + stmpeId   = index of the device (0-3)
 + channel   = accept STMPE2401_PWM1, STMPE2401_PWM2 or STMPE2401_PWM3
-+ Value     = pwm value. Range 0-255. 
-+             - 0   = 0V 
++ Value     = pwm value. Range 0-255.
++             - 0   = 0V
 +             - 255 = 1,8V
 +*/
 +t_STMPE2401_error STMPE2401_SetPwm(uint8 stmpeId, uint8 channel, uint8 Value)
@@ -180948,30 +181597,30 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      uint8 tempAdd;
 +      uint16 Istructions[15];
 +      signed int sign = 0;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
-+      
++
 +      if((PwmInitializationCheck[stmpeId] & channel) == 0)
 +      {
 +              retval = STMPE2401_INITIALIZATION_ERROR;
 +              return retval;
 +      }
-+      
-+      /* 
++
++      /*
 +      Istruction calculation.
 +      example for set pwm at 100:
-+      
++
 +      adress  opcode         istruction
-+      -------------------------------- 
-+      
++      --------------------------------
++
 +      0000   00FF           SMAX               ; set output to 0V
 +      0001   00E4           RAMP_DN   64       ; step, immediate action
 +                     _label:
-+      0002   7F01           RAMP_UP_SLOW       ; 
++      0002   7F01           RAMP_UP_SLOW       ;
 +      0003   7F81           RAMP_DN_SLOW       ;
 +      0004   a002           BRANCH    _label   ; infinite loop
 +      */
@@ -181008,7 +181657,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      delta = Devices[stmpeId].Pwm.PwmValue - Value;
 +                      sign = -1;
 +              }
-+              
++
 +              if(Devices[stmpeId].Pwm.PwmValue == 0)
 +              {
 +                      Istructions[0] = SMAX_ISTRUCTION;
@@ -181039,14 +181688,14 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              }
 +              /*insert a semi-flat ramp*/
 +              tempAdd = len;
-+              
++
 +              if(sign == -1)
 +              {
 +                      /*slow ramp down  first, needed for direction inversion*/
 +                      Istructions[len] = RAMP_DN_SLOW;
-+                      len++;                  
++                      len++;
 +                      Istructions[len] = RAMP_UP_SLOW;
-+                      len++;          
++                      len++;
 +              }
 +              else
 +              {
@@ -181061,7 +181710,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              len++;
 +      }
 +      retval = STMPE2401_SetPwmIstructions( stmpeId,  channel, Istructions, len);
-+      
++
 +      if(retval == STMPE2401_OK)
 +      {
 +              Devices[stmpeId].Pwm.PwmValue = Value;
@@ -181070,9 +181719,9 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      {
 +              Devices[stmpeId].Pwm.PwmValue = 0;
 +      }
-+      
++
 +      return retval;
-+}     
++}
 +
 +/*
 + This function write end execute the pwm microcode passed by "*Istructions"
@@ -181082,34 +181731,34 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + channel      = accept STMPE2401_PWM1, STMPE2401_PWM2 or STMPE2401_PWM3
 + Istructions  = user microcode
 + len          = code len
-+*/ 
++*/
 +t_STMPE2401_error STMPE2401_SetPwmIstructions(uint8 stmpeId, uint8 channel, uint16 Istructions[],uint8 len)
 +{
-+      
++
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 tempbyte;
 +      uint8 tempbuffer[130], bufferLen;
 +      uint8 checkbuffer[130];
 +      t_STMPE2401_info tempInfo;
 +      uint8 i;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
-+      
++
 +      if((PwmInitializationCheck[stmpeId] & channel) == 0)
 +      {
 +              retval = STMPE2401_INITIALIZATION_ERROR;
 +              return retval;
 +      }
-+      
++
 +      if(len > 64)
 +      {
 +              /*max istruction allowed = 64*/
 +              retval = STMPE2401_BAD_PARAMETER;
-+              return retval;          
++              return retval;
 +      }
 +      switch(channel)
 +      {
@@ -181128,25 +181777,25 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      break;
 +      }
 +      bufferLen = 1;
-+      
++
 +      /*disable pwm channel*/
 +      tempbyte = Devices[stmpeId].Pwm.ControlRegister;
 +      tempbyte &=~ channel;
 +      retval = STMPE2401_WriteByte( stmpeId,PWMCS_Index, tempbyte );
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
 +      }
 +      /*dummy read*/
 +      i = 0;
 +      do
 +      {
-+              retval = STMPE2401_Info( stmpeId, &tempInfo );  
++              retval = STMPE2401_Info( stmpeId, &tempInfo );
 +              i++;
 +              if(i >= 10)
 +              {
 +                      /*execute max 10 tries*/
-+                      return retval;                  
++                      return retval;
 +              }
 +      }
 +      while(retval != STMPE2401_OK);
@@ -181160,19 +181809,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      }
 +      retval = STMPE2401_Write( stmpeId, tempbuffer, bufferLen );
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
 +      }
 +      /*dummy read*/
 +      i = 0;
 +      do
 +      {
-+              retval = STMPE2401_Info( stmpeId, &tempInfo );  
++              retval = STMPE2401_Info( stmpeId, &tempInfo );
 +              i++;
 +              if(i >= 10)
 +              {
 +                      /*execute max 10 tries*/
-+                      return retval;                  
++                      return retval;
 +              }
 +      }
 +      while(retval != STMPE2401_OK);
@@ -181193,9 +181842,9 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      Devices[stmpeId].Pwm.ControlRegister = tempbyte;
 +      retval = STMPE2401_WriteByte( stmpeId,PWMCS_Index, tempbyte );
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
-+      }       
++      }
 +      /*check if there is a invalid istruction*/
 +      retval = STMPE2401_Read( stmpeId,PWMCS_Index,&tempbyte, 1 );
 +      if(retval != STMPE2401_OK)
@@ -181217,12 +181866,12 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              schedule_work(&work0);
 +        else if(stmp_intr == STMP1_INTR)
 +                schedule_work(&work1);
-+      return IRQ_HANDLED;     
++      return IRQ_HANDLED;
 +}
 +
 +
 +/*
-+ This function init interrupt system base configuration and reset device 
++ This function init interrupt system base configuration and reset device
 + register to default.
 +
 + Parameter
@@ -181233,19 +181882,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +t_STMPE2401_error STMPE2401_Interrupt_Init(uint8 stmpeId,gpio_pin NdkPin, gpio_config NdkPinConfig)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
-+      uint8 tempBuffer[20],i ; 
-+      int err;        
++      uint8 tempBuffer[20],i ;
++      int err;
 +
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
-+      
++
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
 +
 +      /*reset to default value*/
-+      tempBuffer[0] = ICR_Lsb_Index;  
-+      
++      tempBuffer[0] = ICR_Lsb_Index;
++
 +      /*ICR_Lsb_Index contents*/
 +      switch(NdkPinConfig.trig)
 +      {
@@ -181262,7 +181911,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      tempBuffer[1] = 0x02;           /*edge (0x2) + falling (0x0)*/
 +                      break;
 +              case GPIO_TRIG_BOTH_EDGES:              /*Triggers an IT on a rising and a falling edge*/
-+                      retval = STMPE2401_BAD_PARAMETER;/*not allowed*/        
++                      retval = STMPE2401_BAD_PARAMETER;/*not allowed*/
 +                      break;
 +              case GPIO_TRIG_HIGH_LEVEL:              /*Triggers an IT on a high level*/
 +                      tempBuffer[1] = 0x04;           /*level (0x0) + high (0x4)*/
@@ -181272,57 +181921,57 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      break;
 +              default :
 +                      break;
-+      }    
-+      
++      }
++
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
 +
 +      /*saving configuration*/
-+      Devices[stmpeId].Interrupt.ControlReg = tempBuffer[1];  
-+      
++      Devices[stmpeId].Interrupt.ControlReg = tempBuffer[1];
++
 +      /*all interrupt disabled exept gpio */
 +      tempBuffer[2] = 0x01;
 +      tempBuffer[3] = 0x00;
-+      
++
 +      /*saving configuration*/
 +      /*gpio global interrupt source enabled by default,
 +      gpio single source are disabled in "GpioMaskReg"
 +      */
 +
-+      Devices[stmpeId].Interrupt.EnableReg = 0x0100;  
-+      
++      Devices[stmpeId].Interrupt.EnableReg = 0x0100;
++
 +      /*clear all interrupt flag*/
 +      tempBuffer[4] = 0x01;   /*ISR_Msb_Index*/
 +      tempBuffer[5] = 0xFF;   /*ISR_Lsb_Index*/
-+      
++
 +      /*all gpio interrupt disabled*/
 +      tempBuffer[6] = 0x00;   /*IEGPIOR_Msb_Index*/
 +      tempBuffer[7] = 0x00;   /*IEGPIOR_Csb_Index*/
 +      tempBuffer[8] = 0x00;   /*IEGPIOR_Lsb_Index*/
 +      /*saving configuration*/
 +      Devices[stmpeId].Interrupt.GpioMaskReg = 0;
-+      
++
 +      /*clear all gpio interrupt fl/seag*/
 +      tempBuffer[9]  = 0xFF;  /*IEGPIOR_Msb_Index*/
 +      tempBuffer[10] = 0xFF;  /*IEGPIOR_Csb_Index*/
 +      tempBuffer[11] = 0xFF;  /*IEGPIOR_Lsb_Index*/
-+      
++
 +      retval = STMPE2401_Write( stmpeId,tempBuffer, 12 );
-+      
++
 +      for(i=0;i<MAX_STMPE2401_CALLBACK;i++)
 +      {
 +              Devices[stmpeId].Interrupt.Callback[i] = &EmptyCallback;
-+              Devices[stmpeId].Interrupt.CallbackParam[i] = NULL;     
++              Devices[stmpeId].Interrupt.CallbackParam[i] = NULL;
 +      }
-+      
++
 +      CallbackInstallationCheck[stmpeId] = 0; /*no callback installed*/
-+      
++
 +      /*saving configuration*/
 +      Devices[stmpeId].Interrupt.NdkPin = NdkPin;
 +      Devices[stmpeId].Interrupt.NdkPinConfig = NdkPinConfig;
-+      
++
 +      /*apply configuration*/
 +      if(nomadik_gpio_setpinconfig(NdkPin,&NdkPinConfig) != GPIO_OK)
 +      {
@@ -181334,13 +181983,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              err = request_irq(IRQNO_GPIO(NdkPin), stmp_intr_handler , SA_TRIGGER_FALLING, "stmpe0", NULL);
 +      else
 +              err = request_irq(IRQNO_GPIO(NdkPin), stmp_intr_handler , SA_TRIGGER_FALLING, "stmpe1", NULL);
-+      
++
 +      if(err) {
 +              printk("unable to Request for the irq %d\n", NdkPin);
 +              return err;
 +      }
-+      /*Enable the global stmpe interrupt*/   
-+      retval = STMPE2401_InterruptAbilitation(stmpeId, STMPE2401_ENABLE_INTERRUPT );  
++      /*Enable the global stmpe interrupt*/
++      retval = STMPE2401_InterruptAbilitation(stmpeId, STMPE2401_ENABLE_INTERRUPT );
 +      if(retval != STMPE2401_OK)
 +        {
 +                return retval;
@@ -181351,21 +182000,21 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + This function init Keypad functions
 + Parameter
 + stmpeId      = index of the device (0-3)
-+ Settings     = keypad settings, Settings.scan field can be ignored for this 
++ Settings     = keypad settings, Settings.scan field can be ignored for this
 +                function, after initializzation is always STMPE2401_SCAN_OFF
-+*/ 
++*/
 +t_STMPE2401_error STMPE2401_Keypad_init(uint8 stmpeId, t_STMPE2401_key_config  Settings)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 tempBuffer[10];
 +      uint8 i;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
-+      
++
 +      /*settings verification*/
 +      if(Settings.columns > 0x00FF)
 +      {
@@ -181385,15 +182034,15 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      {
 +              retval = STMPE2401_BAD_PARAMETER;
 +      }
-+      
++
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
-+      
++
 +      /*setting GPIO alternate function
 +        columns 0-7 are connected to gpio 0-7*/
-+      for(i=0; i<8; i++ )  
++      for(i=0; i<8; i++ )
 +      {
 +              if((Settings.columns & (1<<i)) != 0)
 +              {
@@ -181407,17 +182056,17 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      if(retval != STMPE2401_OK)
 +                      {
 +                              return retval;
-+                      }               
++                      }
 +                      /*enable pull-up and disable pull-down*/
 +                      retval = STMPE2401_SetGpioPull( stmpeId,i, STMPE2401_PULL_UP );
 +                      if(retval != STMPE2401_OK)
 +                      {
 +                              return retval;
-+                      }                       
++                      }
 +              }
 +      }
 +      /*row 0-6 are connected to gpio 8-14*/
-+      for(i=0; i<=6; i++ )  
++      for(i=0; i<=6; i++ )
 +      {
 +              if((Settings.rows & (1<<i)) != 0)
 +              {
@@ -181437,11 +182086,11 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      if(retval != STMPE2401_OK)
 +                      {
 +                              return retval;
-+                      }                       
++                      }
 +              }
-+      }       
++      }
 +      /*row 7-11 are connected to gpio 16-20*/
-+      for(i=7; i<=11; i++ )  
++      for(i=7; i<=11; i++ )
 +      {
 +              if((Settings.rows & (1<<i)) != 0)
 +              {
@@ -181461,9 +182110,9 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      if(retval != STMPE2401_OK)
 +                      {
 +                              return retval;
-+                      }                       
++                      }
 +              }
-+      }               
++      }
 +      Settings.scan = STMPE2401_SCAN_OFF;
 +      /*save settings*/
 +      memcpy(&Devices[stmpeId].Key, &Settings, sizeof(t_STMPE2401_key_config));
@@ -181488,19 +182137,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + Parameter
 + stmpeId   = index of the device (0-3)
 + status    = STMPE2401_SCAN_ON or STMPE2401_SCAN_OFF
-+*/             
++*/
 +t_STMPE2401_error STMPE2401_Keypad_scan(uint8 stmpeId, uint8 status)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
 +      uint8 tempByte;
-+              
++
 +      retval = STMPE2401_Gpio_Parameter_Check(stmpeId,(uint8)NULL);
 +      if(retval != STMPE2401_OK)
 +      {
 +              return retval;
 +      }
 +      tempByte = (Devices[stmpeId].Key.debounce << 1);
-+      
++
 +      switch(status)
 +      {
 +              case STMPE2401_SCAN_ON:
@@ -181513,7 +182162,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      retval = STMPE2401_BAD_PARAMETER;
 +                      break;
 +      }
-+      
++
 +      if(retval == STMPE2401_OK)
 +      {
 +              retval = STMPE2401_WriteByte(stmpeId,KPC_CTRL_Lsb_Index, tempByte );
@@ -181530,7 +182179,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + Parameter
 + stmpeId   = index of the device (0-3)
 + keys      = keys pressed
-+*/             
++*/
 +t_STMPE2401_error STMPE2401_Keypressed(uint8 stmpeId, t_STMPE2401_key_status *keys)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
@@ -181538,10 +182187,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +      keys->buttonPressed = 0;
 +      keys->buttonReleased = 0;
-+      
++
 +      retval = STMPE2401_Read( stmpeId,KPC_DATA_BYTE0_Index,tempBuffer, 1 );
 +      retval = STMPE2401_Read( stmpeId,KPC_DATA_BYTE1_Index,&tempBuffer[1], 1 );
-+      
++
 +      if((tempBuffer[0] & STMPE2401_MASK_NO_KEY) != STMPE2401_MASK_NO_KEY )
 +      {
 +              if((tempBuffer[0] & 0x80) == 0)
@@ -181552,7 +182201,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              else
 +              {
 +                      keys->released[0] = tempBuffer[0] & 0x7F;
-+                      keys->buttonReleased++; 
++                      keys->buttonReleased++;
 +              }
 +      }
 +      if((tempBuffer[1] & STMPE2401_MASK_NO_KEY) != STMPE2401_MASK_NO_KEY )
@@ -181584,14 +182233,14 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      void *CallbackParam)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check( stmpeId,(uint8)NULL);
 +      if(HwSource >= MAX_STMPE2401_CALLBACK)
 +      {
 +              retval = STMPE2401_BAD_PARAMETER;
 +      }
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
 +      }
 +      switch(HwSource)
@@ -181618,7 +182267,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      retval = STMPE2401_FEAT_NOT_SUPPORTED;
 +                      break;
 +              default :
-+                                              
++
 +                      break;
 +      }
 +      Devices[stmpeId].Interrupt.Callback[HwSource] = Callback;
@@ -181638,14 +182287,14 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +t_STMPE2401_error STMPE2401_Remove_Callback(uint8 stmpeId, uint8 HwSource)
 +{
 +      t_STMPE2401_error retval = STMPE2401_OK;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check( stmpeId,(uint8)NULL);
 +      if(HwSource >= MAX_STMPE2401_CALLBACK)
 +      {
 +              retval = STMPE2401_BAD_PARAMETER;
 +      }
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
 +      }
 +      /*check if interrupt is already active*/
@@ -181659,22 +182308,22 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      }
 +      Devices[stmpeId].Interrupt.Callback[HwSource] = &EmptyCallback;
 +      Devices[stmpeId].Interrupt.CallbackParam[HwSource] = NULL;
-+      
++
 +      /*Set the callback as installed*/
 +      CallbackInstallationCheck[stmpeId] &=~ ((uint32)1 << HwSource);
-+      
++
 +      return retval;
 +}
 +
 +/*
 + This function enable/disable a interrupt source
-+ In case of interrupt abilitation the interrupt callback MUST be installed 
++ In case of interrupt abilitation the interrupt callback MUST be installed
 + first for safety pourpose.
 +
 + Parameter
 + stmpeId     = index of the device (0-3)
 + HwSource    = interrupt source
-+ Abilitation = state to be set (STMPE2401_ENABLE_INTERRUPT or 
++ Abilitation = state to be set (STMPE2401_ENABLE_INTERRUPT or
 +                                STMPE2401_DISABLE_INTERRUPT)
 +*/
 +t_STMPE2401_error STMPE2401_InterruptSourceAbilitation(uint8 stmpeId, uint8 HwSource, uint8 Abilitation )
@@ -181683,18 +182332,18 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      uint8 tempByte,offset;
 +      uint16 mask=0,tempWord;
 +      uint32 tempLong;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check( stmpeId,(uint8)NULL);
 +      if(HwSource >= MAX_STMPE2401_CALLBACK)
 +      {
 +              retval = STMPE2401_BAD_PARAMETER;
 +      }
-+      
++
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
 +      }
-+      
++
 +      switch(HwSource)
 +      {
 +              case STMPE2401_WAKEUP_IRQ:
@@ -181726,13 +182375,13 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      break;
 +      }
 +      if(retval != STMPE2401_OK)
-+      {       
++      {
 +              return retval;
 +      }
-+      
++
 +      tempWord = Devices[stmpeId].Interrupt.EnableReg;
 +      tempLong = Devices[stmpeId].Interrupt.GpioMaskReg;
-+      
++
 +      switch(Abilitation)
 +      {
 +              case STMPE2401_ENABLE_INTERRUPT:
@@ -181765,7 +182414,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      }
 +                      break;
 +              case STMPE2401_DISABLE_INTERRUPT:
-+                      
++
 +                      if(HwSource <= STMPE2401_GPIO_IRQ(23))
 +                      {
 +                              tempLong &=~ ((uint32)1 << HwSource);
@@ -181780,9 +182429,9 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      break;
 +      }
 +      if(retval == STMPE2401_OK)
-+      {       
++      {
 +              if(HwSource <= STMPE2401_GPIO_IRQ(23))
-+              {       
++              {
 +                      /*update only gpio mask register*/
 +                      tempByte = (tempLong >> ((HwSource / 8) * 8)) & 0xFF;
 +                      offset   = IEGPIOR_Lsb_Index - (HwSource / 8);
@@ -181795,10 +182444,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              }
 +      }
 +      if(retval == STMPE2401_OK)
-+      {       
++      {
 +              Devices[stmpeId].Interrupt.EnableReg = tempWord;
 +              Devices[stmpeId].Interrupt.GpioMaskReg = tempLong;
-+              
++
 +              if(Abilitation == STMPE2401_ENABLE_INTERRUPT)
 +              {
 +                      InterruptActive[stmpeId] |= ((uint32)1 << HwSource);
@@ -181809,7 +182458,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              }
 +      }
 +      return retval;
-+      
++
 +}
 +
 +/* Modified version : enables/disables only global interrupt inside the STMPE2401*/
@@ -181820,7 +182469,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +      tempByte[0] = Devices[stmpeId].Interrupt.ControlReg >>8;
 +      tempByte[1] = Devices[stmpeId].Interrupt.ControlReg & 0xFF;
-+      
++
 +      retval = STMPE2401_Gpio_Parameter_Check( stmpeId, (uint8)NULL);
 +      if(retval == STMPE2401_OK )
 +      {
@@ -181836,7 +182485,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                              /*clear Global Interrupt Mask bit*/
 +                              tempByte[1] &=~ 0x01;
 +                              Devices[stmpeId].Interrupt.ControlReg &=~ 0x01;
-+                              retval = STMPE2401_WriteByte( stmpeId,ICR_Lsb_Index, tempByte[1] );                             
++                              retval = STMPE2401_WriteByte( stmpeId,ICR_Lsb_Index, tempByte[1] );
 +                              /*clear pending flags ??*/
 +                              break;
 +                      default :
@@ -181858,7 +182507,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      tempBuffer[1] = (uint8)(irqSource >> 8);
 +      tempBuffer[2] = (uint8)(irqSource & 0xFF);
 +      err = STMPE2401_Write( stmpeId,tempBuffer, 3 );
-+      
++
 +      /* if it's a GPIO interrupt then acknowledge the GPIO interrupt status as well*/
 +      if(irqSource & 0x100)
 +      {
@@ -181874,7 +182523,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      return err;
 +}
 +
-+/*IRQ function. 
++/*IRQ function.
 +*/
 +static void nomadik_stmpe0_wq(void * data)
 +{
@@ -181884,10 +182533,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      uint16 irqSource = 0, shift;
 +      uint32 irqGpioSource = 0;
 +      /*unsigned long flags; */
-+      uint8 stmpeId = STMPE0; 
-+      
++      uint8 stmpeId = STMPE0;
++
 +      /*spin_lock_irqsave(&stmpe_list_lock, flags);*/
-+      /*check the interruption sources reading the "Interrupt status register" 
++      /*check the interruption sources reading the "Interrupt status register"
 +      and if needed "Interrupt status GPIO register"
 +      */
 +      err = STMPE2401_Read( stmpeId,ISR_Msb_Index, &tempBuffer[1], 2 );
@@ -181947,10 +182596,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                                      err = STMPE2401_Write( stmpeId, tempBuffer, 4 );
 +                              }
 +                      }
-+              }       
++              }
 +      }
 +      if(err == STMPE2401_OK)
-+      {       
++      {
 +              while(irqSource != 0)
 +              {
 +                      ISx = 8;
@@ -181973,7 +182622,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                              }
 +                              /*clear gpio request bit*/
 +                              irqGpioSource &=~ ((uint32)1 << ISGx);
-+                              vector = ISGx;                  
++                              vector = ISGx;
 +                              if(irqGpioSource == 0)
 +                              {
 +                                      /*no other gpio request, clear request bit*/
@@ -182008,7 +182657,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      {
 +                              err = STMPE2401_INTERNAL_ERROR;
 +                      }
-+                      
++
 +                      if(err == STMPE2401_OK)
 +                      {
 +                              /*Callback execution*/
@@ -182044,9 +182693,9 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      uint16 irqSource = 0, shift;
 +      uint32 irqGpioSource = 0;
 +      /*unsigned long flags; */
-+      uint8 stmpeId = STMPE1; 
++      uint8 stmpeId = STMPE1;
 +
-+      /*check the interruption sources reading the "Interrupt status register" 
++      /*check the interruption sources reading the "Interrupt status register"
 +      and if needed "Interrupt status GPIO register"
 +      */
 +      err = STMPE2401_Read( stmpeId,ISR_Msb_Index, &tempBuffer[1], 2 );
@@ -182056,7 +182705,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              irqSource =  irqSource << 8;
 +              irqSource |= tempBuffer[2];
 +              irqSource &= 0x1FF;     /*remove non ISx bits*/
-+              
++
 +              if(irqSource == 0)
 +              {
 +                      /*error, no STMPE2401 irq request find !!!*/
@@ -182067,8 +182716,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      /*write back flags for interrupt request clearing*/
 +                      tempBuffer[0] = ISR_Msb_Index;
 +                      err = STMPE2401_Write( stmpeId,tempBuffer, 3 );
-+                      
-+                      
++
++
 +                      if(irqSource & 0x100)
 +                      {
 +                              /*irqGpioSource*/
@@ -182077,7 +182726,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                              {
 +                                      irqGpioSource = (tempBuffer[1] << 16) | (tempBuffer[2] << 8) | (tempBuffer[3]);
 +                              }
-+                              
++
 +                              if(irqGpioSource == 0)
 +                              {
 +                                      /*error, no STMPE2401 gpio irq request find !!!*/
@@ -182111,10 +182760,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                              }
 +
 +                      }
-+              }       
++              }
 +      }
 +      if(err == STMPE2401_OK)
-+      {       
++      {
 +              while(irqSource != 0)
 +              {
 +                      ISx = 8;
@@ -182122,14 +182771,14 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      {
 +                              if((irqSource & shift) != 0)
 +                              {
-+                              
++
 +                                      break;
 +                              }
 +                              ISx --;
 +                      }
 +                      if(ISx == 8)
 +                      {
-+                              
++
 +                              for(ISGx=0;ISGx<24;ISGx ++ )
 +                              {
 +                                      if(irqGpioSource & ((uint32)1 << ISGx ))
@@ -182139,20 +182788,20 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                              }
 +                              /*clear gpio request bit*/
 +                              irqGpioSource &=~ ((uint32)1 << ISGx);
-+                              vector = ISGx;                  
-+                              
++                              vector = ISGx;
++
 +                              if(irqGpioSource == 0)
 +                              {
 +                                      /*no other gpio request, clear request bit*/
 +                                      irqSource &=~ 0x100;
 +                              }
-+                                      
++
 +                      }
 +                      else
 +                      {
 +                              /*clear request bit*/
 +                              irqSource &=~ shift;
-+                              
++
 +                              vector = ISx + STMPE2401_WAKEUP_IRQ;
 +                              if(vector >= STMPE2401_ROTATOR_IRQ)
 +                              {
@@ -182177,7 +182826,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +                      {
 +                              err = STMPE2401_INTERNAL_ERROR;
 +                      }
-+                      
++
 +                      if(err == STMPE2401_OK)
 +                      {
 +                              /*Callback execution*/
@@ -182211,7 +182860,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 + Parameter
 + stmpeId   = index of the device (0-3)
-+ PinIndex  = pin to be set (0-23) 
++ PinIndex  = pin to be set (0-23)
 +             use NULL if don't care
 +*/
 +static t_STMPE2401_error STMPE2401_Gpio_Parameter_Check(uint8 stmpeId, uint8 PinIndex)
@@ -182229,7 +182878,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      if(PinIndex >= MAX_STMPE2401_GPIO)
 +      {
 +              /*number of pin exceeded*/
-+              return STMPE2401_BAD_PARAMETER;         
++              return STMPE2401_BAD_PARAMETER;
 +      }
 +      return STMPE2401_OK;
 +}
@@ -182238,20 +182887,20 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 + This function execute common gpio bit calculation
 +
 + Parameter
-+ PinIndex  = pin to be set (0-23) 
++ PinIndex  = pin to be set (0-23)
 + PinValue  = value to be set (0-1)
 + Offset    = in  - base register XXXX_Msb_Index
-+             out - correct register 
++             out - correct register
 + RegValue  = in  - current register value
 +             out - new value
 +*/
 +static t_STMPE2401_error STMPE2401_Bit_Calc( uint8 PinIndex, uint8 PinValue,uint8 *Register, uint32 *RegValue, uint8 *RegByte)
 +{
 +      uint8 mask;
-+      
++
 +      mask = 1 << (PinIndex % 8);
 +      *RegByte = (*RegValue >> ((PinIndex / 8) * 8)) & 0xFF;
-+      
++
 +      if(PinValue == 0)
 +      {
 +              *RegByte  &=~ mask;
@@ -182283,7 +182932,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +/*
 + This function write via I2C on the selected STMPE2401
-+ the first BYTE must be the internal register offset. 
++ the first BYTE must be the internal register offset.
 +
 + Parameter
 + stmpeId   = index of the device (0-3)
@@ -182300,7 +182949,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +              ret_val=nomadik_i2c_write_register(I2C_STMPE1_CLIENT,&buffer[1],buffer[0],nByte);
 +      }
 +
-+      if (ret_val)    { 
++      if (ret_val)    {
 +              printk("Error in writing value to STMPE register\n");
 +              return ret_val;
 +      }
@@ -182328,7 +182977,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +
 +/*
 + This function read via I2C on the selected STMPE2401
-+ the first BYTE must be the internal register offset. 
++ the first BYTE must be the internal register offset.
 +
 + Parameter
 + stmpeId   = index of the device (0-3)
@@ -182338,15 +182987,15 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +*/
 +static t_STMPE2401_error STMPE2401_Read(uint8 stmpeId,uint8 offset,uint8 *buffer, uint8 nByte )
 +{
-+      int ret_val = 0;        
-+      
++      int ret_val = 0;
++
 +      if (stmpeId == STMPE0)  {
 +              ret_val=nomadik_i2c_read_register(I2C_STMPE0_CLIENT,(__u8 *)buffer,offset,nByte);
 +              if (ret_val) return ret_val;
 +      }else   {
 +              ret_val=nomadik_i2c_read_register(I2C_STMPE1_CLIENT,(__u8 *)buffer,offset,nByte);
 +              if (ret_val) return ret_val;
-+      }       
++      }
 +      return STMPE2401_OK;
 +}
 +
@@ -182382,7 +183031,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +{
 +      int i;
 +      t_STMPE2401_error err = STMPE2401_OK;
-+      
++
 +      for(i=0; i<2; i++)      {
 +              /*syscontrol*/
 +              STMPE2401_Read(i, SYSCON_Index, &syscont[i].syscon_data, 1);
@@ -182545,8 +183194,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      return err;
 +}
 +/*
-+ This function is used for disabled callback. 
-+ Reduce the danger of execution of null poiter. 
++ This function is used for disabled callback.
++ Reduce the danger of execution of null poiter.
 +*/
 +static void EmptyCallback(void *parameter)
 +{
@@ -182572,7 +183221,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +      STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_5,STMPE2401_PRIMARY_FUNCTION);
 +      STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_5,STMPE2401_GPIO_OUT );
 +      STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_5, 1);
-+      
++
 +      return 0;
 +}
 +#else
@@ -182608,7 +183257,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +EXPORT_SYMBOL(STMPE2401_ClearGpioEdgeStatus);
 +EXPORT_SYMBOL(STMPE2401_SetGpioEdgeDetect);
 +EXPORT_SYMBOL(STMPE2401_Install_Callback);
-+EXPORT_SYMBOL(STMPE2401_SetGpioDir); 
++EXPORT_SYMBOL(STMPE2401_SetGpioDir);
 +EXPORT_SYMBOL(STMPE2401_SetGpioAltFunction);
 +EXPORT_SYMBOL(STMPE2401_InterruptSourceAbilitation);
 +EXPORT_SYMBOL(STMPE2401_InterruptAbilitation);
@@ -182622,9 +183271,8 @@ diff -Nauprw linux-2.6.20/drivers/misc/pexp-nomadik.c ../new/linux-2.6.20/driver
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("ST Microelectronics");
 +MODULE_DESCRIPTION("STMPE driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers/misc/sif-nomadik.c
---- linux-2.6.20/drivers/misc/sif-nomadik.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/misc/sif-nomadik.c     2008-10-20 13:37:45.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/misc/sif-nomadik.c
 @@ -0,0 +1,560 @@
 +/*
 + * Overview:
@@ -182666,7 +183314,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +#include <asm/arch/debug.h>
 +#include <asm/arch/gpio.h>
 +
-+#define SIF_SDA               GPIO_PIN_4      
++#define SIF_SDA               GPIO_PIN_4
 +#define SIF_SCL               GPIO_PIN_5
 +#define SIF_SCEN      GPIO_PIN_6
 +
@@ -182745,9 +183393,9 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +#define SIF_GAMMA248          0x1E
 +#define SIF_GAMMA256          0x1F
 +
-+#define SIF_GAMMA_PVOLTAGE    0x20    
++#define SIF_GAMMA_PVOLTAGE    0x20
 +#define SIF_GAMMA_NVOLTAGE    0x21
-+#define SIF_DC_VCOM           0x22    
++#define SIF_DC_VCOM           0x22
 +
 +
 +/*file operation members*/
@@ -182823,7 +183471,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +                      }
 +        //GPIO_SetGpioPin(scl);
 +        sif_wait150ns(); // hold time
-+      
++
 +      nomadik_gpio_writepin(SIF_SCL,0,"sif");
 +        //GPIO_ClearGpioPin(scl);
 +}
@@ -182836,7 +183484,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +        unsigned char bit=0;
 +
 +        *p_databyte = 0x0;
-+/*    
++/*
 +      gpio_config.dev_name = "sif";
 +        gpio_config.mode = GPIO_MODE_SOFTWARE;
 +        gpio_config.direction = GPIO_DIR_OUTPUT;
@@ -182847,7 +183495,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +                       if (ret) {
 +                                printk("Error in setting GPIO_PIN_04");
 +                        }
-+*/    
++*/
 +        sif_wait150ns();
 +        // start
 +        //GPIO_ClearGpioPin(scen);
@@ -182864,7 +183512,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +        // Read bit
 +        sif_write_databit(1);
 +
-+      
++
 +      nomadik_gpio_resetpinconfig(SIF_SDA, "sif");
 +
 +        // turn-round cycle
@@ -182925,7 +183573,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +{
 +      int ret;
 +      gpio_config sif_pin;
-+      
++
 +      sif_pin.dev_name = "sif";
 +        sif_pin.mode = GPIO_MODE_SOFTWARE;
 +        sif_pin.direction = GPIO_DIR_OUTPUT;
@@ -182934,7 +183582,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +
 +        sif_pin.trig = GPIO_TRIG_LEAVE_UNCHANGED;
 +        sif_pin.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      
++
 +/*    ret = nomadik_gpio_setpinconfig(SIF_SDA, &sif_pin);
 +        if (ret) {
 +                printk("7)Error in setting GPIO_PIN_04");
@@ -182971,7 +183619,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +
 +      //udelay(100);
 +      sif_wait150ns();
-+      
++
 +      ret = nomadik_gpio_writepin(SIF_SCEN,1,"sif");
 +        if (ret) {
 +                printk("8)Error in setting GPIO_PIN_06");
@@ -182988,7 +183636,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +      struct bright bright;
 +      struct gamma gamma;
 +
-+              
++
 +      if (_IOC_DIR(cmd) & _IOC_READ)
 +              err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
 +      else if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -182997,7 +183645,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +              return -EFAULT;
 +
 +      switch (cmd) {
-+      
++
 +      case SIF_READ_CHIP_ID_REV:
 +              //copy_from_user(&bklight ,argp, sizeof(int));
 +              //sif_read(SIF_CHIPID_VER,&byte_val);
@@ -183008,7 +183656,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +              int __user *argp = (struct contrast __user *)arg;
 +              if (copy_from_user(&ctr ,argp, sizeof(struct contrast)))
 +                      return -EFAULT;
-+                      
++
 +              printk("RGB contrast = %x %x %x\n",ctr.r,ctr.g, ctr.b);
 +              sif_write(SIF_RGAIN_CONTRAST,ctr.r);
 +              sif_write(SIF_GGAIN_CONTRAST,ctr.g);
@@ -183022,19 +183670,19 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +                        return -EFAULT;
 +
 +              printk("RGB brightness = %x %x %x\n",bright.r,bright.g,bright.b);
-+               sif_write(SIF_OFFSET_RBRIGHTNESS,bright.r);    
-+               sif_write(SIF_OFFSET_GBRIGHTNESS,bright.g);    
-+               sif_write(SIF_OFFSET_BBRIGHTNESS,bright.b);    
++               sif_write(SIF_OFFSET_RBRIGHTNESS,bright.r);
++               sif_write(SIF_OFFSET_GBRIGHTNESS,bright.g);
++               sif_write(SIF_OFFSET_BBRIGHTNESS,bright.b);
 +              }
 +              break;
 +
 +      case SIF_GAMMA_CORRECTION:
 +              {
 +              int __user *argp = (struct gamma __user *)arg;
-+              
++
 +              if (copy_from_user(&gamma ,argp, sizeof(struct gamma)))
 +                        return -EFAULT;
-+              
++
 +              printk("gamma values = %x %x %x %x %x %x %x %x %x %x %x %x\n",gamma.gamma0,gamma.gamma8,gamma.gamma16,gamma.gamma32,gamma.gamma64,gamma.gamma96,gamma.gamma128,gamma.gamma192,gamma.gamma224,gamma.gamma240,gamma.gamma248,gamma.gamma256);
 +
 +              sif_write(SIF_GAMMA0, gamma.gamma0);
@@ -183050,7 +183698,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +              sif_write(SIF_GAMMA248, gamma.gamma248);
 +              sif_write(SIF_GAMMA256, gamma.gamma256);
 +              }
-+              break;  
++              break;
 +      default:
 +              return -EINVAL;
 +      }
@@ -183059,7 +183707,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +/**
 + * nomadik_sif_open - open sys call for sif device
 + * @inode: pointer to the inode structure for the sif device
-+ * @filp: pointer to the file structure for the sif device 
++ * @filp: pointer to the file structure for the sif device
 + *
 + * This function opens the sif device for file operations.
 + */
@@ -183070,7 +183718,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +
 +/**
 + * nomadik_sif_release - close sys call for sif device
-+ * @inode: pointer to the inode structure for the sif device 
++ * @inode: pointer to the inode structure for the sif device
 + * @filp: pointer to the file structure for the sif device
 + *
 + * This function is called when the sif device is closed.
@@ -183105,7 +183753,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +static int __init sif_nomadik_init(void)
 +{
 +      int ret=0;
-+      unsigned char byte_value;       
++      unsigned char byte_value;
 +
 +      gpio_config sif_pin;
 +      sif_pin.dev_name = "sif";
@@ -183113,7 +183761,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +        sif_pin.direction = GPIO_DIR_OUTPUT;
 +        sif_pin.trig = GPIO_TRIG_LEAVE_UNCHANGED;
 +        sif_pin.debounce = GPIO_DEBOUNCE_UNCHANGED;
-+      
++
 +      ret = nomadik_gpio_setpinconfig(SIF_SDA, &sif_pin);
 +        if (ret) {
 +                printk("9)Error in setting GPIO_PIN_04");
@@ -183133,7 +183781,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +      nomadik_gpio_writepin(SIF_SDA,0,"sif");
 +      nomadik_gpio_writepin(SIF_SCL,0,"sif");
 +      nomadik_gpio_writepin(SIF_SCEN,1,"sif");
-+      
++
 +
 +      ret = misc_register(&sif_dev);
 +      if (ret) {
@@ -183145,10 +183793,10 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +      sif_write(SIF_RGAIN_CONTRAST,24);
 +      sif_write(SIF_GGAIN_CONTRAST,23);
 +      sif_write(SIF_BGAIN_CONTRAST,23);
-+              
-+      sif_write(SIF_OFFSET_RBRIGHTNESS,63);   
-+      sif_write(SIF_OFFSET_GBRIGHTNESS,63);   
-+      sif_write(SIF_OFFSET_BBRIGHTNESS,63);   
++
++      sif_write(SIF_OFFSET_RBRIGHTNESS,63);
++      sif_write(SIF_OFFSET_GBRIGHTNESS,63);
++      sif_write(SIF_OFFSET_BBRIGHTNESS,63);
 +
 +      /*set the default gamma values */
 +      sif_write(SIF_GAMMA0, 0); //gamma.gamma0);
@@ -183177,7 +183825,7 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +      nomadik_gpio_resetpinconfig(SIF_SDA, "sif");
 +      nomadik_gpio_resetpinconfig(SIF_SCL, "sif");
 +      nomadik_gpio_resetpinconfig(SIF_SCEN, "sif");
-+      misc_deregister(&sif_dev);       
++      misc_deregister(&sif_dev);
 +      return;
 +}
 +
@@ -183186,10 +183834,11 @@ diff -Nauprw linux-2.6.20/drivers/misc/sif-nomadik.c ../new/linux-2.6.20/drivers
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("ST Microelectronics");
 +MODULE_DESCRIPTION("CLCD proptocol driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/drivers/mmc/Kconfig ../new/linux-2.6.20/drivers/mmc/Kconfig
---- linux-2.6.20/drivers/mmc/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mmc/Kconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -125,4 +125,31 @@ config MMC_TIFM_SD
+--- linux-2.6.20.orig/drivers/mmc/Kconfig
++++ linux-2.6.20/drivers/mmc/Kconfig
+@@ -123,6 +123,33 @@ config MMC_TIFM_SD
+         (TIFM_7XX1)'.
            To compile this driver as a module, choose M here: the
          module will be called tifm_sd.
  
@@ -183202,7 +183851,7 @@ diff -Nauprw linux-2.6.20/drivers/mmc/Kconfig ../new/linux-2.6.20/drivers/mmc/Kc
 +        Depends on Nomadik DMA driver.
 +
 +        If unsure, say N.
-+      choice 
++      choice
 +              prompt "Driver mode"
 +              depends on MMC_NOMADIK
 +              default NOMADIK_MMC_DMA
@@ -183210,7 +183859,7 @@ diff -Nauprw linux-2.6.20/drivers/mmc/Kconfig ../new/linux-2.6.20/drivers/mmc/Kc
 +              config NOMADIK_MMC_DMA
 +              depends on MMC_NOMADIK
 +              bool   "DMA mode"
-+              
++
 +              config NOMADIK_MMC_POLL
 +              depends on MMC_NOMADIK
 +              bool   "Polling mode"
@@ -183221,10 +183870,11 @@ diff -Nauprw linux-2.6.20/drivers/mmc/Kconfig ../new/linux-2.6.20/drivers/mmc/Kc
 +      endchoice
 +
  endmenu
-diff -Nauprw linux-2.6.20/drivers/mmc/Makefile ../new/linux-2.6.20/drivers/mmc/Makefile
---- linux-2.6.20/drivers/mmc/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mmc/Makefile   2007-11-21 11:51:41.000000000 +0530
-@@ -6,21 +6,22 @@
+--- linux-2.6.20.orig/drivers/mmc/Makefile
++++ linux-2.6.20/drivers/mmc/Makefile
+@@ -4,25 +4,26 @@
+ #
  # Core
  #
  obj-$(CONFIG_MMC)             += mmc_core.o
@@ -183251,9 +183901,10 @@ diff -Nauprw linux-2.6.20/drivers/mmc/Makefile ../new/linux-2.6.20/drivers/mmc/M
  obj-$(CONFIG_MMC_OMAP)                += omap.o
  obj-$(CONFIG_MMC_AT91)                += at91_mci.o
  obj-$(CONFIG_MMC_TIFM_SD)     += tifm_sd.o
-diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/mmc/mmc-nomadik.c
---- linux-2.6.20/drivers/mmc/mmc-nomadik.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mmc/mmc-nomadik.c      2007-11-21 11:51:42.000000000 +0530
+ mmc_core-y := mmc.o mmc_sysfs.o
+--- /dev/null
++++ linux-2.6.20/drivers/mmc/mmc-nomadik.c
 @@ -0,0 +1,1435 @@
 +/*
 + *  linux/drivers/mmc/mmc-nomadik.c - ARM PrimeCell MMCI PL180 driver
@@ -184240,7 +184891,7 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +      mmc = amba_get_drvdata(nomadik_mmc_dev);
 +      host = mmc_priv(mmc);
 +
-+//Adding This AK 
++//Adding This AK
 +#if 0
 +      nomadik_gpio_readpin(GPIO_PIN_FOR_IRQ(dev->irq[1]), &status);
 +      if (status)
@@ -184288,8 +184939,8 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +
 +
 +
-+//--- Changes this Callback Function . AK 
-+#if 1 //ak FOR TEST 
++//--- Changes this Callback Function . AK
++#if 1 //ak FOR TEST
 +static irqreturn_t nomadik_mmc_detect_int(int irq, void *dev_id)
 +{
 +      struct nomadik_mmci_host *host = (struct nomadik_mmci_host *)dev_id;
@@ -184307,11 +184958,11 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +      int err;
 +      unsigned char  byte_value;
 +      struct nomadik_mmci_host *host = (struct nomadik_mmci_host *)dev_id;
-+      int ret; 
++      int ret;
 +      /*
 +       * Used to implement S/W debounce
 +       */
-+      // --- Added Ak 
++      // --- Added Ak
 +      printk("\n Got the Card Dectect Interrupt\n") ;
 +    err = STMPE2401_GetGpioVal(STMPE1,EGPIO_PIN_7,&byte_value);
 +           if(err != STMPE2401_OK )
@@ -184445,7 +185096,7 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +      /*
 +       * Card detection interrupt request
 +       */
-+//   --- Addition Starts  AK 
++//   --- Addition Starts  AK
 +          err = STMPE2401_SetGpioVal(STMPE1,EGPIO_PIN_2, 0);
 +           if (err != STMPE2401_OK)
 +              {
@@ -184463,7 +185114,7 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +              }
 +              //err = STMPE2401_Install_Callback(STMPE1,EGPIO_PIN_7,(void *)nomadik_mmc_detect_int,host);
 +          err = STMPE2401_Install_Callback(STMPE1,EGPIO_PIN_7,(void *)nomadik_mmc_detect,host);
-+          
++
 +              if (err != STMPE2401_OK)
 +             {
 +                        DEBUG(KERN_ALERT "Couldn't setup codec callback\n");
@@ -184481,7 +185132,7 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +                                      DEBUG("Couldn't abilitate the codec source interrupt\n");
 +              }
 +                  udelay(50);
-+#if 0 //Ak for test 
++#if 0 //Ak for test
 +      ret = request_irq(dev->irq[1], nomadik_mmc_detect_int,
 +                        (SA_TRIGGER_RISING | SA_TRIGGER_FALLING),
 +                        "mmc_detect", host);
@@ -184690,10 +185341,11 @@ diff -Nauprw linux-2.6.20/drivers/mmc/mmc-nomadik.c ../new/linux-2.6.20/drivers/
 +MODULE_AUTHOR("Vaibhav Agarwal (vaibhav.agarwal@st.com)");
 +MODULE_DESCRIPTION("ARM PrimeCell PL180 Multimedia Card Interface driver");
 +MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/mtd/maps/Kconfig ../new/linux-2.6.20/drivers/mtd/maps/Kconfig
---- linux-2.6.20/drivers/mtd/maps/Kconfig      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/maps/Kconfig       2007-11-21 11:51:41.000000000 +0530
-@@ -69,6 +69,13 @@ config MTD_PHYSMAP_OF
+--- linux-2.6.20.orig/drivers/mtd/maps/Kconfig
++++ linux-2.6.20/drivers/mtd/maps/Kconfig
+@@ -67,10 +67,17 @@ config MTD_PHYSMAP_OF
+         This provides a 'mapping' driver which allows the NOR Flash and
+         ROM driver code to communicate with chips which are mapped
          physically into the CPU's memory. The mapping description here is
          taken from OF device tree.
  
@@ -184707,10 +185359,13 @@ diff -Nauprw linux-2.6.20/drivers/mtd/maps/Kconfig ../new/linux-2.6.20/drivers/m
  config MTD_SUN_UFLASH
        tristate "Sun Microsystems userflash support"
        depends on SPARC && MTD_CFI
-diff -Nauprw linux-2.6.20/drivers/mtd/maps/Makefile ../new/linux-2.6.20/drivers/mtd/maps/Makefile
---- linux-2.6.20/drivers/mtd/maps/Makefile     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/maps/Makefile      2007-11-21 11:51:41.000000000 +0530
-@@ -7,7 +7,12 @@ ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
+       help
+         This provides a 'mapping' driver which supports the way in
+--- linux-2.6.20.orig/drivers/mtd/maps/Makefile
++++ linux-2.6.20/drivers/mtd/maps/Makefile
+@@ -5,11 +5,16 @@
+ ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
  obj-$(CONFIG_MTD)             += map_funcs.o
  endif
  
@@ -184723,7 +185378,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/maps/Makefile ../new/linux-2.6.20/drivers/
  obj-$(CONFIG_MTD_CDB89712)    += cdb89712.o
  obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
  obj-$(CONFIG_MTD_BAST)                += bast-flash.o
-@@ -25,7 +30,7 @@ obj-$(CONFIG_MTD_MAINSTONE)  += mainstone
+ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
+ obj-$(CONFIG_MTD_DC21285)     += dc21285.o
+@@ -23,19 +28,19 @@ obj-$(CONFIG_MTD_TSUNAMI)  += tsunami_fla
+ obj-$(CONFIG_MTD_LUBBOCK)     += lubbock-flash.o
+ obj-$(CONFIG_MTD_MAINSTONE)   += mainstone-flash.o
  obj-$(CONFIG_MTD_MBX860)      += mbx860.o
  obj-$(CONFIG_MTD_CEIVA)               += ceiva.o
  obj-$(CONFIG_MTD_OCTAGON)     += octagon-5066.o
@@ -184732,7 +185391,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/maps/Makefile ../new/linux-2.6.20/drivers/
  obj-$(CONFIG_MTD_PHYSMAP_OF)  += physmap_of.o
  obj-$(CONFIG_MTD_PNC2000)     += pnc2000.o
  obj-$(CONFIG_MTD_PCMCIA)      += pcmciamtd.o
-@@ -33,7 +38,7 @@ obj-$(CONFIG_MTD_RPXLITE)    += rpxlite.o
+ obj-$(CONFIG_MTD_RPXLITE)     += rpxlite.o
  obj-$(CONFIG_MTD_TQM8XXL)     += tqm8xxl.o
  obj-$(CONFIG_MTD_SA1100)      += sa1100-flash.o
  obj-$(CONFIG_MTD_IPAQ)                += ipaq-flash.o
@@ -184741,15 +185400,18 @@ diff -Nauprw linux-2.6.20/drivers/mtd/maps/Makefile ../new/linux-2.6.20/drivers/
  obj-$(CONFIG_MTD_SC520CDP)    += sc520cdp.o
  obj-$(CONFIG_MTD_NETSC520)    += netsc520.o
  obj-$(CONFIG_MTD_TS5500)      += ts5500_flash.o
-@@ -72,3 +77,5 @@ obj-$(CONFIG_MTD_PLATRAM)    += plat-ram.o
+ obj-$(CONFIG_MTD_SUN_UFLASH)  += sun_uflash.o
+ obj-$(CONFIG_MTD_VMAX)                += vmax301.o
+@@ -70,5 +75,7 @@ obj-$(CONFIG_MTD_DMV182)     += dmv182.o
+ obj-$(CONFIG_MTD_SHARP_SL)    += sharpsl-flash.o
+ obj-$(CONFIG_MTD_PLATRAM)     += plat-ram.o
  obj-$(CONFIG_MTD_OMAP_NOR)    += omap_nor.o
  obj-$(CONFIG_MTD_MTX1)                += mtx-1_flash.o
  obj-$(CONFIG_MTD_TQM834x)     += tqm834x.o
 +
 +
-diff -Nauprw linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c ../new/linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c
---- linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c
 @@ -0,0 +1,411 @@
 +/*
 + * drivers/mtd/maps/norflash-nomadik.c
@@ -184760,14 +185422,14 @@ diff -Nauprw linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c ../new/linux-2.6.2
 + *
 + * Based on ADI BRH map written by Deepak Saxena
 + * Based on iq80310 map written by Nicolas Pitre
-+ * 
-+ * 02-05-2007: Sachin Verma (sachin.verma@st.com) 
++ *
++ * 02-05-2007: Sachin Verma (sachin.verma@st.com)
 + *  - Rewritten Driver to use standard kernel interfaces.
 + *  - Added Power Management Routines for suspend()/resume()
-+ *  - Removed static mtd_info structures, replacing them with platform data 
++ *  - Removed static mtd_info structures, replacing them with platform data
 + *  - Removed Header File asm/arch/norflash-nomadik.h
-+ * 
-+ * 
++ *
++ *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
@@ -185162,10 +185824,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/maps/norflash-nomadik.c ../new/linux-2.6.2
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("ST Microelectronics (prafulla.wadaskar@st.com)");
 +MODULE_DESCRIPTION("MTD map driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/drivers/mtd/nand/Kconfig ../new/linux-2.6.20/drivers/mtd/nand/Kconfig
---- linux-2.6.20/drivers/mtd/nand/Kconfig      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/nand/Kconfig       2007-11-21 11:51:41.000000000 +0530
-@@ -13,6 +13,12 @@ config MTD_NAND
+--- linux-2.6.20.orig/drivers/mtd/nand/Kconfig
++++ linux-2.6.20/drivers/mtd/nand/Kconfig
+@@ -11,10 +11,16 @@ config MTD_NAND
+       help
+         This enables support for accessing all type of NAND flash
          devices. For further information see
          <http://www.linux-mtd.infradead.org/doc/nand.html>.
  
@@ -185178,10 +185841,13 @@ diff -Nauprw linux-2.6.20/drivers/mtd/nand/Kconfig ../new/linux-2.6.20/drivers/m
  config MTD_NAND_VERIFY_WRITE
        bool "Verify NAND page writes"
        depends on MTD_NAND
-diff -Nauprw linux-2.6.20/drivers/mtd/nand/Makefile ../new/linux-2.6.20/drivers/mtd/nand/Makefile
---- linux-2.6.20/drivers/mtd/nand/Makefile     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/nand/Makefile      2007-11-21 11:51:41.000000000 +0530
-@@ -24,6 +24,11 @@ obj-$(CONFIG_MTD_NAND_NANDSIM)              += nands
+       help
+         This adds an extra check when data is written to the flash. The
+--- linux-2.6.20.orig/drivers/mtd/nand/Makefile
++++ linux-2.6.20/drivers/mtd/nand/Makefile
+@@ -22,8 +22,13 @@ obj-$(CONFIG_MTD_NAND_SHARPSL)              += sharp
+ obj-$(CONFIG_MTD_NAND_TS7250)         += ts7250.o
+ obj-$(CONFIG_MTD_NAND_NANDSIM)                += nandsim.o
  obj-$(CONFIG_MTD_NAND_CS553X)         += cs553x_nand.o
  obj-$(CONFIG_MTD_NAND_NDFC)           += ndfc.o
  obj-$(CONFIG_MTD_NAND_AT91)           += at91_nand.o
@@ -185193,9 +185859,8 @@ diff -Nauprw linux-2.6.20/drivers/mtd/nand/Makefile ../new/linux-2.6.20/drivers/
  
  nand-objs := nand_base.o nand_bbt.o
  cafe_nand-objs := cafe.o cafe_ecc.o
-diff -Nauprw linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c ../new/linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c
---- linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c   2008-07-04 23:45:21.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c
 @@ -0,0 +1,296 @@
 +/*
 + *  drivers/mtd/nand/nandflash-nomadik.c
@@ -185367,8 +186032,8 @@ diff -Nauprw linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c ../new/linux-2.6.
 +        data->chip.options |= NAND_OWN_BUFFERS;
 +
 +
-+      /* 
-+       * Scan to find existance of the device 
++      /*
++       * Scan to find existance of the device
 +       */
 +      if (nand_scan(&data->mtd, 1)) {
 +              ret = -ENXIO;
@@ -185394,7 +186059,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c ../new/linux-2.6.
 +}
 +
 +/**
-+ * nand_default_bbt - [NAND Interface] Select a default bad block table for the device 
++ * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
 + * @mtd:        MTD device structure
 + *
 + * This function selects the default bad block table
@@ -185493,10 +186158,101 @@ diff -Nauprw linux-2.6.20/drivers/mtd/nand/nandflash-nomadik.c ../new/linux-2.6.
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
 +MODULE_DESCRIPTION("NAND driver for Nomadik Platform");
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/drivers/mtd/onenand/generic.c
---- linux-2.6.20/drivers/mtd/onenand/generic.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/generic.c  2008-09-17 13:23:33.000000000 +0530
-@@ -19,6 +19,7 @@
+--- linux-2.6.20.orig/drivers/mtd/onenand/Kconfig
++++ linux-2.6.20/drivers/mtd/onenand/Kconfig
+@@ -1,39 +1,35 @@
+ #
+ # linux/drivers/mtd/onenand/Kconfig
+ #
+-menu "OneNAND Flash Device Drivers"
+-      depends on MTD != n
+-
+-config MTD_ONENAND
++menuconfig MTD_ONENAND
+       tristate "OneNAND Device Support"
+       depends on MTD
+       help
+         This enables support for accessing all type of OneNAND flash
+         devices. For further information see
+-        <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
++        <http://www.samsung.com/Products/Semiconductor/OneNAND/index.htm>
++if MTD_ONENAND
+ config MTD_ONENAND_VERIFY_WRITE
+       bool "Verify OneNAND page writes"
+-      depends on MTD_ONENAND
+       help
+         This adds an extra check when data is written to the flash. The
+         OneNAND flash device internally checks only bits transitioning
+         from 1 to 0. There is a rare possibility that even though the
+         device thinks the write was successful, a bit could have been
+         flipped accidentally due to device wear or something else.
+ config MTD_ONENAND_GENERIC
+       tristate "OneNAND Flash device via platform device driver"
+-      depends on MTD_ONENAND && ARM
++      depends on ARM
+       help
+         Support for OneNAND flash via platform device driver.
+ config MTD_ONENAND_OTP
+       bool "OneNAND OTP Support"
+-      depends on MTD_ONENAND
+       help
+         One Block of the NAND Flash Array memory is reserved as
+         a One-Time Programmable Block memory area.
+         Also, 1st Block of NAND Flash Array can be used as OTP.
+@@ -41,6 +37,30 @@ config MTD_ONENAND_OTP
+         operations as any other NAND Flash Array memory block.
+         OTP block cannot be erased.
+         OTP block is fully-guaranteed to be a valid block.
+-endmenu
++config MTD_ONENAND_2X_PROGRAM
++      bool "OneNAND 2X program support"
++      help
++        The 2X Program is an extension of Program Operation.
++        Since the device is equipped with two DataRAMs, and two-plane NAND
++        Flash memory array, these two component enables simultaneous program
++        of 4KiB. Plane1 has only even blocks such as block0, block2, block4
++        while Plane2 has only odd blocks such as block1, block3, block5.
++        So MTD regards it as 4KiB page size and 256KiB block size
++
++        Now the following chips support it. (KFXXX16Q2M)
++          Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
++          Mux:   KFM2G16Q2M, KFN4G16Q2M,
++
++        And more recent chips
++
++config MTD_ONENAND_SIM
++      tristate "OneNAND simulator support"
++      depends on MTD_PARTITIONS
++      help
++        The simulator may simulate various OneNAND flash chips for the
++        OneNAND MTD layer.
++
++endif # MTD_ONENAND
++
+--- linux-2.6.20.orig/drivers/mtd/onenand/Makefile
++++ linux-2.6.20/drivers/mtd/onenand/Makefile
+@@ -6,6 +6,9 @@
+ obj-$(CONFIG_MTD_ONENAND)             += onenand.o
+ # Board specific.
+ obj-$(CONFIG_MTD_ONENAND_GENERIC)     += generic.o
++# Simulator
++obj-$(CONFIG_MTD_ONENAND_SIM)         += onenand_sim.o
++
+ onenand-objs = onenand_base.o onenand_bbt.o
+--- linux-2.6.20.orig/drivers/mtd/onenand/generic.c
++++ linux-2.6.20/drivers/mtd/onenand/generic.c
+@@ -17,10 +17,11 @@
+ #include <linux/slab.h>
+ #include <linux/platform_device.h>
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/onenand.h>
  #include <linux/mtd/partitions.h>
@@ -185504,7 +186260,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/driv
  
  #include <asm/io.h>
  #include <asm/mach/flash.h>
-@@ -36,20 +37,30 @@ struct onenand_info {
+ #define DRIVER_NAME   "onenand"
+@@ -34,24 +35,34 @@ struct onenand_info {
+       struct mtd_info         mtd;
+       struct mtd_partition    *parts;
        struct onenand_chip     onenand;
  };
  
@@ -185538,7 +186298,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/driv
                err = -EBUSY;
                goto out_free_info;
        }
-@@ -96,11 +107,12 @@ out_free_info:
+       info->onenand.base = ioremap(res->start, size);
+@@ -94,15 +105,16 @@ out_free_info:
+       kfree(info);
        return err;
  }
  
@@ -185552,7 +186316,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/driv
        unsigned long size = res->end - res->start + 1;
  
        dev_set_drvdata(&pdev->dev, NULL);
-@@ -116,27 +128,57 @@ static int __devexit generic_onenand_rem
+       if (info) {
+@@ -114,31 +126,61 @@ static int __devexit generic_onenand_rem
+               onenand_release(&info->mtd);
+               release_mem_region(res->start, size);
                iounmap(info->onenand.base);
                kfree(info);
        }
@@ -185589,7 +186357,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/driv
 +#define nomadik_onenand_resume NULL
 +#endif
 +
-+static struct platform_driver generic_onenand_driver = { 
++static struct platform_driver generic_onenand_driver = {
        .probe          = generic_onenand_probe,
 -      .remove         = __devexit_p(generic_onenand_remove),
 +      .remove         = generic_onenand_remove,
@@ -185616,93 +186384,13 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/driv
  }
  
  module_init(generic_onenand_init);
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/Kconfig ../new/linux-2.6.20/drivers/mtd/onenand/Kconfig
---- linux-2.6.20/drivers/mtd/onenand/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/Kconfig    2008-11-19 16:47:03.000000000 +0530
-@@ -2,20 +2,17 @@
- # linux/drivers/mtd/onenand/Kconfig
- #
+ module_exit(generic_onenand_exit);
  
--menu "OneNAND Flash Device Drivers"
--      depends on MTD != n
--
--config MTD_ONENAND
-+menuconfig MTD_ONENAND
-       tristate "OneNAND Device Support"
-       depends on MTD
-       help
-         This enables support for accessing all type of OneNAND flash
-         devices. For further information see
--        <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
-+        <http://www.samsung.com/Products/Semiconductor/OneNAND/index.htm>
-+if MTD_ONENAND
- config MTD_ONENAND_VERIFY_WRITE
-       bool "Verify OneNAND page writes"
--      depends on MTD_ONENAND
-       help
-         This adds an extra check when data is written to the flash. The
-         OneNAND flash device internally checks only bits transitioning
-@@ -25,13 +22,12 @@ config MTD_ONENAND_VERIFY_WRITE
- config MTD_ONENAND_GENERIC
-       tristate "OneNAND Flash device via platform device driver"
--      depends on MTD_ONENAND && ARM
-+      depends on ARM
-       help
-         Support for OneNAND flash via platform device driver.
- config MTD_ONENAND_OTP
-       bool "OneNAND OTP Support"
--      depends on MTD_ONENAND
-       help
-         One Block of the NAND Flash Array memory is reserved as
-         a One-Time Programmable Block memory area.
-@@ -43,4 +39,28 @@ config MTD_ONENAND_OTP
-         OTP block is fully-guaranteed to be a valid block.
--endmenu
-+config MTD_ONENAND_2X_PROGRAM
-+      bool "OneNAND 2X program support"
-+      help
-+        The 2X Program is an extension of Program Operation.
-+        Since the device is equipped with two DataRAMs, and two-plane NAND
-+        Flash memory array, these two component enables simultaneous program
-+        of 4KiB. Plane1 has only even blocks such as block0, block2, block4
-+        while Plane2 has only odd blocks such as block1, block3, block5.
-+        So MTD regards it as 4KiB page size and 256KiB block size
-+
-+        Now the following chips support it. (KFXXX16Q2M)
-+          Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
-+          Mux:   KFM2G16Q2M, KFN4G16Q2M,
-+
-+        And more recent chips
-+
-+config MTD_ONENAND_SIM
-+      tristate "OneNAND simulator support"
-+      depends on MTD_PARTITIONS
-+      help
-+        The simulator may simulate various OneNAND flash chips for the
-+        OneNAND MTD layer.
-+
-+endif # MTD_ONENAND
-+
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/Makefile ../new/linux-2.6.20/drivers/mtd/onenand/Makefile
---- linux-2.6.20/drivers/mtd/onenand/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/Makefile   2008-11-19 16:47:03.000000000 +0530
-@@ -8,4 +8,7 @@ obj-$(CONFIG_MTD_ONENAND)              += onenand.o
- # Board specific.
- obj-$(CONFIG_MTD_ONENAND_GENERIC)     += generic.o
-+# Simulator
-+obj-$(CONFIG_MTD_ONENAND_SIM)         += onenand_sim.o
-+
- onenand-objs = onenand_base.o onenand_bbt.o
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_base.c
---- linux-2.6.20/drivers/mtd/onenand/onenand_base.c    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_base.c     2008-11-19 16:47:03.000000000 +0530
-@@ -33,8 +33,8 @@ static struct nand_ecclayout onenand_oob
+--- linux-2.6.20.orig/drivers/mtd/onenand/onenand_base.c
++++ linux-2.6.20/drivers/mtd/onenand/onenand_base.c
+@@ -31,12 +31,12 @@ static struct nand_ecclayout onenand_oob
+               24, 25, 26, 27, 28,
+               40, 41, 42, 43, 44,
                56, 57, 58, 59, 60,
                },
        .oobfree        = {
@@ -185713,7 +186401,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        }
  };
  
-@@ -61,6 +61,17 @@ static const unsigned char ffchars[] = {
+ /**
+  * onenand_oob_32 - oob info for middle (1KB) page
+@@ -59,10 +59,21 @@ static const unsigned char ffchars[] = {
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
  };
  
@@ -185731,7 +186423,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  /**
   * onenand_readw - [OneNAND Interface] Read OneNAND register
   * @param addr                address to read
-@@ -94,16 +105,9 @@ static void onenand_writew(unsigned shor
+  *
+  * Read OneNAND register
+@@ -92,20 +103,13 @@ static void onenand_writew(unsigned shor
+  *
+  * Setup Start Address 1 Register (F100h)
   */
  static int onenand_block_address(struct onenand_chip *this, int block)
  {
@@ -185749,7 +186445,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        return block;
  }
-@@ -118,17 +122,11 @@ static int onenand_block_address(struct 
+ /**
+@@ -116,21 +120,15 @@ static int onenand_block_address(struct 
+  *
+  * Setup Start Address 2 Register (F101h) for DDP
   */
  static int onenand_bufferram_address(struct onenand_chip *this, int block)
  {
@@ -185759,17 +186459,21 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 -
                if (block & this->density_mask)
 -                      dbs = 1;
-+              return ONENAND_DDP_CHIP1;
+-
 -              return (dbs << ONENAND_DDP_SHIFT);
 -      }
--
++              return ONENAND_DDP_CHIP1;
 -      return 0;
 +      return ONENAND_DDP_CHIP0;
  }
  
  /**
-@@ -214,6 +212,15 @@ static int onenand_command(struct mtd_in
+  * onenand_page_address - [DEFAULT] Get page address
+  * @param page                the page address
+@@ -212,20 +210,33 @@ static int onenand_command(struct mtd_in
+               break;
        default:
                block = (int) (addr >> this->erase_shift);
                page = (int) (addr >> this->page_shift);
@@ -185785,7 +186489,10 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                page &= this->page_mask;
                break;
        }
-@@ -224,6 +231,10 @@ static int onenand_command(struct mtd_in
+       /* NOTE: The setting order of the registers is very important! */
+       if (cmd == ONENAND_CMD_BUFFERRAM) {
+               /* Select DataRAM for DDP */
                value = onenand_bufferram_address(this, block);
                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
  
@@ -185796,7 +186503,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                /* Switch to the next data buffer */
                ONENAND_SET_NEXT_BUFFERRAM(this);
  
-@@ -255,6 +266,8 @@ static int onenand_command(struct mtd_in
+               return 0;
+       }
+@@ -253,10 +264,12 @@ static int onenand_command(struct mtd_in
+                       dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
+                       readcmd = 1;
                        break;
  
                default:
@@ -185805,7 +186516,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                        dataram = ONENAND_CURRENT_BUFFERRAM(this);
                        break;
                }
-@@ -317,23 +330,28 @@ static int onenand_wait(struct mtd_info 
+               /* Write 'FPA, FSA' of Flash */
+@@ -315,27 +328,32 @@ static int onenand_wait(struct mtd_info 
+       interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
        ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
  
        if (ctrl & ONENAND_CTRL_ERROR) {
@@ -185840,7 +186555,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        return 0;
  }
-@@ -347,7 +365,7 @@ static int onenand_wait(struct mtd_info 
+ /*
+@@ -345,11 +363,11 @@ static int onenand_wait(struct mtd_info 
+  *
+  * complete the work
   */
  static irqreturn_t onenand_interrupt(int irq, void *data)
  {
@@ -185849,7 +186568,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* To handle shared interrupt */
        if (!this->complete.done)
-@@ -450,8 +468,9 @@ static inline int onenand_bufferram_offs
+               complete(&this->complete);
+@@ -448,12 +466,13 @@ static void onenand_setup_wait(struct mt
+ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
+ {
        struct onenand_chip *this = mtd->priv;
  
        if (ONENAND_CURRENT_BUFFERRAM(this)) {
@@ -185860,7 +186583,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                if (area == ONENAND_SPARERAM)
                        return mtd->oobsize;
        }
-@@ -474,14 +493,12 @@ static int onenand_read_bufferram(struct
+       return 0;
+@@ -472,28 +491,24 @@ static inline int onenand_bufferram_offs
+ static int onenand_read_bufferram(struct mtd_info *mtd, int area,
+               unsigned char *buffer, int offset, size_t count)
  {
        struct onenand_chip *this = mtd->priv;
        void __iomem *bufferram;
@@ -185876,7 +186603,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                /* Align with word(16-bit) size */
                count--;
  
-@@ -489,9 +506,7 @@ static int onenand_read_bufferram(struct
+               /* Read word and save byte */
                word = this->read_word(bufferram + offset + count);
                buffer[count] = (word & 0xff);
        }
@@ -185887,7 +186614,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        return 0;
  }
  
-@@ -510,7 +525,7 @@ static int onenand_sync_read_bufferram(s
+ /**
+  * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
+@@ -508,11 +523,11 @@ static int onenand_read_bufferram(struct
+ static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
+               unsigned char *buffer, int offset, size_t count)
  {
        struct onenand_chip *this = mtd->priv;
        void __iomem *bufferram;
@@ -185896,7 +186627,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        bufferram = this->base + area;
  
        bufferram += onenand_bufferram_offset(mtd, area);
-@@ -528,8 +543,7 @@ static int onenand_sync_read_bufferram(s
+       this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
+@@ -526,12 +541,11 @@ static int onenand_sync_read_bufferram(s
+               /* Read word and save byte */
+               word = this->read_word(bufferram + offset + count);
                buffer[count] = (word & 0xff);
        }
  
@@ -185906,7 +186641,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        this->mmcontrol(mtd, 0);
  
        return 0;
-@@ -550,6 +564,7 @@ static int onenand_write_bufferram(struc
+ }
+@@ -548,10 +562,11 @@ static int onenand_sync_read_bufferram(s
+ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
+               const unsigned char *buffer, int offset, size_t count)
  {
        struct onenand_chip *this = mtd->priv;
        void __iomem *bufferram;
@@ -185914,7 +186653,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        bufferram = this->base + area;
  
-@@ -571,12 +586,35 @@ static int onenand_write_bufferram(struc
+       bufferram += onenand_bufferram_offset(mtd, area);
+@@ -569,77 +584,134 @@ static int onenand_write_bufferram(struc
+               word = this->read_word(bufferram + byte_offset);
+               word = (word & ~0xff) | buffer[count];
                this->write_word(word, bufferram + byte_offset);
        }
  
@@ -185952,7 +186695,10 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
   * onenand_check_bufferram - [GENERIC] Check BufferRAM information
   * @param mtd         MTD data structure
   * @param addr                address to check
-@@ -587,22 +625,35 @@ static int onenand_write_bufferram(struc
+  * @return            1 if there are valid data, otherwise 0
+  *
+  * Check bufferram if there is data we required
+  */
  static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
  {
        struct onenand_chip *this = mtd->priv;
@@ -185999,7 +186745,10 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -613,31 +664,52 @@ static int onenand_check_bufferram(struc
+  * onenand_update_bufferram - [GENERIC] Update BufferRAM information
+  * @param mtd         MTD data structure
+  * @param addr                address to update
+  * @param valid               valid flag
   *
   * Update BufferRAM information
   */
@@ -186068,7 +186817,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -694,38 +766,85 @@ static void onenand_release_device(struc
+  * onenand_get_device - [GENERIC] Get chip for selected access
+  * @param mtd         MTD device structure
+@@ -692,167 +764,246 @@ static void onenand_release_device(struc
+       wake_up(&this->wq);
+       spin_unlock(&this->chip_lock);
  }
  
  /**
@@ -186171,7 +186924,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        stats = mtd->ecc_stats;
  
        /* Read-while-load method */
-@@ -733,47 +852,64 @@ static int onenand_read(struct mtd_info 
        /* Do first load to bufferRAM */
        if (read < len) {
                if (!onenand_check_bufferram(mtd, from)) {
@@ -186220,11 +186973,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 +              if (oobbuf) {
 +                      thisooblen = oobsize - oobcolumn;
 +                      thisooblen = min_t(int, thisooblen, ooblen - oobread);
-+                      
++
 +                      if (ops->mode == MTD_OOB_AUTO){
 +                              onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
 +                      }
-+                      else{   
++                      else{
 +                              this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
 +                      }
 +                      oobread += thisooblen;
@@ -186248,7 +187001,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                column = 0;
                cond_resched();
                /* Now wait for load */
-@@ -781,76 +917,91 @@ static int onenand_read(struct mtd_info 
+               ret = this->wait(mtd, FL_READING);
                onenand_update_bufferram(mtd, from, !ret);
        }
  
@@ -186368,7 +187121,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                }
  
                read += thislen;
-@@ -868,27 +1019,185 @@ int onenand_do_read_oob(struct mtd_info 
+               if (read == len)
+@@ -866,184 +1017,417 @@ int onenand_do_read_oob(struct mtd_info 
+                       from += mtd->writesize;
+                       column = 0;
                }
        }
  
@@ -186459,7 +187216,9 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 +      unsigned long timeout;
 +      unsigned int interrupt;
 +      unsigned int ctrl;
-+
+-      return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen,
+-                                 &ops->oobretlen, ops->oobbuf);
 +      /* The 20 msec is enough */
 +      timeout = jiffies + msecs_to_jiffies(20);
 +      while (time_before(jiffies, timeout)) {
@@ -186500,7 +187259,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 + *
 + * OneNAND read out-of-band data from the spare area for bbt scan
 + */
-+int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, 
++int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
 +                          struct mtd_oob_ops *ops)
 +{
 +      struct onenand_chip *this = mtd->priv;
@@ -186545,9 +187304,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 +                      break;
 +
 +              buf += thislen;
--      return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen,
--                                 &ops->oobretlen, ops->oobbuf);
++
 +              /* Read more? */
 +              if (read < len) {
 +                      /* Update Page size */
@@ -186564,7 +187321,8 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
-@@ -897,14 +1206,11 @@ static int onenand_read_oob(struct mtd_i
+ /**
+  * onenand_verify_oob - [GENERIC] verify the oob contents after a write
   * @param mtd         MTD device structure
   * @param buf         the databuffer to verify
   * @param to          offset to read from
@@ -186581,7 +187339,8 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        int status, i;
  
        this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
-@@ -913,33 +1219,37 @@ static int onenand_verify_oob(struct mtd
+       onenand_update_bufferram(mtd, to, 0);
+       status = this->wait(mtd, FL_READING);
        if (status)
                return status;
  
@@ -186632,7 +187391,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        ret = this->wait(mtd, FL_READING);
        if (ret)
-@@ -947,101 +1257,175 @@ static int onenand_verify_page(struct mt
+               return ret;
  
        onenand_update_bufferram(mtd, addr, 1);
  
@@ -186844,7 +187603,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                        break;
                }
  
-@@ -1058,118 +1442,191 @@ static int onenand_write(struct mtd_info
+               written += thislen;
+@@ -1056,122 +1440,195 @@ static int onenand_write(struct mtd_info
+       }
        /* Deselect and wake up anyone waiting on the device */
        onenand_release_device(mtd);
  
@@ -186990,7 +187753,8 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 +
 +      return ret;
 +}
-+
+-      *retlen = written;
 +/**
 + * onenand_write - [MTD Interface] write buffer to FLASH
 + * @param mtd         MTD device structure
@@ -187012,11 +187776,10 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
 +      };
 +      int ret;
  
--      *retlen = written;
 +      onenand_get_device(mtd, FL_WRITING);
 +      ret = onenand_write_ops_nolock(mtd, to, &ops);
 +      onenand_release_device(mtd);
++
 +      *retlen = ops.retlen;
        return ret;
  }
@@ -187074,7 +187837,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  {
        struct onenand_chip *this = mtd->priv;
        struct bbm_info *bbm = this->bbm;
-@@ -1199,19 +1656,19 @@ static int onenand_erase(struct mtd_info
+       /* Return info from the table */
+@@ -1197,23 +1654,23 @@ static int onenand_erase(struct mtd_info
+       block_size = (1 << this->erase_shift);
  
        /* Start address must align on block boundary */
        if (unlikely(instr->addr & (block_size - 1))) {
@@ -187097,7 +187864,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                return -EINVAL;
        }
  
-@@ -1230,7 +1687,7 @@ static int onenand_erase(struct mtd_info
+       instr->fail_addr = 0xffffffff;
+@@ -1228,22 +1685,24 @@ static int onenand_erase(struct mtd_info
+       while (len) {
                cond_resched();
  
                /* Check if we have a bad block, we do not erase bad blocks */
@@ -187106,7 +187877,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                        printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
-@@ -1238,10 +1695,12 @@ static int onenand_erase(struct mtd_info
+               }
  
                this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
  
@@ -187120,7 +187891,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                        instr->state = MTD_ERASE_FAILED;
                        instr->fail_addr = addr;
                        goto erase_exit;
-@@ -1256,13 +1715,14 @@ static int onenand_erase(struct mtd_info
+               }
+@@ -1254,17 +1713,18 @@ static int onenand_erase(struct mtd_info
+       instr->state = MTD_ERASE_DONE;
  erase_exit:
  
        ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
@@ -187138,7 +187913,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        return ret;
  }
  
-@@ -1292,11 +1752,16 @@ static void onenand_sync(struct mtd_info
+ /**
+  * onenand_sync - [MTD Interface] sync
+@@ -1290,15 +1750,20 @@ static void onenand_sync(struct mtd_info
+  *
+  * Check whether the block is bad
   */
  static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
  {
@@ -187156,7 +187935,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -1312,7 +1777,12 @@ static int onenand_default_block_markbad
+  * onenand_default_block_markbad - [DEFAULT] mark a block bad
+  * @param mtd         MTD device structure
+@@ -1310,21 +1775,26 @@ static int onenand_block_isbad(struct mt
+ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
+ {
        struct onenand_chip *this = mtd->priv;
        struct bbm_info *bbm = this->bbm;
        u_char buf[2] = {0, 0};
@@ -187170,7 +187953,9 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        int block;
  
        /* Get block number */
-@@ -1322,7 +1792,7 @@ static int onenand_default_block_markbad
+       block = ((int) ofs) >> bbm->bbt_erase_shift;
+         if (bbm->bbt)
+                 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
  
          /* We write two bytes, so we dont have to mess with 16 bit access */
          ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
@@ -187179,7 +187964,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -1345,7 +1815,10 @@ static int onenand_block_markbad(struct 
+  * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
+  * @param mtd         MTD device structure
+@@ -1343,18 +1813,22 @@ static int onenand_block_markbad(struct 
+               if (ret > 0)
+                       return 0;
                return ret;
        }
  
@@ -187191,7 +187980,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -1353,6 +1826,7 @@ static int onenand_block_markbad(struct 
+  * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
   * @param mtd         MTD device structure
   * @param ofs         offset relative to mtd start
   * @param len         number of bytes to lock or unlock
@@ -187199,7 +187988,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
   *
   * Lock or unlock one or more blocks
   */
-@@ -1435,7 +1909,12 @@ static int onenand_do_lock_cmd(struct mt
+ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
+ {
+@@ -1433,11 +1907,16 @@ static int onenand_do_lock_cmd(struct mt
+  *
+  * Lock one or more blocks
   */
  static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
  {
@@ -187213,7 +188006,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -1448,7 +1927,12 @@ static int onenand_lock(struct mtd_info 
+  * onenand_unlock - [MTD Interface] Unlock block(s)
+  * @param mtd         MTD device structure
+@@ -1446,11 +1925,16 @@ static int onenand_lock(struct mtd_info 
+  *
+  * Unlock one or more blocks
   */
  static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
  {
@@ -187227,7 +188024,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -1491,6 +1975,8 @@ static int onenand_unlock_all(struct mtd
+  * onenand_check_lock_status - [OneNAND Interface] Check lock status
+  * @param this                onenand chip data structure
+@@ -1489,10 +1973,12 @@ static void onenand_check_lock_status(st
+ static int onenand_unlock_all(struct mtd_info *mtd)
+ {
        struct onenand_chip *this = mtd->priv;
  
        if (this->options & ONENAND_HAS_UNLOCK_ALL) {
@@ -187236,7 +188037,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                /* Write unlock command */
                this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
  
-@@ -1503,15 +1989,12 @@ static int onenand_unlock_all(struct mtd
+               /* There's no return value */
+               this->wait(mtd, FL_LOCKING);
+@@ -1501,27 +1987,24 @@ static int onenand_unlock_all(struct mtd
+               while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+                   & ONENAND_CTRL_ONGO)
                        continue;
  
                /* Workaround for all block unlock in DDP */
@@ -187256,7 +188061,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
                }
  
                onenand_check_lock_status(this);
-@@ -1519,7 +2002,7 @@ static int onenand_unlock_all(struct mtd
                return 0;
        }
  
@@ -187265,7 +188070,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        return 0;
  }
-@@ -1544,13 +2027,19 @@ static int do_otp_read(struct mtd_info *
+ #ifdef CONFIG_MTD_ONENAND_OTP
+@@ -1542,17 +2025,23 @@ typedef int (*otp_op_t)(struct mtd_info 
+  */
+ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
                size_t *retlen, u_char *buf)
  {
        struct onenand_chip *this = mtd->priv;
@@ -187286,7 +188095,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* Exit OTP access mode */
        this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-@@ -1562,19 +2051,20 @@ static int do_otp_read(struct mtd_info *
+       this->wait(mtd, FL_RESETING);
+@@ -1560,23 +2049,24 @@ static int do_otp_read(struct mtd_info *
+ }
  /**
   * do_otp_write - [DEFAULT] Write OTP block area
   * @param mtd         MTD device structure
@@ -187309,7 +188122,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* Force buffer page aligned */
        if (len < mtd->writesize) {
-@@ -1588,7 +2078,12 @@ static int do_otp_write(struct mtd_info 
+               memcpy(this->page_buf, buf, len);
+               memset(this->page_buf + len, 0xff, mtd->writesize - len);
+@@ -1586,11 +2076,16 @@ static int do_otp_write(struct mtd_info 
+       /* Enter OTP access mode */
        this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
        this->wait(mtd, FL_OTPING);
  
@@ -187323,7 +188140,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* Exit OTP access mode */
        this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-@@ -1611,13 +2106,21 @@ static int do_otp_lock(struct mtd_info *
+       this->wait(mtd, FL_RESETING);
+@@ -1609,17 +2104,25 @@ static int do_otp_write(struct mtd_info 
+  */
+ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
                size_t *retlen, u_char *buf)
  {
        struct onenand_chip *this = mtd->priv;
@@ -187346,7 +188167,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* Exit OTP access mode */
        this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-@@ -1664,13 +2167,16 @@ static int onenand_otp_walk(struct mtd_i
+       this->wait(mtd, FL_RESETING);
+@@ -1662,17 +2165,20 @@ static int onenand_otp_walk(struct mtd_i
+       /* Check User/Factory boundary */
        if (((mtd->writesize * otp_pages) - (from + len)) < 0)
                return 0;
  
@@ -187365,7 +188190,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
                        otpinfo = (struct otp_info *) buf;
                        otpinfo->start = from;
-@@ -1690,13 +2196,14 @@ static int onenand_otp_walk(struct mtd_i
+                       otpinfo->length = mtd->writesize;
+                       otpinfo->locked = 0;
+@@ -1688,17 +2194,18 @@ static int onenand_otp_walk(struct mtd_i
+                       buf += size;
                        len -= size;
                        *retlen += size;
  
@@ -187383,7 +188212,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  /**
-@@ -1823,12 +2330,14 @@ static int onenand_lock_user_prot_reg(st
+  * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
+  * @param mtd         MTD device structure
+@@ -1821,61 +2328,79 @@ static int onenand_lock_user_prot_reg(st
+       return ret ? : retlen;
+ }
  #endif        /* CONFIG_MTD_ONENAND_OTP */
  
  /**
@@ -187401,7 +188234,9 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  {
        struct onenand_chip *this = mtd->priv;
        unsigned int density, process;
-@@ -1838,31 +2347,47 @@ static void onenand_lock_scheme(struct m
+       /* Lock scheme depends on density and process */
+       density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
        process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
  
        /* Lock scheme */
@@ -187461,7 +188296,10 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
          vcc = device & ONENAND_DEVICE_VCC_MASK;
          demuxed = device & ONENAND_DEVICE_IS_DEMUX;
          ddp = device & ONENAND_DEVICE_IS_DDP;
-@@ -1873,7 +2398,7 @@ static void onenand_print_device_info(in
+         density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
+         printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
+                 demuxed ? "" : "Muxed ",
+                 ddp ? "(DDP)" : "",
                  (16 << density),
                  vcc ? "2.65/3.3" : "1.8",
                  device);
@@ -187470,7 +188308,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  static const struct onenand_manufacturers onenand_manuf_ids[] = {
-@@ -1911,12 +2436,12 @@ static int onenand_check_maf(int manuf)
+         {ONENAND_MFR_SAMSUNG, "Samsung"},
+ };
+@@ -1909,16 +2434,16 @@ static int onenand_check_maf(int manuf)
+ /**
+  * onenand_probe - [OneNAND Interface] Probe the OneNAND device
   * @param mtd         MTD device structure
   *
   * OneNAND detection method:
@@ -187485,7 +188327,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        int density;
        int syscfg;
  
-@@ -1948,6 +2473,7 @@ static int onenand_probe(struct mtd_info
+       /* Save system configuration 1 */
+       syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+@@ -1946,10 +2471,11 @@ static int onenand_probe(struct mtd_info
+       /* Read manufacturer and device IDs from Register */
        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
        ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
@@ -187493,7 +188339,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* Check OneNAND device */
        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
-@@ -1961,26 +2487,41 @@ static int onenand_probe(struct mtd_info
+               return -ENXIO;
+@@ -1959,30 +2485,45 @@ static int onenand_probe(struct mtd_info
+       this->version_id = ver_id;
        density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
        this->chipsize = (16 << density) << 20;
        /* Set density mask. it is used for DDP */
@@ -187540,7 +188390,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        return 0;
  }
-@@ -2021,6 +2562,7 @@ static void onenand_resume(struct mtd_in
+ /**
+@@ -2019,10 +2560,11 @@ static void onenand_resume(struct mtd_in
+  * The flash ID is read and the mtd/chip structures are
+  * filled with the appropriate values.
   */
  int onenand_scan(struct mtd_info *mtd, int maxchips)
  {
@@ -187548,7 +188402,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        struct onenand_chip *this = mtd->priv;
  
        if (!this->read_word)
-@@ -2044,7 +2586,9 @@ int onenand_scan(struct mtd_info *mtd, i
+               this->read_word = onenand_readw;
+       if (!this->write_word)
+@@ -2042,29 +2584,41 @@ int onenand_scan(struct mtd_info *mtd, i
+               this->block_markbad = onenand_default_block_markbad;
+       if (!this->scan_bbt)
                this->scan_bbt = onenand_default_bbt;
  
        if (onenand_probe(mtd))
@@ -187558,7 +188416,9 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        /* Set Sync. Burst Read after probing */
        if (this->mmcontrol) {
-@@ -2054,15 +2598,25 @@ int onenand_scan(struct mtd_info *mtd, i
+               printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
+               this->read_bufferram = onenand_sync_read_bufferram;
+       }
  
        /* Allocate buffers, if necessary */
        if (!this->page_buf) {
@@ -187587,7 +188447,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  
        this->state = FL_READY;
        init_waitqueue_head(&this->wq);
-@@ -2092,12 +2646,23 @@ int onenand_scan(struct mtd_info *mtd, i
+       spin_lock_init(&this->chip_lock);
+@@ -2090,16 +2644,27 @@ int onenand_scan(struct mtd_info *mtd, i
+               this->ecclayout = &onenand_oob_32;
+               break;
        }
  
        this->subpagesize = mtd->writesize >> mtd->subpage_sft;
@@ -187612,7 +188476,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
        mtd->erase = onenand_erase;
        mtd->point = NULL;
        mtd->unpoint = NULL;
-@@ -2144,11 +2709,16 @@ void onenand_release(struct mtd_info *mt
+       mtd->read = onenand_read;
+       mtd->write = onenand_write;
+@@ -2142,18 +2707,24 @@ void onenand_release(struct mtd_info *mt
+ #endif
+       /* Deregister the device */
        del_mtd_device (mtd);
  
        /* Free bad block table memory, if allocated */
@@ -187631,15 +188499,17 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_base.c ../new/linux-2.6.20
  }
  
  EXPORT_SYMBOL_GPL(onenand_scan);
-@@ -2157,3 +2727,4 @@ EXPORT_SYMBOL_GPL(onenand_release);
+ EXPORT_SYMBOL_GPL(onenand_release);
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
  MODULE_DESCRIPTION("Generic OneNAND flash driver code");
 +
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c
---- linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c      2008-09-17 13:23:33.000000000 +0530
-@@ -10,6 +10,11 @@
+--- linux-2.6.20.orig/drivers/mtd/onenand/onenand_bbt.c
++++ linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c
+@@ -8,19 +8,24 @@
+  *
+  *  Derived from nand_bbt.c
   *
   *  TODO:
   *    Split BBT core and chip specific BBT.
@@ -187651,7 +188521,7 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/
   */
  
  #include <linux/slab.h>
-@@ -17,8 +22,8 @@
+ #include <linux/mtd/mtd.h>
  #include <linux/mtd/onenand.h>
  #include <linux/mtd/compatmac.h>
  
@@ -187662,7 +188532,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/
  
  /**
   * check_short_pattern - [GENERIC] check if a pattern is in the buffer
-@@ -65,10 +70,11 @@ static int create_bbt(struct mtd_info *m
+  * @param buf         the buffer to search
+  * @param len         the length of buffer to search
+@@ -63,14 +68,15 @@ static int create_bbt(struct mtd_info *m
+       struct bbm_info *bbm = this->bbm;
+       int i, j, numblocks, len, scanlen;
        int startblock;
        loff_t from;
        size_t readlen, ooblen;
@@ -187675,7 +188549,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/
  
        /* We need only read few bytes from the OOB area */
        scanlen = ooblen = 0;
-@@ -82,22 +88,24 @@ static int create_bbt(struct mtd_info *m
+       readlen = bd->len;
+@@ -80,26 +86,28 @@ static int create_bbt(struct mtd_info *m
+        */
+       numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
        startblock = 0;
        from = 0;
  
@@ -187707,7 +188585,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/
                                bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
                                printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
                                        i >> 1, (unsigned int) from);
-@@ -167,9 +175,8 @@ static int onenand_isbad_bbt(struct mtd_
+                               mtd->ecc_stats.badblocks++;
+                               break;
+@@ -165,13 +173,12 @@ static int onenand_isbad_bbt(struct mtd_
+  *
+  * The function checks, if a bad block table(s) is/are already
   * available. If not it scans the device for manufacturer
   * marked good / bad blocks and writes the bad block table(s) to
   * the selected place.
@@ -187719,9 +188601,10 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_bbt.c ../new/linux-2.6.20/
   *
   */
  int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
-diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_sim.c ../new/linux-2.6.20/drivers/mtd/onenand/onenand_sim.c
---- linux-2.6.20/drivers/mtd/onenand/onenand_sim.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/mtd/onenand/onenand_sim.c      2008-11-19 16:47:10.000000000 +0530
+ {
+       struct onenand_chip *this = mtd->priv;
+--- /dev/null
++++ linux-2.6.20/drivers/mtd/onenand/onenand_sim.c
 @@ -0,0 +1,495 @@
 +/*
 + *  linux/drivers/mtd/onenand/onenand_sim.c
@@ -187736,1766 +188619,4724 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/onenand_sim.c ../new/linux-2.6.20/
 + * published by the Free Software Foundation.
 + */
 +
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/vmalloc.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/onenand.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/vmalloc.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/onenand.h>
++
++#include <linux/io.h>
++
++#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
++#define CONFIG_ONENAND_SIM_MANUFACTURER         0xec
++#endif
++#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
++#define CONFIG_ONENAND_SIM_DEVICE_ID            0x04
++#endif
++#ifndef CONFIG_ONENAND_SIM_VERSION_ID
++#define CONFIG_ONENAND_SIM_VERSION_ID           0x1e
++#endif
++
++static int manuf_id   = CONFIG_ONENAND_SIM_MANUFACTURER;
++static int device_id  = CONFIG_ONENAND_SIM_DEVICE_ID;
++static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
++
++struct onenand_flash {
++      void __iomem *base;
++      void __iomem *data;
++};
++
++#define ONENAND_CORE(flash)           (flash->data)
++#define ONENAND_CORE_SPARE(flash, this, offset)                               \
++      ((flash->data) + (this->chipsize) + (offset >> 5))
++
++#define ONENAND_MAIN_AREA(this, offset)                                       \
++      (this->base + ONENAND_DATARAM + offset)
++
++#define ONENAND_SPARE_AREA(this, offset)                              \
++      (this->base + ONENAND_SPARERAM + offset)
++
++#define ONENAND_GET_WP_STATUS(this)                                   \
++      (readw(this->base + ONENAND_REG_WP_STATUS))
++
++#define ONENAND_SET_WP_STATUS(v, this)                                        \
++      (writew(v, this->base + ONENAND_REG_WP_STATUS))
++
++/* It has all 0xff chars */
++#define MAX_ONENAND_PAGESIZE          (2048 + 64)
++static unsigned char *ffchars;
++
++static struct mtd_partition os_partitions[] = {
++      {
++              .name           = "OneNAND simulator partition",
++              .offset         = 0,
++              .size           = MTDPART_SIZ_FULL,
++      },
++};
++
++/*
++ * OneNAND simulator mtd
++ */
++struct onenand_info {
++      struct mtd_info         mtd;
++      struct mtd_partition    *parts;
++      struct onenand_chip     onenand;
++      struct onenand_flash    flash;
++};
++
++static struct onenand_info *info;
++
++#define DPRINTK(format, args...)                                      \
++do {                                                                  \
++      printk(KERN_DEBUG "%s[%d]: " format "\n", __func__,             \
++                         __LINE__, ##args);                           \
++} while (0)
++
++/**
++ * onenand_lock_handle - Handle Lock scheme
++ * @this:             OneNAND device structure
++ * @cmd:              The command to be sent
++ *
++ * Send lock command to OneNAND device.
++ * The lock scheme depends on chip type.
++ */
++static void onenand_lock_handle(struct onenand_chip *this, int cmd)
++{
++      int block_lock_scheme;
++      int status;
++
++      status = ONENAND_GET_WP_STATUS(this);
++      block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
++
++      switch (cmd) {
++      case ONENAND_CMD_UNLOCK:
++              if (block_lock_scheme)
++                      ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
++              else
++                      ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
++              break;
++
++      case ONENAND_CMD_LOCK:
++              if (block_lock_scheme)
++                      ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
++              else
++                      ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
++              break;
++
++      case ONENAND_CMD_LOCK_TIGHT:
++              if (block_lock_scheme)
++                      ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
++              else
++                      ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
++              break;
++
++      default:
++              break;
++      }
++}
++
++/**
++ * onenand_bootram_handle - Handle BootRAM area
++ * @this:             OneNAND device structure
++ * @cmd:              The command to be sent
++ *
++ * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
++ */
++static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
++{
++      switch (cmd) {
++      case ONENAND_CMD_READID:
++              writew(manuf_id, this->base);
++              writew(device_id, this->base + 2);
++              writew(version_id, this->base + 4);
++              break;
++
++      default:
++              /* REVIST: Handle other commands */
++              break;
++      }
++}
++
++/**
++ * onenand_update_interrupt - Set interrupt register
++ * @this:         OneNAND device structure
++ * @cmd:          The command to be sent
++ *
++ * Update interrupt register. The status depends on command.
++ */
++static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
++{
++      int interrupt = ONENAND_INT_MASTER;
++
++      switch (cmd) {
++      case ONENAND_CMD_READ:
++      case ONENAND_CMD_READOOB:
++              interrupt |= ONENAND_INT_READ;
++              break;
++
++      case ONENAND_CMD_PROG:
++      case ONENAND_CMD_PROGOOB:
++              interrupt |= ONENAND_INT_WRITE;
++              break;
++
++      case ONENAND_CMD_ERASE:
++              interrupt |= ONENAND_INT_ERASE;
++              break;
++
++      case ONENAND_CMD_RESET:
++              interrupt |= ONENAND_INT_RESET;
++              break;
++
++      default:
++              break;
++      }
++
++      writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
++}
++
++/**
++ * onenand_check_overwrite - Check if over-write happened
++ * @dest:             The destination pointer
++ * @src:              The source pointer
++ * @count:            The length to be check
++ *
++ * Returns:           0 on same, otherwise 1
++ *
++ * Compare the source with destination
++ */
++static int onenand_check_overwrite(void *dest, void *src, size_t count)
++{
++      unsigned int *s = (unsigned int *) src;
++      unsigned int *d = (unsigned int *) dest;
++      int i;
++
++      count >>= 2;
++      for (i = 0; i < count; i++)
++              if ((*s++ ^ *d++) != 0)
++                      return 1;
++
++      return 0;
++}
++
++/**
++ * onenand_data_handle - Handle OneNAND Core and DataRAM
++ * @this:             OneNAND device structure
++ * @cmd:              The command to be sent
++ * @dataram:          Which dataram used
++ * @offset:           The offset to OneNAND Core
++ *
++ * Copy data from OneNAND Core to DataRAM (read)
++ * Copy data from DataRAM to OneNAND Core (write)
++ * Erase the OneNAND Core (erase)
++ */
++static void onenand_data_handle(struct onenand_chip *this, int cmd,
++                              int dataram, unsigned int offset)
++{
++      struct mtd_info *mtd = &info->mtd;
++      struct onenand_flash *flash = this->priv;
++      int main_offset, spare_offset;
++      void __iomem *src;
++      void __iomem *dest;
++      unsigned int i;
++
++      if (dataram) {
++              main_offset = mtd->writesize;
++              spare_offset = mtd->oobsize;
++      } else {
++              main_offset = 0;
++              spare_offset = 0;
++      }
++
++      switch (cmd) {
++      case ONENAND_CMD_READ:
++              src = ONENAND_CORE(flash) + offset;
++              dest = ONENAND_MAIN_AREA(this, main_offset);
++              memcpy(dest, src, mtd->writesize);
++              /* Fall through */
++
++      case ONENAND_CMD_READOOB:
++              src = ONENAND_CORE_SPARE(flash, this, offset);
++              dest = ONENAND_SPARE_AREA(this, spare_offset);
++              memcpy(dest, src, mtd->oobsize);
++              break;
++
++      case ONENAND_CMD_PROG:
++              src = ONENAND_MAIN_AREA(this, main_offset);
++              dest = ONENAND_CORE(flash) + offset;
++              /* To handle partial write */
++              for (i = 0; i < (1 << mtd->subpage_sft); i++) {
++                      int off = i * this->subpagesize;
++                      if (!memcmp(src + off, ffchars, this->subpagesize))
++                              continue;
++                      if (memcmp(dest + off, ffchars, this->subpagesize) &&
++                          onenand_check_overwrite(dest + off, src + off, this->subpagesize))
++                              printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
++                      memcpy(dest + off, src + off, this->subpagesize);
++              }
++              /* Fall through */
++
++      case ONENAND_CMD_PROGOOB:
++              src = ONENAND_SPARE_AREA(this, spare_offset);
++              /* Check all data is 0xff chars */
++              if (!memcmp(src, ffchars, mtd->oobsize))
++                      break;
++
++              dest = ONENAND_CORE_SPARE(flash, this, offset);
++              if (memcmp(dest, ffchars, mtd->oobsize) &&
++                  onenand_check_overwrite(dest, src, mtd->oobsize))
++                      printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
++                             offset);
++              memcpy(dest, src, mtd->oobsize);
++              break;
++
++      case ONENAND_CMD_ERASE:
++              memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
++              memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
++                     (mtd->erasesize >> 5));
++              break;
++
++      default:
++              break;
++      }
++}
++
++/**
++ * onenand_command_handle - Handle command
++ * @this:             OneNAND device structure
++ * @cmd:              The command to be sent
++ *
++ * Emulate OneNAND command.
++ */
++static void onenand_command_handle(struct onenand_chip *this, int cmd)
++{
++      unsigned long offset = 0;
++      int block = -1, page = -1, bufferram = -1;
++      int dataram = 0;
++
++      switch (cmd) {
++      case ONENAND_CMD_UNLOCK:
++      case ONENAND_CMD_LOCK:
++      case ONENAND_CMD_LOCK_TIGHT:
++      case ONENAND_CMD_UNLOCK_ALL:
++              onenand_lock_handle(this, cmd);
++              break;
++
++      case ONENAND_CMD_BUFFERRAM:
++              /* Do nothing */
++              return;
++
++      default:
++              block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
++              if (block & (1 << ONENAND_DDP_SHIFT)) {
++                      block &= ~(1 << ONENAND_DDP_SHIFT);
++                      /* The half of chip block */
++                      block += this->chipsize >> (this->erase_shift + 1);
++              }
++              if (cmd == ONENAND_CMD_ERASE)
++                      break;
++
++              page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
++              page = (page >> ONENAND_FPA_SHIFT);
++              bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
++              bufferram >>= ONENAND_BSA_SHIFT;
++              bufferram &= ONENAND_BSA_DATARAM1;
++              dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
++              break;
++      }
++
++      if (block != -1)
++              offset += block << this->erase_shift;
++
++      if (page != -1)
++              offset += page << this->page_shift;
++
++      onenand_data_handle(this, cmd, dataram, offset);
++
++      onenand_update_interrupt(this, cmd);
++}
++
++/**
++ * onenand_writew - [OneNAND Interface] Emulate write operation
++ * @value:            value to write
++ * @addr:             address to write
++ *
++ * Write OneNAND register with value
++ */
++static void onenand_writew(unsigned short value, void __iomem * addr)
++{
++      struct onenand_chip *this = info->mtd.priv;
++
++      /* BootRAM handling */
++      if (addr < this->base + ONENAND_DATARAM) {
++              onenand_bootram_handle(this, value);
++              return;
++      }
++      /* Command handling */
++      if (addr == this->base + ONENAND_REG_COMMAND)
++              onenand_command_handle(this, value);
++
++      writew(value, addr);
++}
++
++/**
++ * flash_init - Initialize OneNAND simulator
++ * @flash:            OneNAND simulator data strucutres
++ *
++ * Initialize OneNAND simulator.
++ */
++static int __init flash_init(struct onenand_flash *flash)
++{
++      int density, size;
++      int buffer_size;
++
++      flash->base = kzalloc(131072, GFP_KERNEL);
++      if (!flash->base) {
++              printk(KERN_ERR "Unable to allocate base address.\n");
++              return -ENOMEM;
++      }
++
++      density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
++      size = ((16 << 20) << density);
++
++      ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
++      if (!ONENAND_CORE(flash)) {
++              printk(KERN_ERR "Unable to allocate nand core address.\n");
++              kfree(flash->base);
++              return -ENOMEM;
++      }
++
++      memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
++
++      /* Setup registers */
++      writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
++      writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
++      writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
++
++      if (density < 2)
++              buffer_size = 0x0400;   /* 1KiB page */
++      else
++              buffer_size = 0x0800;   /* 2KiB page */
++      writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
++
++      return 0;
++}
++
++/**
++ * flash_exit - Clean up OneNAND simulator
++ * @flash:            OneNAND simulator data structures
++ *
++ * Clean up OneNAND simulator.
++ */
++static void flash_exit(struct onenand_flash *flash)
++{
++      vfree(ONENAND_CORE(flash));
++      kfree(flash->base);
++}
++
++static int __init onenand_sim_init(void)
++{
++      /* Allocate all 0xff chars pointer */
++      ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
++      if (!ffchars) {
++              printk(KERN_ERR "Unable to allocate ff chars.\n");
++              return -ENOMEM;
++      }
++      memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
++
++      /* Allocate OneNAND simulator mtd pointer */
++      info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
++      if (!info) {
++              printk(KERN_ERR "Unable to allocate core structures.\n");
++              kfree(ffchars);
++              return -ENOMEM;
++      }
++
++      /* Override write_word function */
++      info->onenand.write_word = onenand_writew;
++
++      if (flash_init(&info->flash)) {
++              printk(KERN_ERR "Unable to allocate flash.\n");
++              kfree(ffchars);
++              kfree(info);
++              return -ENOMEM;
++      }
++
++      info->parts = os_partitions;
++
++      info->onenand.base = info->flash.base;
++      info->onenand.priv = &info->flash;
++
++      info->mtd.name = "OneNAND simulator";
++      info->mtd.priv = &info->onenand;
++      info->mtd.owner = THIS_MODULE;
++
++      if (onenand_scan(&info->mtd, 1)) {
++              flash_exit(&info->flash);
++              kfree(ffchars);
++              kfree(info);
++              return -ENXIO;
++      }
++
++      add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
++
++      return 0;
++}
++
++static void __exit onenand_sim_exit(void)
++{
++      struct onenand_chip *this = info->mtd.priv;
++      struct onenand_flash *flash = this->priv;
++
++      onenand_release(&info->mtd);
++      flash_exit(flash);
++      kfree(ffchars);
++      kfree(info);
++}
++
++module_init(onenand_sim_init);
++module_exit(onenand_sim_exit);
++
++MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
++MODULE_DESCRIPTION("The OneNAND flash simulator");
++MODULE_LICENSE("GPL");
+--- linux-2.6.20.orig/drivers/net/Makefile
++++ linux-2.6.20/drivers/net/Makefile
+@@ -211,9 +211,10 @@ obj-$(CONFIG_HAMRADIO) += hamradio/
+ obj-$(CONFIG_IRDA) += irda/
+ obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+ obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
+ obj-$(CONFIG_NETCONSOLE) += netconsole.o
++obj-$(CONFIG_KGDBOE) += kgdboe.o
+ obj-$(CONFIG_FS_ENET) += fs_enet/
+ obj-$(CONFIG_NETXEN_NIC) += netxen/
+--- /dev/null
++++ linux-2.6.20/drivers/net/kgdboe.c
+@@ -0,0 +1,294 @@
++/*
++ * drivers/net/kgdboe.c
++ *
++ * A network interface for GDB.
++ * Based upon 'gdbserial' by David Grothe <dave@gcom.com>
++ * and Scott Foehner <sfoehner@engr.sgi.com>
++ *
++ * Maintainers: Amit S. Kale <amitkale@linsyssoft.com> and
++ *            Tom Rini <trini@kernel.crashing.org>
++ *
++ * 2004 (c) Amit S. Kale <amitkale@linsyssoft.com>
++ * 2004-2005 (c) MontaVista Software, Inc.
++ * 2005 (c) Wind River Systems, Inc.
++ *
++ * Contributors at various stages not listed above:
++ * San Mehat <nettwerk@biodome.org>, Robert Walsh <rjwalsh@durables.org>,
++ * wangdi <wangdi@clusterfs.com>, Matt Mackall <mpm@selenic.com>,
++ * Pavel Machek <pavel@suse.cz>, Jason Wessel <jason.wessel@windriver.com>
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/string.h>
++#include <linux/kgdb.h>
++#include <linux/netpoll.h>
++#include <linux/init.h>
++
++#include <asm/atomic.h>
++
++#define IN_BUF_SIZE 512               /* power of 2, please */
++#define NOT_CONFIGURED_STRING "not_configured"
++#define OUT_BUF_SIZE 30               /* We don't want to send too big of a packet. */
++#define MAX_KGDBOE_CONFIG_STR 256
++
++static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE];
++static int in_head, in_tail, out_count;
++static atomic_t in_count;
++/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */
++static int configured;
++static struct kgdb_io local_kgdb_io_ops;
++static int use_dynamic_mac;
++
++MODULE_DESCRIPTION("KGDB driver for network interfaces");
++MODULE_LICENSE("GPL");
++static char config[MAX_KGDBOE_CONFIG_STR] = NOT_CONFIGURED_STRING;
++static struct kparam_string kps = {
++      .string = config,
++      .maxlen = MAX_KGDBOE_CONFIG_STR,
++};
++
++static void rx_hook(struct netpoll *np, int port, char *msg, int len,
++                  struct sk_buff *skb)
++{
++      int i;
++
++      np->remote_port = port;
++
++      /* Copy the MAC address if we need to. */
++      if (use_dynamic_mac) {
++              memcpy(np->remote_mac, eth_hdr(skb)->h_source,
++                              sizeof(np->remote_mac));
++              use_dynamic_mac = 0;
++      }
++
++      /*
++       * This could be GDB trying to attach.  But it could also be GDB
++       * finishing up a session, with kgdb_connected=0 but GDB sending
++       * an ACK for the final packet.  To make sure we don't try and
++       * make a breakpoint when GDB is leaving, make sure that if
++       * !kgdb_connected the only len == 1 packet we allow is ^C.
++       */
++      if (!kgdb_connected && (len != 1 || msg[0] == 3) &&
++          !atomic_read(&kgdb_setting_breakpoint)) {
++              tasklet_schedule(&kgdb_tasklet_breakpoint);
++      }
++
++      for (i = 0; i < len; i++) {
++              if (msg[i] == 3)
++                      tasklet_schedule(&kgdb_tasklet_breakpoint);
++
++              if (atomic_read(&in_count) >= IN_BUF_SIZE) {
++                      /* buffer overflow, clear it */
++                      in_head = in_tail = 0;
++                      atomic_set(&in_count, 0);
++                      break;
++              }
++              in_buf[in_head++] = msg[i];
++              in_head &= (IN_BUF_SIZE - 1);
++              atomic_inc(&in_count);
++      }
++}
++
++static struct netpoll np = {
++      .dev_name = "eth0",
++      .name = "kgdboe",
++      .rx_hook = rx_hook,
++      .local_port = 6443,
++      .remote_port = 6442,
++      .remote_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
++};
++
++static void eth_pre_exception_handler(void)
++{
++      /* Increment the module count when the debugger is active */
++      if (!kgdb_connected)
++              try_module_get(THIS_MODULE);
++      netpoll_set_trap(1);
++}
++
++static void eth_post_exception_handler(void)
++{
++      /* decrement the module count when the debugger detaches */
++      if (!kgdb_connected)
++              module_put(THIS_MODULE);
++      netpoll_set_trap(0);
++}
++
++static int eth_get_char(void)
++{
++      int chr;
++
++      while (atomic_read(&in_count) == 0)
++              netpoll_poll(&np);
++
++      chr = in_buf[in_tail++];
++      in_tail &= (IN_BUF_SIZE - 1);
++      atomic_dec(&in_count);
++      return chr;
++}
++
++static void eth_flush_buf(void)
++{
++      if (out_count && np.dev) {
++              netpoll_send_udp(&np, out_buf, out_count);
++              memset(out_buf, 0, sizeof(out_buf));
++              out_count = 0;
++      }
++}
++
++static void eth_put_char(u8 chr)
++{
++      out_buf[out_count++] = chr;
++      if (out_count == OUT_BUF_SIZE)
++              eth_flush_buf();
++}
++
++static int option_setup(char *opt)
++{
++      char opt_scratch[MAX_KGDBOE_CONFIG_STR];
++
++      /* If we're being given a new configuration, copy it in. */
++      if (opt != config)
++              strcpy(config, opt);
++      /* But work on a copy as netpoll_parse_options will eat it. */
++      strcpy(opt_scratch, opt);
++      configured = !netpoll_parse_options(&np, opt_scratch);
++
++      use_dynamic_mac = 1;
++
++      return 0;
++}
++__setup("kgdboe=", option_setup);
++
++/* With our config string set by some means, configure kgdboe. */
++static int configure_kgdboe(void)
++{
++      /* Try out the string. */
++      option_setup(config);
++
++      if (!configured) {
++              printk(KERN_ERR "kgdboe: configuration incorrect - kgdboe not "
++                     "loaded.\n");
++              printk(KERN_ERR "  Usage: kgdboe=[src-port]@[src-ip]/[dev],"
++                              "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
++              return -EINVAL;
++      }
++
++      /* Bring it up. */
++      if (netpoll_setup(&np)) {
++              printk(KERN_ERR "kgdboe: netpoll_setup failed kgdboe failed\n");
++              return -EINVAL;
++      }
++
++      if (kgdb_register_io_module(&local_kgdb_io_ops)) {
++              netpoll_cleanup(&np);
++              return -EINVAL;
++      }
++
++      configured = 2;
++
++      return 0;
++}
++
++static int init_kgdboe(void)
++{
++      int ret;
++
++      /* Already done? */
++      if (configured == 2)
++              return 0;
++
++      /* OK, go ahead and do it. */
++      ret = configure_kgdboe();
++
++      if (configured == 2)
++              printk(KERN_INFO "kgdboe: debugging over ethernet enabled\n");
++
++      return ret;
++}
++
++static void cleanup_kgdboe(void)
++{
++      netpoll_cleanup(&np);
++      configured = 0;
++      kgdb_unregister_io_module(&local_kgdb_io_ops);
++}
++
++static int param_set_kgdboe_var(const char *kmessage, struct kernel_param *kp)
++{
++      char kmessage_save[MAX_KGDBOE_CONFIG_STR];
++      int msg_len = strlen(kmessage);
++
++      if (msg_len + 1 > MAX_KGDBOE_CONFIG_STR) {
++              printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
++                     kp->name, MAX_KGDBOE_CONFIG_STR - 1);
++              return -ENOSPC;
++      }
++
++      if (kgdb_connected) {
++              printk(KERN_ERR "kgdboe: Cannot reconfigure while KGDB is "
++                              "connected.\n");
++              return 0;
++      }
++
++      /* Start the reconfiguration process by saving the old string */
++      strncpy(kmessage_save, config, sizeof(kmessage_save));
++
++
++      /* Copy in the new param and strip out invalid characters so we
++       * can optionally specify the MAC.
++       */
++      strncpy(config, kmessage, sizeof(config));
++      msg_len--;
++      while (msg_len > 0 &&
++                      (config[msg_len] < ',' || config[msg_len] > 'f')) {
++              config[msg_len] = '\0';
++              msg_len--;
++      }
++
++      /* Check to see if we are unconfiguring the io module and that it
++       * was in a fully configured state, as this is the only time that
++       * netpoll_cleanup should get called
++       */
++      if (configured == 2 && strcmp(config, NOT_CONFIGURED_STRING) == 0) {
++              printk(KERN_INFO "kgdboe: reverting to unconfigured state\n");
++              cleanup_kgdboe();
++              return 0;
++      } else
++              /* Go and configure with the new params. */
++              configure_kgdboe();
++
++      if (configured == 2)
++              return 0;
++
++      /* If the new string was invalid, revert to the previous state, which
++       * is at a minimum not_configured. */
++      strncpy(config, kmessage_save, sizeof(config));
++      if (strcmp(kmessage_save, NOT_CONFIGURED_STRING) != 0) {
++              printk(KERN_INFO "kgdboe: reverting to prior configuration\n");
++              /* revert back to the original config */
++              strncpy(config, kmessage_save, sizeof(config));
++              configure_kgdboe();
++      }
++      return 0;
++}
++
++static struct kgdb_io local_kgdb_io_ops = {
++      .read_char = eth_get_char,
++      .write_char = eth_put_char,
++      .init = init_kgdboe,
++      .flush = eth_flush_buf,
++      .pre_exception = eth_pre_exception_handler,
++      .post_exception = eth_post_exception_handler
++};
++
++module_init(init_kgdboe);
++module_exit(cleanup_kgdboe);
++module_param_call(kgdboe, param_set_kgdboe_var, param_get_string, &kps, 0644);
++MODULE_PARM_DESC(kgdboe, " kgdboe=[src-port]@[src-ip]/[dev],"
++               "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
+--- linux-2.6.20.orig/drivers/net/smc91x.c
++++ linux-2.6.20/drivers/net/smc91x.c
+@@ -1,5 +1,6 @@
++
+ /*
+  * smc91x.c
+  * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
+  *
+  * Copyright (C) 1996 by Erik Stahlman
+@@ -63,11 +64,10 @@ static const char version[] =
+ /* Debugging level */
+ #ifndef SMC_DEBUG
+ #define SMC_DEBUG             0
+ #endif
+-
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+@@ -88,10 +88,12 @@ static const char version[] =
+ #include <asm/io.h>
+ #include "smc91x.h"
++#include <linux/delay.h>
++
+ #ifdef CONFIG_ISA
+ /*
+  * the LAN91C111 can be at any of the following port addresses.  To change,
+  * for a slightly different card, you can add it to the array.  Keep in
+  * mind that the array must end in zero.
+@@ -266,11 +268,10 @@ static void PRINT_PKT(u_char *buf, int l
+ }
+ #else
+ #define PRINT_PKT(x...)  do { } while(0)
+ #endif
+-
+ /* this enables an interrupt in the interrupt mask register */
+ #define SMC_ENABLE_INT(x) do {                                                \
+       unsigned char mask;                                             \
+       spin_lock_irq(&lp->lock);                                       \
+       mask = SMC_GET_INT_MASK();                                      \
+@@ -306,11 +307,10 @@ static void PRINT_PKT(u_char *buf, int l
+                       cpu_relax();                                    \
+               }                                                       \
+       }                                                               \
+ } while (0)
+-
+ /*
+  * this does a soft reset on the device
+  */
+ static void smc_reset(struct net_device *dev)
+ {
+@@ -492,12 +492,11 @@ static inline void  smc_rcv(struct net_d
+       /* First two words are status and packet length */
+       SMC_GET_PKT_HDR(status, packet_len);
+       packet_len &= 0x07ff;  /* mask off top bits */
+       DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
+-              dev->name, packet_number, status,
+-              packet_len, packet_len);
++          dev->name, packet_number, status, packet_len, packet_len);
+       back:
+       if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
+               if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) {
+                       /* accept VLAN packets */
+@@ -833,11 +832,10 @@ static void smc_tx(struct net_device *de
+       SMC_SELECT_BANK(0);
+       SMC_SET_TCR(lp->tcr_cur_mode);
+       SMC_SELECT_BANK(2);
+ }
+-
+ /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
+ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
+ {
+       struct smc_local *lp = netdev_priv(dev);
+@@ -925,11 +923,13 @@ static void smc_phy_write(struct net_dev
+       /* Idle - 32 ones */
+       smc_mii_out(dev, 0xffffffff, 32);
+       /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */
+-      smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
++      smc_mii_out(dev,
++                  5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata,
++                  32);
+       /* Return to idle state */
+       SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
+       DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+@@ -959,12 +959,11 @@ static void smc_phy_detect(struct net_de
+               /* Read the PHY identifiers */
+               id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1);
+               id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2);
+-              DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n",
+-                      dev->name, id1, id2);
++              DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", dev->name, id1, id2);
+               /* Make sure it is a valid identifier */
+               if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
+                   id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
+                       /* Save the PHY's address */
+@@ -1182,11 +1181,13 @@ static void smc_phy_configure(struct wor
+       if (my_phy_caps & BMSR_10HALF)
+               my_ad_caps |= ADVERTISE_10HALF;
+       /* Disable capabilities not selected by our user */
+       if (lp->ctl_rspeed != 100)
+-              my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
++              my_ad_caps &=
++                  ~(ADVERTISE_100BASE4 | ADVERTISE_100FULL |
++                    ADVERTISE_100HALF);
+       if (!lp->ctl_rfduplx)
+               my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
+       /* Update our Auto-Neg Advertisement Register */
+@@ -1312,15 +1313,16 @@ static irqreturn_t smc_interrupt(int irq
+       do {
+               status = SMC_GET_INT();
+               DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
+-                      dev->name, status, mask,
+-                      ({ int meminfo; SMC_SELECT_BANK(0);
++                  dev->name, status, mask, ( {
++                                            int meminfo;
++                                            SMC_SELECT_BANK(0);
+                          meminfo = SMC_GET_MIR();
+-                         SMC_SELECT_BANK(2); meminfo; }),
+-                      SMC_GET_FIFO());
++                                            SMC_SELECT_BANK(2);
++                                            meminfo;}), SMC_GET_FIFO());
+               status &= mask;
+               if (!status)
+                       break;
+@@ -1352,14 +1354,22 @@ static irqreturn_t smc_interrupt(int irq
+                       card_stats >>= 4;
+                       /* multiple collisions */
+                       lp->stats.collisions += card_stats & 0xF;
+               } else if (status & IM_RX_OVRN_INT) {
+-                      DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
+-                             ({ int eph_st; SMC_SELECT_BANK(0);
+-                                eph_st = SMC_GET_EPH_STATUS();
+-                                SMC_SELECT_BANK(2); eph_st; }) );
++                      DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, ( {
++                                                                             int
++                                                                             eph_st;
++                                                                             SMC_SELECT_BANK
++                                                                             (0);
++                                                                             eph_st
++                                                                             =
++                                                                             SMC_GET_EPH_STATUS
++                                                                             ();
++                                                                             SMC_SELECT_BANK
++                                                                             (2);
++                                                                             eph_st;}));
+                       SMC_ACK_INT(IM_RX_OVRN_INT);
+                       lp->stats.rx_errors++;
+                       lp->stats.rx_fifo_errors++;
+               } else if (status & IM_EPH_INT) {
+                       smc_eph_interrupt(dev);
+@@ -1498,11 +1508,12 @@ static void smc_set_multicast_list(struc
+       else if (dev->mc_count)  {
+               int i;
+               struct dev_mc_list *cur_addr;
+               /* table for flipping the order of 3 bits */
+-              static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7};
++              static const unsigned char invert3[] =
++                  { 0, 4, 2, 6, 1, 5, 3, 7 };
+               /* start with a table of all zeros: reject all */
+               memset(multicast_table, 0, sizeof(multicast_table));
+               cur_addr = dev->mc_list;
+@@ -1551,18 +1562,16 @@ static void smc_set_multicast_list(struc
+       }
+       SMC_SELECT_BANK(2);
+       spin_unlock_irq(&lp->lock);
+ }
+-
+ /*
+  * Open and Initialize the board
+  *
+  * Set up everything, reset the card, etc..
+  */
+-static int
+-smc_open(struct net_device *dev)
++static int smc_open(struct net_device *dev)
+ {
+       struct smc_local *lp = netdev_priv(dev);
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+@@ -1657,22 +1666,22 @@ smc_ethtool_getsettings(struct net_devic
+               spin_lock_irq(&lp->lock);
+               ret = mii_ethtool_gset(&lp->mii, cmd);
+               spin_unlock_irq(&lp->lock);
+       } else {
+               cmd->supported = SUPPORTED_10baseT_Half |
+-                               SUPPORTED_10baseT_Full |
+-                               SUPPORTED_TP | SUPPORTED_AUI;
++                  SUPPORTED_10baseT_Full | SUPPORTED_TP | SUPPORTED_AUI;
+               if (lp->ctl_rspeed == 10)
+                       cmd->speed = SPEED_10;
+               else if (lp->ctl_rspeed == 100)
+                       cmd->speed = SPEED_100;
+               cmd->autoneg = AUTONEG_DISABLE;
+               cmd->transceiver = XCVR_INTERNAL;
+               cmd->port = 0;
+-              cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
++              cmd->duplex =
++                  lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
+               ret = 0;
+       }
+       return ret;
+@@ -1689,12 +1698,12 @@ smc_ethtool_setsettings(struct net_devic
+               ret = mii_ethtool_sset(&lp->mii, cmd);
+               spin_unlock_irq(&lp->lock);
+       } else {
+               if (cmd->autoneg != AUTONEG_DISABLE ||
+                   cmd->speed != SPEED_10 ||
+-                  (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
+-                  (cmd->port != PORT_TP && cmd->port != PORT_AUI))
++                  (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
++                  || (cmd->port != PORT_TP && cmd->port != PORT_AUI))
+                       return -EINVAL;
+ //            lp->port = cmd->port;
+               lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL;
+@@ -1710,11 +1719,12 @@ smc_ethtool_setsettings(struct net_devic
+ static void
+ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+ {
+       strncpy(info->driver, CARDNAME, sizeof(info->driver));
+       strncpy(info->version, version, sizeof(info->version));
+-      strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
++      strncpy(info->bus_info, dev->class_dev.dev->bus_id,
++              sizeof(info->bus_info));
+ }
+ static int smc_ethtool_nwayreset(struct net_device *dev)
+ {
+       struct smc_local *lp = netdev_priv(dev);
+@@ -1837,11 +1847,11 @@ static int __init smc_findirq(void __iom
+  * o  set up my private data
+  * o  configure the dev structure with my subroutines
+  * o  actually GRAB the irq.
+  * o  GRAB the region
+  */
+-static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
++int __init smc_probe(struct net_device *dev, void __iomem * ioaddr)
+ {
+       struct smc_local *lp = netdev_priv(dev);
+       static int version_printed = 0;
+       int i, retval;
+       unsigned int val, revision_register;
+@@ -1878,10 +1888,12 @@ static int __init smc_probe(struct net_d
+        * time won't hurt.  This time, I need to switch the bank
+        * register to bank 1, so I can access the base address
+        * register
+        */
+       SMC_SELECT_BANK(1);
++      mdelay(100);
++      val = SMC_CURRENT_BANK();
+       val = SMC_GET_BASE();
+       val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
+       if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
+               printk("%s: IOADDR %p doesn't match configuration (%x).\n",
+                       CARDNAME, ioaddr, val);
+@@ -1916,10 +1928,11 @@ static int __init smc_probe(struct net_d
+       lp->version = revision_register & 0xff;
+       spin_lock_init(&lp->lock);
+       /* Get the MAC address */
+       SMC_SELECT_BANK(1);
++
+       SMC_GET_MAC_ADDR(dev->dev_addr);
+       /* now, reset the chip, and put it into a known state */
+       smc_reset(dev);
+@@ -2003,11 +2016,15 @@ static int __init smc_probe(struct net_d
+               lp->ctl_rfduplx = 1;
+               lp->ctl_rspeed = 100;
+       }
+       /* Grab the IRQ */
+-              retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
++      printk("dev->irq = %d\n", dev->irq);
++
++      retval =
++          request_irq(dev->irq, smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
++
+               if (retval)
+                       goto err_out;
+ #ifdef SMC_USE_PXA_DMA
+       {
+@@ -2043,11 +2060,12 @@ static int __init smc_probe(struct net_d
+               }
+               if (lp->phy_type == 0) {
+                       PRINTK("%s: No PHY found\n", dev->name);
+               } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) {
+-                      PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name);
++                      PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n",
++                             dev->name);
+               } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
+                       PRINTK("%s: PHY LAN83C180\n", dev->name);
+               }
+       }
+@@ -2064,11 +2082,12 @@ static int smc_enable_device(struct plat
+       unsigned long flags;
+       unsigned char ecor, ecsr;
+       void __iomem *addr;
+       struct resource * res;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++      res =
++          platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+       if (!res)
+               return 0;
+       /*
+        * Map the attribute space.  This is overkill, but clean.
+@@ -2120,11 +2139,12 @@ static int smc_enable_device(struct plat
+       return 0;
+ }
+ static int smc_request_attrib(struct platform_device *pdev)
+ {
+-      struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++      struct resource *res =
++          platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+       if (!res)
+               return 0;
+       if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME))
+@@ -2133,11 +2153,12 @@ static int smc_request_attrib(struct pla
+       return 0;
+ }
+ static void smc_release_attrib(struct platform_device *pdev)
+ {
+-      struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++      struct resource *res =
++          platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+       if (res)
+               release_mem_region(res->start, ATTRIB_SIZE);
+ }
+@@ -2157,12 +2178,16 @@ static inline void smc_request_datacs(st
+               lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
+       }
+ }
+-static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
++static void smc_release_datacs(struct platform_device *pdev,
++                             struct net_device *ndev)
+ {
++//    struct smc_local *lp = netdev_priv(ndev);
++//    struct resource *res =
++//        platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
+       if (SMC_CAN_USE_DATACS) {
+               struct smc_local *lp = netdev_priv(ndev);
+               struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
+               if (lp->datacs)
+@@ -2199,11 +2224,10 @@ static int smc_drv_probe(struct platform
+       if (!res) {
+               ret = -ENODEV;
+               goto out;
+       }
+-
+       if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
+               ret = -EBUSY;
+               goto out;
+       }
+@@ -2238,10 +2262,11 @@ static int smc_drv_probe(struct platform
+               ret = -ENOMEM;
+               goto out_release_attrib;
+       }
+       platform_set_drvdata(pdev, ndev);
++
+       ret = smc_probe(ndev, addr);
+       if (ret != 0)
+               goto out_iounmap;
+ #ifdef SMC_USE_PXA_DMA
+       else {
+@@ -2276,11 +2301,10 @@ static int smc_drv_remove(struct platfor
+       struct resource *res;
+       platform_set_drvdata(pdev, NULL);
+       unregister_netdev(ndev);
+-
+       free_irq(ndev->irq, ndev);
+ #ifdef SMC_USE_PXA_DMA
+       if (ndev->dma != (unsigned char)-1)
+               pxa_free_dma(ndev->dma);
+@@ -2346,12 +2370,10 @@ static int __init smc_init(void)
+ {
+ #ifdef MODULE
+ #ifdef CONFIG_ISA
+       if (io == -1)
+               printk(KERN_WARNING
+-                      "%s: You shouldn't use auto-probing with insmod!\n",
+-                      CARDNAME);
+ #endif
+ #endif
+       return platform_driver_register(&smc_driver);
+ }
+--- linux-2.6.20.orig/drivers/net/smc91x.h
++++ linux-2.6.20/drivers/net/smc91x.h
+@@ -32,11 +32,10 @@
+  .
+  ---------------------------------------------------------------------------*/
+ #ifndef _SMC91X_H_
+ #define _SMC91X_H_
+-
+ /*
+  * Define your architecture specific bus configuration parameters here.
+  */
+ #if   defined(CONFIG_ARCH_LUBBOCK)
+@@ -161,12 +160,11 @@
+ #define SMC_outl(v, a, r)     writel(v, (a) + (r))
+ #define SMC_insl(a, r, p, l)  readsl((a) + (r), p, l)
+ #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+ /* We actually can't write halfwords properly if not word aligned */
+-static inline void
+-SMC_outw(u16 val, void __iomem *ioaddr, int reg)
++static inline void SMC_outw(u16 val, void __iomem * ioaddr, int reg)
+ {
+       if (reg & 2) {
+               unsigned int v = val << 16;
+               v |= readl(ioaddr + (reg & ~2)) & 0xffff;
+               writel(v, ioaddr + (reg & ~2));
+@@ -197,10 +195,81 @@ SMC_outw(u16 val, void __iomem *ioaddr, 
+               || machine_is_omap_h3() \
+               || machine_is_omap_h4() \
+               || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
+       ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
++#elif defined(CONFIG_ARCH_NOMADIK)
++
++#include <asm/hardware.h>
++
++#define SMC_CAN_USE_8BIT      0
++#define SMC_CAN_USE_16BIT     1
++#define SMC_CAN_USE_32BIT     0
++#define SMC_IO_SHIFT          0
++#define SMC_NOWAIT            0
++
++#define SMC_inb(a, r)         readb((a) + (r))
++#define SMC_outb(v, a, r)     writeb(v, (a) + (r))
++#define SMC_inw(a, r)         readw((a) + (r))
++#define SMC_outw(v, a, r)     writew(v, (a) + (r))
++#define SMC_insw(a, r, p, l)  readsw((a) + (r), p, l)
++#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
++#define SMC_inl(a, r)         readl((a) + (r))
++#define SMC_outl(v, a, r)     writel(v, (a) + (r))
++#define SMC_insl(a, r, p, l)  readsl((a) + (r), p, l)
++#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
++
++#ifdef CONFIG_NOMADIK_NHK15
++#define SMC_IRQ_FLAGS           SA_TRIGGER_RISING
++#else
++#define SMC_IRQ_FLAGS         (SA_SHIRQ)
++#endif
++
++static unsigned char new_mac_addr[MAX_ADDR_LEN] =
++    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
++
++static int smc_mac_setup(char *opt)
++{
++      char *cur = opt, *delim;
++      if (*cur != 0) {
++              /* Get the new MAC address */
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim = 0;
++              new_mac_addr[0] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++              new_mac_addr[0] &= 0xFE;        /* clear multicast bit */
++              new_mac_addr[0] |= 0x02;        /* set local assignment bit (IEEE802) */
++              cur = delim + 1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim = 0;
++              new_mac_addr[1] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++              cur = delim + 1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim = 0;
++              new_mac_addr[2] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++              cur = delim + 1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim = 0;
++              new_mac_addr[3] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++              cur = delim + 1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim = 0;
++              new_mac_addr[4] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++              cur = delim + 1;
++              new_mac_addr[5] = (*cur - '0') * 16 + (*(cur + 1) - '0');
++      }
++      return 0;
++parse_failed:
++      printk(KERN_INFO "mac=: couldn't parse config at %s!\n", cur);
++      return -1;
++}
++
++__setup("mac=", smc_mac_setup);
+ #elif defined(CONFIG_SH_SH4202_MICRODEV)
+ #define SMC_CAN_USE_8BIT      0
+ #define SMC_CAN_USE_16BIT     1
+@@ -475,24 +544,25 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ {
+       DCSR(dma) = 0;
+ }
+ #endif  /* SMC_USE_PXA_DMA */
+-
+ /*
+  * Everything a particular hardware setup needs should have been defined
+  * at this point.  Add stubs for the undefined cases, mainly to avoid
+  * compilation warnings since they'll be optimized away, or to prevent buggy
+  * use of them.
+  */
++#if 0 /*Vaibhav*/
+ #if ! SMC_CAN_USE_32BIT
+ #define SMC_inl(ioaddr, reg)          ({ BUG(); 0; })
+ #define SMC_outl(x, ioaddr, reg)      BUG()
+ #define SMC_insl(a, r, p, l)          BUG()
+ #define SMC_outsl(a, r, p, l)         BUG()
+ #endif
++#endif
+ #if !defined(SMC_insl) || !defined(SMC_outsl)
+ #define SMC_insl(a, r, p, l)          BUG()
+ #define SMC_outsl(a, r, p, l)         BUG()
+ #endif
+@@ -520,18 +590,22 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define SMC_insw(a, r, p, l)          BUG()
+ #define SMC_outsw(a, r, p, l)         BUG()
+ #endif
++#if 0 /*Vaibhav*/
+ #if !defined(SMC_insw) || !defined(SMC_outsw)
+ #define SMC_insw(a, r, p, l)          BUG()
+ #define SMC_outsw(a, r, p, l)         BUG()
+ #endif
++#endif
+ #if ! SMC_CAN_USE_8BIT
++#if 0 /*Vaibhav*/
+ #define SMC_inb(ioaddr, reg)          ({ BUG(); 0; })
+ #define SMC_outb(x, ioaddr, reg)      BUG()
++#endif
+ #define SMC_insb(a, r, p, l)          BUG()
+ #define SMC_outsb(a, r, p, l)         BUG()
+ #endif
+ #if !defined(SMC_insb) || !defined(SMC_outsb)
+@@ -567,11 +641,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+  .            xx              = bank number
+  .            yyyy yyyy       = 0x33, for identification purposes.
+ */
+ #define BANK_SELECT           (14 << SMC_IO_SHIFT)
+-
+ // Transmit Control Register
+ /* BANK 0  */
+ #define TCR_REG       SMC_REG(0x0000, 0)
+ #define TCR_ENABLE    0x0001  // When 1 we can transmit
+ #define TCR_LOOP      0x0002  // Controls output pin LBK
+@@ -586,11 +659,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define TCR_CLEAR     0       /* do NOTHING */
+ /* the default settings for the TCR register : */
+ #define TCR_DEFAULT   (TCR_ENABLE | TCR_PAD_EN)
+-
+ // EPH Status Register
+ /* BANK 0  */
+ #define EPH_STATUS_REG        SMC_REG(0x0002, 0)
+ #define ES_TX_SUC     0x0001  // Last TX was successful
+ #define ES_SNGL_COL   0x0002  // Single collision detected for last tx
+@@ -605,11 +677,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define ES_EXC_DEF    0x0800  // Excessive Deferral
+ #define ES_CTR_ROL    0x1000  // Counter Roll Over indication
+ #define ES_LINK_OK    0x4000  // Driven by inverted value of nLNK pin
+ #define ES_TXUNRN     0x8000  // Tx Underrun
+-
+ // Receive Control Register
+ /* BANK 0  */
+ #define RCR_REG               SMC_REG(0x0004, 0)
+ #define RCR_RX_ABORT  0x0001  // Set if a rx frame was aborted
+ #define RCR_PRMS      0x0002  // Enable promiscuous mode
+@@ -622,21 +693,18 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ /* the normal settings for the RCR register : */
+ #define RCR_DEFAULT   (RCR_STRIP_CRC | RCR_RXEN)
+ #define RCR_CLEAR     0x0     // set it to a base state
+-
+ // Counter Register
+ /* BANK 0  */
+ #define COUNTER_REG   SMC_REG(0x0006, 0)
+-
+ // Memory Information Register
+ /* BANK 0  */
+ #define MIR_REG               SMC_REG(0x0008, 0)
+-
+ // Receive/Phy Control Register
+ /* BANK 0  */
+ #define RPC_REG               SMC_REG(0x000A, 0)
+ #define RPC_SPEED     0x2000  // When 1 PHY is in 100Mbps mode.
+ #define RPC_DPLX      0x1000  // When 1 PHY is in Full-Duplex Mode
+@@ -659,18 +727,16 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define RPC_LSB_DEFAULT RPC_LED_FD
+ #endif
+ #define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
+-
+ /* Bank 0 0x0C is reserved */
+ // Bank Select Register
+ /* All Banks */
+ #define BSR_REG               0x000E
+-
+ // Configuration Reg
+ /* BANK 1 */
+ #define CONFIG_REG    SMC_REG(0x0000, 1)
+ #define CONFIG_EXT_PHY        0x0200  // 1=external MII, 0=internal Phy
+ #define CONFIG_GPCNTRL        0x0400  // Inverse value drives pin nCNTRL
+@@ -678,28 +744,24 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode.
+ // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
+ #define CONFIG_DEFAULT        (CONFIG_EPH_POWER_EN)
+-
+ // Base Address Register
+ /* BANK 1 */
+ #define BASE_REG      SMC_REG(0x0002, 1)
+-
+ // Individual Address Registers
+ /* BANK 1 */
+ #define ADDR0_REG     SMC_REG(0x0004, 1)
+ #define ADDR1_REG     SMC_REG(0x0006, 1)
+ #define ADDR2_REG     SMC_REG(0x0008, 1)
+-
+ // General Purpose Register
+ /* BANK 1 */
+ #define GP_REG                SMC_REG(0x000A, 1)
+-
+ // Control Register
+ /* BANK 1 */
+ #define CTL_REG               SMC_REG(0x000C, 1)
+ #define CTL_RCV_BAD   0x4000 // When 1 bad CRC packets are received
+ #define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
+@@ -708,11 +770,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt
+ #define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store
+ #define CTL_RELOAD    0x0002 // When set reads EEPROM into registers
+ #define CTL_STORE     0x0001 // When set stores registers into EEPROM
+-
+ // MMU Command Register
+ /* BANK 2 */
+ #define MMU_CMD_REG   SMC_REG(0x0000, 2)
+ #define MC_BUSY               1       // When 1 the last release has not completed
+ #define MC_NOP                (0<<5)  // No Op
+@@ -722,22 +783,19 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define MC_RELEASE    (4<<5)  // Remove and release the current rx packet
+ #define MC_FREEPKT    (5<<5)  // Release packet in PNR register
+ #define MC_ENQUEUE    (6<<5)  // Enqueue the packet for transmit
+ #define MC_RSTTXFIFO  (7<<5)  // Reset the TX FIFOs
+-
+ // Packet Number Register
+ /* BANK 2 */
+ #define PN_REG                SMC_REG(0x0002, 2)
+-
+ // Allocation Result Register
+ /* BANK 2 */
+ #define AR_REG                SMC_REG(0x0003, 2)
+ #define AR_FAILED     0x80    // Alocation Failed
+-
+ // TX FIFO Ports Register
+ /* BANK 2 */
+ #define TXFIFO_REG    SMC_REG(0x0004, 2)
+ #define TXFIFO_TEMPTY 0x80    // TX FIFO Empty
+@@ -753,21 +811,18 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define PTR_REG               SMC_REG(0x0006, 2)
+ #define PTR_RCV               0x8000 // 1=Receive area, 0=Transmit area
+ #define PTR_AUTOINC   0x4000 // Auto increment the pointer on each access
+ #define PTR_READ      0x2000 // When 1 the operation is a read
+-
+ // Data Register
+ /* BANK 2 */
+ #define DATA_REG      SMC_REG(0x0008, 2)
+-
+ // Interrupt Status/Acknowledge Register
+ /* BANK 2 */
+ #define INT_REG               SMC_REG(0x000C, 2)
+-
+ // Interrupt Mask Register
+ /* BANK 2 */
+ #define IM_REG                SMC_REG(0x000D, 2)
+ #define IM_MDINT      0x80 // PHY MI Register 18 Interrupt
+ #define IM_ERCV_INT   0x40 // Early Receive Interrupt
+@@ -776,48 +831,42 @@ smc_pxa_dma_irq(int dma, void *dummy)
+ #define IM_ALLOC_INT  0x08 // Set when allocation request is completed
+ #define IM_TX_EMPTY_INT       0x04 // Set if the TX FIFO goes empty
+ #define IM_TX_INT     0x02 // Transmit Interrupt
+ #define IM_RCV_INT    0x01 // Receive Interrupt
+-
+ // Multicast Table Registers
+ /* BANK 3 */
+ #define MCAST_REG1    SMC_REG(0x0000, 3)
+ #define MCAST_REG2    SMC_REG(0x0002, 3)
+ #define MCAST_REG3    SMC_REG(0x0004, 3)
+ #define MCAST_REG4    SMC_REG(0x0006, 3)
+-
+ // Management Interface Register (MII)
+ /* BANK 3 */
+ #define MII_REG               SMC_REG(0x0008, 3)
+ #define MII_MSK_CRS100        0x4000 // Disables CRS100 detection during tx half dup
+ #define MII_MDOE      0x0008 // MII Output Enable
+ #define MII_MCLK      0x0004 // MII Clock, pin MDCLK
+ #define MII_MDI               0x0002 // MII Input, pin MDI
+ #define MII_MDO               0x0001 // MII Output, pin MDO
+-
+ // Revision Register
+ /* BANK 3 */
+ /* ( hi: chip id   low: rev # ) */
+ #define REV_REG               SMC_REG(0x000A, 3)
+-
+ // Early RCV Register
+ /* BANK 3 */
+ /* this is NOT on SMC9192 */
+ #define ERCV_REG      SMC_REG(0x000C, 3)
+ #define ERCV_RCV_DISCRD       0x0080 // When 1 discards a packet being received
+ #define ERCV_THRESHOLD        0x001F // ERCV Threshold Mask
+-
+ // External Register
+ /* BANK 7 */
+ #define EXT_REG               SMC_REG(0x0000, 7)
+-
+ #define CHIP_9192     3
+ #define CHIP_9194     4
+ #define CHIP_9195     5
+ #define CHIP_9196     6
+ #define CHIP_91100    7
+@@ -832,12 +881,12 @@ static const char * chip_ids[ 16 ] =  {
+       /* 6 */ "SMC91C96",
+       /* 7 */ "SMC91C100",
+       /* 8 */ "SMC91C100FD",
+       /* 9 */ "SMC91C11xFD",
+       NULL, NULL, NULL,
+-      NULL, NULL, NULL};
+-
++      NULL, NULL, NULL
++};
+ /*
+  . Receive status bits
+ */
+ #define RS_ALGNERR    0x8000
+@@ -847,11 +896,10 @@ static const char * chip_ids[ 16 ] =  {
+ #define RS_TOOLONG    0x0800
+ #define RS_TOOSHORT   0x0400
+ #define RS_MULTICAST  0x0001
+ #define RS_ERRORS     (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
+-
+ /*
+  * PHY IDs
+  *  LAN83C183 == LAN91C111 Internal PHY
+  */
+ #define PHY_LAN83C183 0x0016f840
+@@ -877,11 +925,10 @@ static const char * chip_ids[ 16 ] =  {
+ #define PHY_CFG1_RLVL0                0x0040  // 1=Rx Squelch level reduced by 4.5db
+ #define PHY_CFG1_TLVL_SHIFT   2       // Transmit Output Level Adjust
+ #define PHY_CFG1_TLVL_MASK    0x003C
+ #define PHY_CFG1_TRF_MASK     0x0003  // Transmitter Rise/Fall time
+-
+ // PHY Configuration Register 2
+ #define PHY_CFG2_REG          0x11
+ #define PHY_CFG2_APOLDIS      0x0020  // 1=Auto Polarity Correction disabled
+ #define PHY_CFG2_JABDIS               0x0010  // 1=Jabber disabled
+ #define PHY_CFG2_MREG         0x0008  // 1=Multiple register access (MII mgt)
+@@ -902,11 +949,10 @@ static const char * chip_ids[ 16 ] =  {
+ // PHY Interrupt/Status Mask Register
+ #define PHY_MASK_REG          0x13    // Interrupt Mask
+ // Uses the same bit definitions as PHY_INT_REG
+-
+ /*
+  * SMC91C96 ethernet config and status registers.
+  * These are in the "attribute" space.
+  */
+ #define ECOR                  0x8000
+@@ -920,11 +966,10 @@ static const char * chip_ids[ 16 ] =  {
+ #define ECSR_PWRDWN           0x04
+ #define ECSR_INT              0x02
+ #define ATTRIB_SIZE           ((64*1024) << SMC_IO_SHIFT)
+-
+ /*
+  * Macros to abstract register access according to the data bus
+  * capabilities.  Please use those and not the in/out primitives.
+  * Note: the following macros do *not* select the bank -- this must
+  * be done separately as needed in the main code.  The SMC_REG() macro
+@@ -1087,10 +1132,27 @@ static const char * chip_ids[ 16 ] =  {
+ #define SMC_GET_TCR()         SMC_inw(ioaddr, TCR_REG)
+ #define SMC_SET_TCR(x)                SMC_outw(x, ioaddr, TCR_REG)
+ #ifndef SMC_GET_MAC_ADDR
++#ifdef CONFIG_ARCH_NOMADIK
++#define SMC_GET_MAC_ADDR(addr)                                                \
++      if (new_mac_addr[0] == 0xFF) {                                  \
++              printk("%s: Setting Random MAC addr\n", CARDNAME);      \
++              random_ether_addr(new_mac_addr);                        \
++      }                                                               \
++      SMC_SET_MAC_ADDR(new_mac_addr);                                 \
++      do {                                                            \
++              unsigned int __v;                                       \
++              __v = SMC_inw( ioaddr, ADDR0_REG );                     \
++              addr[0] = __v; addr[1] = __v >> 8;                      \
++              __v = SMC_inw( ioaddr, ADDR1_REG );                     \
++              addr[2] = __v; addr[3] = __v >> 8;                      \
++              __v = SMC_inw( ioaddr, ADDR2_REG );                     \
++              addr[4] = __v; addr[5] = __v >> 8;                      \
++      } while (0)
++#else
+ #define SMC_GET_MAC_ADDR(addr)                                                \
+       do {                                                            \
+               unsigned int __v;                                       \
+               __v = SMC_inw( ioaddr, ADDR0_REG );                     \
+               addr[0] = __v; addr[1] = __v >> 8;                      \
+@@ -1098,10 +1160,11 @@ static const char * chip_ids[ 16 ] =  {
+               addr[2] = __v; addr[3] = __v >> 8;                      \
+               __v = SMC_inw( ioaddr, ADDR2_REG );                     \
+               addr[4] = __v; addr[5] = __v >> 8;                      \
+       } while (0)
+ #endif
++#endif
+ #define SMC_SET_MAC_ADDR(addr)                                                \
+       do {                                                            \
+               SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG );  \
+               SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG );  \
+--- linux-2.6.20.orig/drivers/serial/amba-pl011.c
++++ linux-2.6.20/drivers/serial/amba-pl011.c
+@@ -50,17 +50,36 @@
+ #include <linux/amba/serial.h>
+ #include <linux/clk.h>
+ #include <asm/io.h>
+ #include <asm/sizes.h>
++#include <asm/mach-types.h>
++#include <asm/hardware.h>
+-#define UART_NR                       14
++/*
++ * Definations here is used instead of this which is defined in platform.h
++ */
++
++#ifndef UART_NR
++#define UART_NR                       14      /*default generic value */
++#endif
++
++#ifndef UART_FIFO_SIZE
++#define UART_FIFO_SIZE          16    /*default generic value */
++#endif
++
++#ifndef UART_PER_ID
++#define UART_PER_ID           0x00041011      /*default uart peripharal id */
++#endif
++
++#ifndef UART_PER_MASK
++#define UART_PER_MASK         0x000fffff      /*default uart peripharal mask */
++#endif
+ #define SERIAL_AMBA_MAJOR     204
+ #define SERIAL_AMBA_MINOR     64
+ #define SERIAL_AMBA_NR                UART_NR
+-
+ #define AMBA_ISR_PASS_LIMIT   256
+ #define UART_DR_ERROR         (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
+ #define UART_DUMMY_DR_RX      (1 << 16)
+@@ -100,23 +119,31 @@ static void pl011_stop_rx(struct uart_po
+ }
+ static void pl011_enable_ms(struct uart_port *port)
+ {
+       struct uart_amba_port *uap = (struct uart_amba_port *)port;
++      unsigned cr;
+-      uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
++      uap->im |=
++          UART011_RIMIM | UART011_CTSMIM | UART011_DCDMIM | UART011_DSRMIM;
+       writew(uap->im, uap->port.membase + UART011_IMSC);
++
++      cr = readw(uap->port.membase + UART011_CR);
++      barrier();
++      cr = cr | UART_CONTROL_MASK_CTSFLOW | UART_CONTROL_MASK_RTSFLOW;
++      writew(cr, uap->port.membase + UART011_CR);
+ }
+ static void pl011_rx_chars(struct uart_amba_port *uap)
+ {
+       struct tty_struct *tty = uap->port.info->tty;
+       unsigned int status, ch, flag, max_count = 256;
+       status = readw(uap->port.membase + UART01x_FR);
+       while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
+               ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
++
+               flag = TTY_NORMAL;
+               uap->port.icount.rx++;
+               /*
+                * Note that the error handling code is
+@@ -172,11 +199,13 @@ static void pl011_tx_chars(struct uart_a
+               pl011_stop_tx(&uap->port);
+               return;
+       }
+       count = uap->port.fifosize >> 1;
++
+       do {
++
+               writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               uap->port.icount.tx++;
+               if (uart_circ_empty(xmit))
+                       break;
+@@ -316,10 +345,11 @@ static void pl011_break_ctl(struct uart_
+ static int pl011_startup(struct uart_port *port)
+ {
+       struct uart_amba_port *uap = (struct uart_amba_port *)port;
+       unsigned int cr;
+       int retval;
++      int status, ch;
+       /*
+        * Try to enable the clock producer.
+        */
+       retval = clk_enable(uap->clk);
+@@ -329,36 +359,54 @@ static int pl011_startup(struct uart_por
+       uap->port.uartclk = clk_get_rate(uap->clk);
+       /*
+        * Allocate the IRQ
+        */
+-      retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
++      retval =
++          request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap);
+       if (retval)
+               goto clk_dis;
+-      writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
+-             uap->port.membase + UART011_IFLS);
++      /*
++       *writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
++       *uap->port.membase + UART011_IFLS);
++       */
++
++      writew(UART_TX_RX_HALF, uap->port.membase + UART011_IFLS);
++      /* Clearing interrupts */
++      writew(0x7ff, uap->port.membase + UART011_ICR);
+       /*
+        * Provoke TX FIFO interrupt into asserting.
+        */
+       cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
+       writew(cr, uap->port.membase + UART011_CR);
+       writew(0, uap->port.membase + UART011_FBRD);
+       writew(1, uap->port.membase + UART011_IBRD);
+       writew(0, uap->port.membase + UART011_LCRH);
+-      writew(0, uap->port.membase + UART01x_DR);
++      writew('Z', uap->port.membase + UART01x_DR);
++
++      barrier();
++      ch = readw(uap->port.membase + UART01x_DR);
++
+       while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
+               barrier();
+       cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
+       writew(cr, uap->port.membase + UART011_CR);
+       /*
+        * initialise the old status of the modem signals
+        */
+-      uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
++      uap->old_status =
++          readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
++
++      status = readw(uap->port.membase + UART01x_FR);
++      while ((status & UART01x_FR_RXFE) == 0) {
++              ch = readw(uap->port.membase + UART01x_DR);
++              status = readw(uap->port.membase + UART01x_FR);
++      }
+       /*
+        * Finally, enable interrupts
+        */
+       spin_lock_irq(&uap->port.lock);
+@@ -394,11 +442,12 @@ static void pl011_shutdown(struct uart_p
+       free_irq(uap->port.irq, uap);
+       /*
+        * disable the port
+        */
+-      writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
++      writew(UART01x_CR_UARTEN | UART011_CR_TXE,
++             uap->port.membase + UART011_CR);
+       /*
+        * disable break condition and fifos
+        */
+       val = readw(uap->port.membase + UART011_LCRH);
+@@ -656,10 +705,11 @@ static int __init pl011_console_setup(st
+       /*
+        * Check whether an invalid uart number has been specified, and
+        * if so, search for the first available port that does have
+        * console support.
+        */
++
+       if (co->index >= UART_NR)
+               co->index = 0;
+       uap = amba_ports[co->index];
+       if (!uap)
+               return -ENODEV;
+@@ -698,10 +748,32 @@ static struct uart_driver amba_reg = {
+       .minor                  = SERIAL_AMBA_MINOR,
+       .nr                     = UART_NR,
+       .cons                   = AMBA_CONSOLE,
+ };
++#ifdef CONFIG_PM
++static int pl011_suspend(struct amba_device *dev, pm_message_t state)
++{
++      struct uart_amba_port *uap = amba_get_drvdata(dev);
++
++      if (uap)
++              uart_suspend_port(&amba_reg, &uap->port);
++
++      return 0;
++}
++
++static int pl011_resume(struct amba_device *dev)
++{
++      struct uart_amba_port *uap = amba_get_drvdata(dev);
++
++      if (uap)
++              uart_resume_port(&amba_reg, &uap->port);
++
++      return 0;
++}
++#endif
++
+ static int pl011_probe(struct amba_device *dev, void *id)
+ {
+       struct uart_amba_port *uap;
+       void __iomem *base;
+       int i, ret;
+@@ -737,13 +809,14 @@ static int pl011_probe(struct amba_devic
+       uap->port.dev = &dev->dev;
+       uap->port.mapbase = dev->res.start;
+       uap->port.membase = base;
+       uap->port.iotype = UPIO_MEM;
+       uap->port.irq = dev->irq[0];
+-      uap->port.fifosize = 16;
++      uap->port.fifosize = UART_FIFO_SIZE;
+       uap->port.ops = &amba_pl011_pops;
+       uap->port.flags = UPF_BOOT_AUTOCONF;
++
+       uap->port.line = i;
+       amba_ports[i] = uap;
+       amba_set_drvdata(dev, uap);
+@@ -780,12 +853,12 @@ static int pl011_remove(struct amba_devi
+       return 0;
+ }
+ static struct amba_id pl011_ids[] __initdata = {
+       {
+-              .id     = 0x00041011,
+-              .mask   = 0x000fffff,
++       .id = UART_PER_ID,
++       .mask = UART_PER_MASK,
+       },
+       { 0, 0 },
+ };
+ static struct amba_driver pl011_driver = {
+@@ -793,10 +866,14 @@ static struct amba_driver pl011_driver =
+               .name   = "uart-pl011",
+       },
+       .id_table       = pl011_ids,
+       .probe          = pl011_probe,
+       .remove         = pl011_remove,
++#ifdef CONFIG_PM
++      .suspend = pl011_suspend,
++      .resume = pl011_resume,
++#endif
+ };
+ static int __init pl011_init(void)
+ {
+       int ret;
+--- linux-2.6.20.orig/drivers/spi/Kconfig
++++ linux-2.6.20/drivers/spi/Kconfig
+@@ -63,10 +63,18 @@ config SPI_BITBANG
+         This is library code, and is automatically selected by drivers that
+         need it.  You only need to select this explicitly to support driver
+         modules that aren't part of this kernel tree.
++config NOMADIK_SPI
++      tristate "Nomadik SPI master"
++      depends on SPI_MASTER && EXPERIMENTAL
++      default y
++      help
++        This enables using the Nomadik SPI controller in master
++        mode.
++
+ config SPI_BUTTERFLY
+       tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
+       depends on SPI_MASTER && PARPORT && EXPERIMENTAL
+       select SPI_BITBANG
+       help
+--- linux-2.6.20.orig/drivers/spi/Makefile
++++ linux-2.6.20/drivers/spi/Makefile
+@@ -10,10 +10,12 @@ endif
+ # config declarations into driver model code
+ obj-$(CONFIG_SPI_MASTER)              += spi.o
+ # SPI master controller drivers (bus)
+ obj-$(CONFIG_SPI_BITBANG)             += spi_bitbang.o
++obj-$(CONFIG_NOMADIK_SPI)             += nmdkmod_spi.o
++nmdkmod_spi-objs                      := spi-nomadik.o
+ obj-$(CONFIG_SPI_BUTTERFLY)           += spi_butterfly.o
+ obj-$(CONFIG_SPI_PXA2XX)              += pxa2xx_spi.o
+ obj-$(CONFIG_SPI_MPC83xx)             += spi_mpc83xx.o
+ obj-$(CONFIG_SPI_S3C24XX_GPIO)                += spi_s3c24xx_gpio.o
+ obj-$(CONFIG_SPI_S3C24XX)             += spi_s3c24xx.o
+--- /dev/null
++++ linux-2.6.20/drivers/spi/spi-nomadik.c
+@@ -0,0 +1,1000 @@
++/*
++ * drivers/spi/spi-nomadik.c
++ *
++ * Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
++ *
++ * Author:    Sachin Verma <sachin.verma@st.com>
++ *            Vaibhav Agarwal <vaibhav.agarwal@st.com
++ * Initial version inspired by:
++ *    linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/ioport.h>
++#include <linux/errno.h>
++#include <linux/platform_device.h>
++#include <linux/amba/bus.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/hardware.h>
++#include <asm/delay.h>
++
++#include <asm/arch/hardware.h>
++#include <asm/arch/defs.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/spi.h>
++#include <asm/arch/debug.h>
++#include <asm/arch/ssp-spi.h>
++#include <asm/arch/msp-spi.h>
++#include <asm/arch/msp.h>
++
++/***************************************************************************/
++
++#define NMDK_SPI_NAME         "NOMADIK_SPI"
++
++#ifndef SPI_DEBUG
++#define SPI_DEBUG 0
++#endif
++
++#define NMDK_DEBUG    SPI_DEBUG       /* enables/disables nmdk_dbg msgs */
++#define NMDK_DEBUG_PFX  NMDK_SPI_NAME /* msg header represents this module */
++#define NMDK_DBG      KERN_ERR        /* message level */
++
++/***************************************************************************/
++
++#define FALSE                                 (0)
++#define TRUE                          (1)
++
++#define DO_NOT_QUEUE_DMA      (0)
++#define QUEUE_DMA             (1)
++
++/*#######################################################################
++      Queue State
++#########################################################################
++ */
++#define QUEUE_RUNNING                   (0)
++#define QUEUE_STOPPED                   (1)
++
++/***************************************************************************/
++static void print_dma_info(u32 xfer_type, struct chip_data *chip){
++      nmdk_dbg("Rx Pipe : mode = %08x\n", chip->dma_info->rx_dma_info.mode);
++      nmdk_dbg("Rx Pipe : config = %08x\n", chip->dma_info->rx_dma_info.config);
++      nmdk_dbg("Rx Pipe : srcdevtype = %s\n", chip->dma_info->rx_dma_info.srcdevtype);
++      nmdk_dbg("Rx Pipe : destdevtype = %s\n", chip->dma_info->rx_dma_info.destdevtype);
++
++      nmdk_dbg("Tx Pipe : mode = %08x\n", chip->dma_info->tx_dma_info.mode);
++      nmdk_dbg("Tx Pipe : config = %08x\n", chip->dma_info->tx_dma_info.config);
++      nmdk_dbg("Tx Pipe : srcdevtype = %s\n", chip->dma_info->tx_dma_info.srcdevtype);
++      nmdk_dbg("Tx Pipe : destdevtype = %s\n", chip->dma_info->tx_dma_info.destdevtype);
++}
++/***************************************************************************/
++
++/**
++ * null_cs_control - Dummy chip select function
++ * @command: select/delect the chip
++ *
++ * If no chip select function is provided by client this is used as dummy
++ * chip select
++ */
++void null_cs_control(u32 command)
++{
++      nmdk_dbg_ftrace();
++      nmdk_dbg("::::Dummy chip select control\n");
++}
++EXPORT_SYMBOL(null_cs_control);
++
++void nomadik_spi_tasklet(unsigned long param)
++{
++      struct driver_data *drv_data = (struct driver_data *)param;
++      struct spi_message *msg = drv_data->cur_msg;
++      struct spi_transfer *previous = NULL;
++      /*DMA complete. schedule next xfer */
++      /*DISABLE DMA, and flush FIFO of SPI Controller */
++      drv_data->execute_cmd(drv_data, DISABLE_DMA);
++      drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++      msg->actual_length += drv_data->cur_transfer->len;
++      if (drv_data->cur_transfer->cs_change)
++              drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
++      msg->state = next_transfer(drv_data);
++      if (msg->state == ERROR_STATE)
++              goto handle_dma_error;
++      else if (msg->state == DONE_STATE) {
++              drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++              msg->status = 0;
++              giveback(msg, drv_data);
++              return ;
++      }
++      /* Delay if requested at end of transfer */
++      else if (msg->state == RUNNING_STATE) {
++              previous =
++                      list_entry(drv_data->cur_transfer->transfer_list.
++                                      prev, struct spi_transfer,
++                                      transfer_list);
++              if (previous->delay_usecs)
++                      udelay(previous->delay_usecs);
++              if (previous->cs_change)
++                      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++      } else  goto handle_dma_error;
++
++      if (drv_data->cur_transfer->tx_dma) {
++              atomic_inc(&drv_data->dma_cnt);
++              __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach, (dma_addr_t) (drv_data->cur_transfer->tx_dma));
++              __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
++                              (dma_addr_t) (drv_data->master_info->dma_srcaddr));
++              set_dma_count(drv_data->cur_chip->dma_info->tx_dmach, (drv_data->cur_transfer->len));
++              enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
++      }
++      if (drv_data->cur_transfer->rx_dma) {
++              atomic_inc(&drv_data->dma_cnt);
++              __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
++                              (dma_addr_t) (drv_data->master_info->dma_destaddr));
++              __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach, (dma_addr_t) (drv_data->cur_transfer->rx_dma));
++              set_dma_count(drv_data->cur_chip->dma_info->rx_dmach, (drv_data->cur_transfer->len));
++              enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
++      }
++      /*Enable DMA for this chip */
++      drv_data->execute_cmd(drv_data, ENABLE_DMA);
++      return ;
++
++      handle_dma_error:
++         atomic_set(&drv_data->dma_cnt, 0);
++        drv_data->execute_cmd(drv_data, DISABLE_DMA);
++        msg->status = -EIO;
++        giveback(msg, drv_data);
++        return ;
++}
++EXPORT_SYMBOL(nomadik_spi_tasklet);
++
++/**
++ * spi_dma_callback_handler - This function is invoked when dma xfer is complete
++ * @param: context data which is drivers private data
++ * @event: Status of current DMA transfer
++ *
++ * This function checks if DMA transfer is complete for current transfer
++ * It fills the Rx Tx buffer pointers again and launch dma for next
++ * transfer from this callback handler itself
++ *
++ */
++irqreturn_t spi_dma_callback_handler(int irq, void *param)
++{
++        struct driver_data *drv_data = (struct driver_data *)param;
++      int flag = 0;
++
++        nmdk_dbg_ftrace();
++
++        smp_mb();
++        if (atomic_dec_and_test(&drv_data->dma_cnt)) {
++                flag = 1;
++        }
++        smp_mb();
++        if (flag == 1) {
++      tasklet_schedule(&drv_data->spi_dma_tasklet);
++      }
++      return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(spi_dma_callback_handler);
++
++/**
++ * giveback - current spi_message is over, schedule next spi_message and call callback of this msg
++ * @message: current SPI message
++ * @drv_data: spi driver private data structure
++ *
++ */
++void giveback(struct spi_message *message, struct driver_data *drv_data)
++{
++      struct spi_transfer *last_transfer;
++      unsigned long flags;
++      struct spi_message *msg;
++      void (*curr_cs_control) (u32 command);
++
++      spin_lock_irqsave(&drv_data->lock, flags);
++      msg = drv_data->cur_msg;
++
++      curr_cs_control = drv_data->cur_chip->cs_control;
++      drv_data->cur_msg = NULL;
++      drv_data->cur_transfer = NULL;
++      drv_data->cur_chip = NULL;
++#ifdef SPI_WORKQUEUE
++      queue_work(drv_data->workqueue, &drv_data->spi_work);
++#endif
++      spin_unlock_irqrestore(&drv_data->lock, flags);
++
++      schedule_work(&drv_data->spi_work);
++
++      last_transfer = list_entry(msg->transfers.prev,
++                                 struct spi_transfer, transfer_list);
++      if (!last_transfer->cs_change)
++              curr_cs_control(SPI_CHIP_DESELECT);
++      msg->state = NULL;
++      if (msg->complete)
++              msg->complete(msg->context);
++      drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++}
++EXPORT_SYMBOL(giveback);
++
++/**
++ * next_transfer - Move to the Next transfer in the current spi message
++ * @drv_data: spi driver private data structure
++ *
++ * This function moves though the linked list of spi transfers in the
++ * current spi message and returns with the state of current spi
++ * message i.e whether its last transfer is done(DONE_STATE) or
++ * Next transfer is ready(RUNNING_STATE)
++ */
++void *next_transfer(struct driver_data *drv_data)
++{
++      struct spi_message *msg = drv_data->cur_msg;
++      struct spi_transfer *trans = drv_data->cur_transfer;
++      /* Move to next transfer */
++      if (trans->transfer_list.next != &msg->transfers) {
++              drv_data->cur_transfer =
++                  list_entry(trans->transfer_list.next,
++                             struct spi_transfer, transfer_list);
++              return RUNNING_STATE;
++      }
++      return DONE_STATE;
++}
++EXPORT_SYMBOL(next_transfer);
++
++/**
++ * ssp_null_writer - To Write Dummy Data in Data register
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a write function for transfer which have
++ * Tx transfer buffer as NULL. It simply writes '0' in the Data
++ * register
++ */
++static void ssp_null_writer(struct driver_data *drv_data)
++{
++      while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF)
++             && (drv_data->tx < drv_data->tx_end)) {
++              /*Write '0' Data to Data Register */
++              writel(0x0, SSP_DR(drv_data->regs));
++              drv_data->tx += (drv_data->cur_chip->n_bytes);
++      }
++}
++
++/**
++ * ssp_null_reader - To read data from Data register and discard it
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a reader function for transfer which have
++ * Rx Transfer buffer as null. Read Data is rejected
++ *
++ */
++static void ssp_null_reader(struct driver_data *drv_data)
++{
++      while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE)
++             && (drv_data->rx < drv_data->rx_end)) {
++              readl(SSP_DR(drv_data->regs));
++              drv_data->rx += (drv_data->cur_chip->n_bytes);
++      }
++}
++
++/**
++ * msp_null_writer - To Write Dummy Data in Data register
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a write function for transfer which have
++ * Tx transfer buffer as NULL. It simply writes '0' in the Data
++ * register
++ */
++static void msp_null_writer(struct driver_data *drv_data)
++{
++      u32 cur_write = 0;
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
++              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
++                      return;
++              writel( 0x0, MSP_DR(drv_data->regs));
++              drv_data->tx += (drv_data->cur_chip->n_bytes);
++              cur_write ++;
++              if(cur_write == 8)
++                      return;
++      }
++}
++
++/**
++ * msp_null_reader - To read data from Data register and discard it
++ * @drv_data: spi driver private data structure
++ *
++ * This function is set as a reader function for transfer which have
++ * Rx Transfer buffer as null. Read Data is rejected
++ *
++ */
++static void msp_null_reader(struct driver_data *drv_data)
++{
++      u32 status;
++      while(1){
++              status = readl(MSP_FLR(drv_data->regs));
++              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
++                      return;
++              readl(MSP_DR(drv_data->regs));
++              drv_data->rx += (drv_data->cur_chip->n_bytes);
++      }
++}
++
++/**
++ * pump_transfers - Tasklet function which schedules next interrupt xfer
++ * @data: spi driver private data structure
++ *
++ */
++static void pump_transfers(unsigned long data)
++{
++      struct driver_data *drv_data = (struct driver_data *)data;
++      struct spi_message *message = NULL;
++      struct spi_transfer *transfer = NULL;
++      struct spi_transfer *previous = NULL;
++
++      nmdk_dbg_ftrace();
++
++      message = drv_data->cur_msg;
++      /* Handle for abort */
++      if (message->state == ERROR_STATE) {
++              message->status = -EIO;
++              giveback(message, drv_data);
++              return;
++      }
++      /* Handle end of message */
++      if (message->state == DONE_STATE) {
++              message->status = 0;
++              giveback(message, drv_data);
++              return;
++      }
++      transfer = drv_data->cur_transfer;
++      /* Delay if requested at end of transfer */
++      if (message->state == RUNNING_STATE) {
++              previous =
++                  list_entry(transfer->transfer_list.prev,
++                             struct spi_transfer, transfer_list);
++              if (previous->delay_usecs)
++                      udelay(previous->delay_usecs);
++              if (previous->cs_change)
++                      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++      } else {
++              /* START_STATE */
++              message->state = RUNNING_STATE;
++      }
++      drv_data->tx = (void *)transfer->tx_buf;
++      drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
++      drv_data->rx = (void *)transfer->rx_buf;
++      drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++
++      if(drv_data->master->bus_num == SSP_CONTROLLER){
++              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
++              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++      }
++      else{
++              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
++              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++      }
++
++      drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++      drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
++}
++
++/**
++ * do_dma_transfer - It handles transfers of the current message if it is DMA xfer
++ * @data: spi driver's private data structure
++ *
++ *
++ *
++ */
++static void do_dma_transfer(void *data)
++{
++        struct driver_data *drv_data = (struct driver_data *)data;
++
++        atomic_set(&drv_data->dma_cnt, 0);
++        drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++
++        if ((drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_MEM) ||
++            (drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_PERIPH)) {
++                if (drv_data->cur_chip->dma_info->tx_dmach >= 0) {
++                        atomic_inc(&drv_data->dma_cnt);
++                        __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach,
++                            (dma_addr_t) (drv_data->cur_transfer->tx_dma));
++                        __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
++                            (dma_addr_t) (drv_data->master_info->dma_srcaddr));
++                        set_dma_count(drv_data->cur_chip->dma_info->tx_dmach,
++                            (drv_data->cur_transfer->len));
++                      enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
++                }
++                if (drv_data->cur_chip->dma_info->rx_dmach >= 0) {
++                        atomic_inc(&drv_data->dma_cnt);
++                        __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
++                            (dma_addr_t) (drv_data->master_info->dma_destaddr));
++                        __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach,
++                            (dma_addr_t) (drv_data->cur_transfer->rx_dma));
++                        set_dma_count(drv_data->cur_chip->dma_info->rx_dmach,
++                            (drv_data->cur_transfer->len));
++                        enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
++                }
++                if((drv_data->cur_chip->dma_info->tx_dma_info.mode & DMA_INFINITE_XFER) &&
++                        (drv_data->cur_chip->dma_info->rx_dma_info.mode & DMA_INFINITE_XFER)){
++                        /*Only if it is an infinite transfer, we will deploy mechanism to stop it*/
++                        nmdk_dbg("Only if it is an infinite transfer, we will deploy mechanism to stop it");
++                        drv_data->dma_ongoing = 1;
++                }
++        } else {
++                nmdk_dbg(":::: Invalid DMA xfer type \n");
++                goto err_dma_transfer;
++        }
++        /*Enable SPI Controller */
++        drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++        return;
++
++      err_dma_transfer:
++        drv_data->cur_msg->state = ERROR_STATE;
++        drv_data->cur_msg->status = -EIO;
++        giveback(drv_data->cur_msg, drv_data);
++        return;
++}
++
++static void do_interrupt_transfer(void *data)
++{
++      struct driver_data *drv_data = (struct driver_data *)data;
++
++      drv_data->tx = (void *)drv_data->cur_transfer->tx_buf;
++      drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
++      drv_data->rx = (void *)drv_data->cur_transfer->rx_buf;
++      drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++
++      if(drv_data->master->bus_num == SSP_CONTROLLER){
++              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
++              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++      }
++      else{
++              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
++              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++      }
++
++      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++
++      drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
++      drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++}
++
++static void do_polling_transfer(void *data)
++{
++      struct driver_data *drv_data = (struct driver_data *)data;
++      struct spi_message *message = NULL;
++      struct spi_transfer *transfer = NULL;
++      struct spi_transfer *previous = NULL;
++      struct chip_data *chip;
++      unsigned long limit = 0;
++
++      chip = drv_data->cur_chip;
++      message = drv_data->cur_msg;
++
++      while (message->state != DONE_STATE) {
++              /* Handle for abort */
++              if (message->state == ERROR_STATE)
++                      break;
++              transfer = drv_data->cur_transfer;
++
++              /* Delay if requested at end of transfer */
++              if (message->state == RUNNING_STATE) {
++                      previous =
++                          list_entry(transfer->transfer_list.prev,
++                                     struct spi_transfer, transfer_list);
++                      if (previous->delay_usecs)
++                              udelay(previous->delay_usecs);
++                      if (previous->cs_change)
++                              drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++              } else {
++                      /* START_STATE */
++                      message->state = RUNNING_STATE;
++                      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++              }
++
++              /*Configuration Changing Per Transfer */
++              drv_data->tx = (void *)transfer->tx_buf;
++              drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
++              drv_data->rx = (void *)transfer->rx_buf;
++              drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++
++              if(drv_data->master->bus_num == SSP_CONTROLLER){
++                      drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
++                      drv_data->read =  drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++              }
++              else{
++                      drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
++                      drv_data->read =  drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++              }
++
++              drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++              drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++
++              nmdk_dbg(":::: POLLING TRANSFER ONGOING ... \n");
++              while (drv_data->tx < drv_data->tx_end) {
++                      drv_data->read(drv_data);
++                      drv_data->write(drv_data);
++              }
++
++              limit = loops_per_jiffy << 1;
++
++              while ((drv_data->rx < drv_data->rx_end) && (limit--)){
++                      drv_data->read(drv_data);
++              }
++
++              /* Update total byte transfered */
++              message->actual_length += drv_data->cur_transfer->len;
++              if (drv_data->cur_transfer->cs_change)
++                      drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
++              drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++
++              /* Move to next transfer */
++              message->state = next_transfer(drv_data);
++      }
++
++      /* Handle end of message */
++      if (message->state == DONE_STATE)
++              message->status = 0;
++      else
++              message->status = -EIO;
++
++      giveback(message, drv_data);
++      return;
++}
++/**
++ * pump_messages - Workqueue function which processes spi message queue
++ * @data: pointer to private data of spi driver
++ *
++ * This function checks if there is any spi message in the queue that
++ * needs processing and delegate control to appropriate function
++ * do_polling_transfer()/do_interrupt_transfer()/do_dma_transfer()
++ * based on the kind of the transfer
++ *
++ */
++static void pump_messages(struct work_struct *work)
++{
++      struct driver_data *drv_data = container_of(work, struct driver_data,spi_work);
++      unsigned long flags;
++
++      /* Lock queue and check for queue work */
++      spin_lock_irqsave(&drv_data->lock, flags);
++      if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
++              nmdk_dbg(":::: work_queue: Queue Empty\n");
++              drv_data->busy = 0;
++              spin_unlock_irqrestore(&drv_data->lock, flags);
++              return;
++      }
++      /* Make sure we are not already running a message */
++      if (drv_data->cur_msg) {
++              spin_unlock_irqrestore(&drv_data->lock, flags);
++              return;
++      }
++
++      /* Extract head of queue */
++      drv_data->cur_msg =
++          list_entry(drv_data->queue.next, struct spi_message, queue);
++
++      list_del_init(&drv_data->cur_msg->queue);
++      drv_data->busy = 1;
++      spin_unlock_irqrestore(&drv_data->lock, flags);
++
++      /* Initial message state */
++      drv_data->cur_msg->state = START_STATE;
++      drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
++                                          struct spi_transfer, transfer_list);
++
++      /* Setup the SPI using the per chip configuration */
++      drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
++      drv_data->execute_cmd(drv_data, RESTORE_STATE);
++      drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++
++      if (drv_data->cur_chip->xfer_type == POLLING_TRANSFER)
++              do_polling_transfer(drv_data);
++      else if (drv_data->cur_chip->xfer_type == INTERRUPT_TRANSFER)
++              do_interrupt_transfer(drv_data);
++      else /* DMA_TRANSFER*/
++              do_dma_transfer(drv_data);
++}
++
++int init_queue(struct driver_data *drv_data)
++{
++      INIT_LIST_HEAD(&drv_data->queue);
++      spin_lock_init(&drv_data->lock);
++
++      drv_data->run = QUEUE_STOPPED;
++      drv_data->busy = 0;
++
++      tasklet_init(&drv_data->pump_transfers, pump_transfers,
++                   (unsigned long)drv_data);
++      INIT_WORK(&drv_data->spi_work, pump_messages);
++#ifdef SPI_WORKQUEUE
++      drv_data->workqueue = create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id);
++      if (drv_data->workqueue == NULL)
++            return -EBUSY;
++#endif
++      return 0;
++}
++EXPORT_SYMBOL(init_queue);
++
++int start_queue(struct driver_data *drv_data)
++{
++      unsigned long flags;
++      spin_lock_irqsave(&drv_data->lock, flags);
++      if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
++              spin_unlock_irqrestore(&drv_data->lock, flags);
++              return -EBUSY;
++      }
++      drv_data->run = QUEUE_RUNNING;
++      drv_data->cur_msg = NULL;
++      drv_data->cur_transfer = NULL;
++      drv_data->cur_chip = NULL;
++      spin_unlock_irqrestore(&drv_data->lock, flags);
++      /*queue_work(drv_data->workqueue, &drv_data->pump_messages);*/
++      /*schedule_work(&drv_data->spi_work);*/
++      return 0;
++}
++EXPORT_SYMBOL(start_queue);
++
++int stop_queue(struct driver_data *drv_data)
++{
++      unsigned long flags;
++      unsigned limit = 500;
++      int status = 0;
++
++      spin_lock_irqsave(&drv_data->lock, flags);
++
++      /* This is a bit lame, but is optimized for the common execution path.
++       * A wait_queue on the drv_data->busy could be used, but then the common
++       * execution path (pump_messages) would be required to call wake_up or
++       * friends on every SPI message. Do this instead */
++      drv_data->run = QUEUE_STOPPED;
++      while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
++              spin_unlock_irqrestore(&drv_data->lock, flags);
++              msleep(10);
++              spin_lock_irqsave(&drv_data->lock, flags);
++      }
++      if (!list_empty(&drv_data->queue) || drv_data->busy)
++              status = -EBUSY;
++
++      spin_unlock_irqrestore(&drv_data->lock, flags);
++
++      return status;
++}
++EXPORT_SYMBOL(stop_queue);
++
++int destroy_queue(struct driver_data *drv_data)
++{
++      int status;
++      status = stop_queue(drv_data);
++      if (status != 0)
++              return status;
++#ifdef SPI_WORKQUEUE
++      destroy_workqueue(drv_data->workqueue);
++#endif
++      return 0;
++}
++EXPORT_SYMBOL(destroy_queue);
++
++/**
++ * nomadik_spi_transfer - transfer function registered to SPI master framework
++ * @spi: spi device which is requesting transfer
++ * @msg: spi message which is to handled is queued to driver queue
++ *
++ * This function is registered to the SPI framework for this SPI master
++ * controller. It will queue the spi_message in the queue of driver if
++ * the queue is not stopped and return.
++ */
++int nomadik_spi_transfer(struct spi_device *spi, struct spi_message *msg)
++{
++      struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++      unsigned long flags;
++
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++      struct spi_master *master;
++      int status = 0;
++#endif
++
++      nmdk_dbg_ftrace();
++
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++      master = drv_data->master;
++      switch(master->bus_num) {
++              case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user != SPI_USER_MSP) {
++                              status = -EINVAL;
++                              printk("MSP0 already in use in %d mode", drv_data->flag_msp0->user);
++                      }
++                      break;
++              case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user != SPI_USER_MSP) {
++                              status = -EINVAL;
++                              printk("MSP1 already in use in %d mode", drv_data->flag_msp1->user);
++                      }
++                      break;
++              case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user != SPI_USER_MSP) {
++                              status = -EINVAL;
++                              printk("MSP2 already in use in %d mode", drv_data->flag_msp2->user);
++                      }
++                      break;
++      }
++      if(status)
++              return status;
++#endif
++      spin_lock_irqsave(&drv_data->lock, flags);
++
++
++      if (drv_data->run == QUEUE_STOPPED) {
++              spin_unlock_irqrestore(&drv_data->lock, flags);
++              return -ESHUTDOWN;
++      }
++      if(drv_data->dma_ongoing){
++              struct chip_data *chip;
++              chip = spi_get_ctldata(spi);
++              nmdk_dbg(":::: Current chip(%p), Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip, chip->chip_id);
++              nmdk_dbg(":::: Current chip Id (doing infinite DMA): %d -- Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip->chip_id, chip->chip_id);
++              if(drv_data->cur_chip->chip_id != chip->chip_id){
++                      nmdk_dbg(":::: Chip_id are not same, Hence current DMA xfer not disabled \n");
++              }
++              else{
++                      nmdk_dbg(":::: Chip_id are same. Disabling current infinite DMA xfer\n");
++
++                      drv_data->dma_ongoing = 0;
++
++                      if (drv_data->cur_chip->dma_info->tx_dmach != -1) {
++                              free_dma(drv_data->cur_chip->dma_info->tx_dmach);
++                              drv_data->cur_chip->dma_info->tx_dmach = -1;
++                      }
++                      if (drv_data->cur_chip->dma_info->rx_dmach != -1) {
++                              free_dma(drv_data->cur_chip->dma_info->rx_dmach);
++                              drv_data->cur_chip->dma_info->rx_dmach = -1;
++                      }
++                      drv_data->execute_cmd(drv_data, DISABLE_DMA);
++                      drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++                      drv_data->cur_msg = NULL;
++                      drv_data->cur_transfer = NULL;
++                      drv_data->cur_chip = NULL;
++#ifdef SPI_WORKQUEUE
++                      queue_work(drv_data->workqueue, &drv_data->spi_work);
++#else
++                      schedule_work(&drv_data->spi_work);
++#endif
++              }
++              spin_unlock_irqrestore(&drv_data->lock, flags);
++              return 0;
++      }
++
++      nmdk_dbg(":::: Regular request (No infinite DMA ongoing)\n");
++
++      msg->actual_length = 0;
++      msg->status = -EINPROGRESS;
++      msg->state = START_STATE;
++
++      list_add_tail(&msg->queue, &drv_data->queue);
++      if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
++#ifdef SPI_WORKQUEUE
++              queue_work(drv_data->workqueue, &drv_data->spi_work);
++#else
++              schedule_work(&drv_data->spi_work);
++#endif
++
++      spin_unlock_irqrestore(&drv_data->lock, flags);
++      return 0;
++}
++EXPORT_SYMBOL(nomadik_spi_transfer);
++
++int calculate_effective_freq(int freq, t_ssp_clock_params * clk_freq)
++{
++      /*Lets calculate the frequency parameters */
++      uint32 cpsdvsr = 2;
++      uint32 scr = 0;
++      bool_t freq_found = FALSE;
++      uint32 max_tclk;
++      uint32 min_tclk;
++
++      nmdk_dbg_ftrace();
++
++      max_tclk = (NMDK_SSP_CLOCK_FREQ / (MIN_CPSDVR * (1 + MIN_SCR)));        /* cpsdvscr = 2 & scr 0 */
++      min_tclk = (NMDK_SSP_CLOCK_FREQ / (MAX_CPSDVR * (1 + MAX_SCR)));        /* cpsdvsr = 254 & scr = 255 */
++
++      if ((freq <= max_tclk) && (freq >= min_tclk)) {
++              while (cpsdvsr <= MAX_CPSDVR && !freq_found) {
++                      while (scr <= MAX_SCR && !freq_found) {
++                              if ((NMDK_SSP_CLOCK_FREQ /
++                                   (cpsdvsr * (1 + scr))) > freq)
++                                      scr += 1;
++                              else {
++                                      /* This bool is made TRUE when effective frequency >= target frequency is found */
++                                      freq_found = TRUE;
++                                      if ((NMDK_SSP_CLOCK_FREQ /
++                                           (cpsdvsr * (1 + scr))) != freq) {
++                                              if (scr == MIN_SCR) {
++                                                      cpsdvsr -= 2;
++                                                      scr = MAX_SCR;
++                                              } else
++                                                      scr -= 1;
++                                      }
++                              }
++                      }
++                      if (!freq_found) {
++                              cpsdvsr += 2;
++                              scr = MIN_SCR;
++                      }
++              }
++              if (cpsdvsr != 0) {
++                      nmdk_dbg(":::: SSP Effective Frequency is %ld\n",    (NMDK_SSP_CLOCK_FREQ / (cpsdvsr * (1 + scr))));
++                      clk_freq->cpsdvsr = (uint8) (cpsdvsr & 0xFF);
++                      clk_freq->scr = (uint8) (scr & 0xFF);
++                      nmdk_dbg(":::: SSP cpsdvsr = %d, scr = %d\n",
++                          clk_freq->cpsdvsr, clk_freq->scr);
++              }
++      } else {
++              /*User is asking for out of range Freq. */
++              nmdk_dbg(":::: setup - controller data is incorrect: Out of Range Frequency");
++              return -EINVAL;
++      }
++      return 0;
++}
++EXPORT_SYMBOL(calculate_effective_freq);
++
++/**
++ * process_dma_info - Processes the DMA info provided by client drivers
++ * @chip_info: chip info provided by client device
++ * @chip: Runtime state maintained by the spi controller for each spi device
++ *
++ * This function processes and stores DMA config provided by client driver
++ * into the runtime state maintained by the spi controller driver
++ */
++int process_dma_info(struct nmdk_spi_config_chip *chip_info,
++                          struct chip_data *chip, void * data)
++{
++      struct driver_data *drv_data = (struct driver_data *)data;
++
++      /* default setup required for any SPI dma transfer*/
++        chip->dma_info->rx_dma_info.srcdevtype = drv_data->master_info->dma_srcdevtype;
++      chip->dma_info->rx_dma_info.config = 0;
++
++      chip->dma_info->tx_dma_info.destdevtype = drv_data->master_info->dma_destdevtype;
++      chip->dma_info->tx_dma_info.config = 0;
++
++      if (chip_info->dma_xfer_type == SPI_WITH_MEM) {
++              chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_MEM);
++              chip->dma_info->rx_dma_info.destdevtype = "mem";
++
++              chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(MEM_TO_PERIPH);
++              chip->dma_info->tx_dma_info.srcdevtype = "mem";
++              if (chip_info->dma_config) {
++                      chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++                      chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++                      if (chip_info->dma_config->tx_client_dmadev_config) {
++                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
++                      }
++                      if (chip_info->dma_config->rx_client_dmadev_config) {
++                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
++                      }
++                      if (chip_info->dma_config->tx_master_dmadev_config) {
++                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
++                      }
++                      if (chip_info->dma_config->rx_master_dmadev_config) {
++                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
++                      }
++              }
++      } else { /*SPI_WITH_PERIPH*/
++              chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
++                chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
++              if (chip_info->dma_config) {
++                      chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++                      chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
++                      if (chip_info->dma_config->tx_client_dmadev_config) {
++                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
++                              chip->dma_info->rx_dma_info.destdevtype = chip_info->dma_config->tx_client_dmadev_config->devtype;
++                      }
++                      if (chip_info->dma_config->rx_client_dmadev_config) {
++                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
++                              chip->dma_info->tx_dma_info.srcdevtype = chip_info->dma_config->rx_client_dmadev_config->devtype;
++                      }
++                      if (chip_info->dma_config->tx_master_dmadev_config) {
++                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
++                      }
++                      if (chip_info->dma_config->rx_master_dmadev_config) {
++                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
++                      }
++              } else return -EINVAL;
++      }
++
++      print_dma_info(chip_info->dma_xfer_type, chip);
++      return 0;
++}
++
++EXPORT_SYMBOL(process_dma_info);
++
++/**
++ * nomadik_spi_cleanup - cleanup function registered to SPI master framework
++ * @spi: spi device which is requesting cleanup
++ *
++ * This function is registered to the SPI framework for this SPI master
++ * controller. It will free the runtime state of chip.
++ */
++void nomadik_spi_cleanup(const struct spi_device *spi)
++{
++      struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
++      struct driver_data *drv_data = spi_master_get_devdata(spi->master);
++      struct spi_master *master;
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++      int status =0;
++#endif
++      nmdk_dbg_ftrace();
++
++      master = drv_data->master;
++
++#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
++      switch(master->bus_num) {
++              case MSP_0_CONTROLLER:  if(drv_data->flag_msp0->user == SPI_USER_MSP) {
++                                              down(&drv_data->flag_msp0->lock);
++                                              drv_data->flag_msp0->user = SPI_NO_MSP_USER;
++                                              up(&drv_data->flag_msp0->lock);
++                                              nmdk_dbg("Flag cleanup for MSP0\n");
++                                      }
++                                      else {
++                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", (drv_data->flag_msp0->user));
++                                              status = -EFAULT;
++                                      }
++                                      break;
++              case MSP_1_CONTROLLER:  if(drv_data->flag_msp1->user == SPI_USER_MSP) {
++                                              down(&drv_data->flag_msp1->lock);
++                                              drv_data->flag_msp1->user = SPI_NO_MSP_USER;
++                                              up(&drv_data->flag_msp1->lock);
++                                              nmdk_dbg("Flag cleanup for MSP1\n");
++                                      }
++                                      else {
++                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++              case MSP_2_CONTROLLER:  if(drv_data->flag_msp2->user == SPI_USER_MSP) {
++                                              down(&drv_data->flag_msp2->lock);
++                                              drv_data->flag_msp2->user = SPI_NO_MSP_USER;
++                                              up(&drv_data->flag_msp2->lock);
++                                              nmdk_dbg("Flag cleanup for MSP2\n");
++                                      }
++                                      else {
++                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
++                                              status = -EFAULT;
++                                      }
++                                      break;
++      }
++      if(status)
++              return ;
++#endif
++      if((master->bus_num == MSP_0_CONTROLLER) ||(master->bus_num == MSP_1_CONTROLLER) || (master->bus_num == MSP_2_CONTROLLER)) {
++              nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
++              free_irq(drv_data->adev->irq[0], drv_data);
++      }
++        if (chip){
++                if(chip->dma_info) {
++                        if (chip->dma_info->tx_dmach != -1) {
++                                free_dma(chip->dma_info->tx_dmach);
++                                chip->dma_info->tx_dmach = -1;
++                        }
++                        if (chip->dma_info->rx_dmach != -1) {
++                                free_dma(chip->dma_info->rx_dmach);
++                                chip->dma_info->rx_dmach = -1;
++                        }
++                        kfree(chip->dma_info);
++                }
++                kfree(chip);
++        }
++}
++EXPORT_SYMBOL(nomadik_spi_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Sachin Verma <sachin.verma@st.com> : Vaibhav Agarwal <vaibhav.agarwal@st.com");
++MODULE_DESCRIPTION("Nomadik SPI driver");
+--- linux-2.6.20.orig/drivers/usb/Kconfig
++++ linux-2.6.20/drivers/usb/Kconfig
+@@ -131,7 +131,9 @@ source "drivers/usb/misc/Kconfig"
+ source "drivers/usb/atm/Kconfig"
+ source "drivers/usb/gadget/Kconfig"
++source "drivers/usb/nomadik/Kconfig"
++
+ endmenu
+--- linux-2.6.20.orig/drivers/usb/Makefile
++++ linux-2.6.20/drivers/usb/Makefile
+@@ -65,8 +65,9 @@ obj-$(CONFIG_USB_PHIDGETSERVO)       += misc/
+ obj-$(CONFIG_USB_RIO500)      += misc/
+ obj-$(CONFIG_USB_SISUSBVGA)   += misc/
+ obj-$(CONFIG_USB_TEST)                += misc/
+ obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/
+ obj-$(CONFIG_USB_USS720)      += misc/
++obj-y                         += nomadik/
+ obj-$(CONFIG_USB_ATM)         += atm/
+ obj-$(CONFIG_USB_SPEEDTOUCH)  += atm/
+--- linux-2.6.20.orig/drivers/usb/gadget/file_storage.c
++++ linux-2.6.20/drivers/usb/gadget/file_storage.c
+@@ -270,16 +270,15 @@ static const char shortname[] = DRIVER_N
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_AUTHOR("Alan Stern");
+ MODULE_LICENSE("Dual BSD/GPL");
+-/* Thanks to NetChip Technologies for donating this product ID.
+- *
+- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+- * Instead:  allocate your own, using normal USB-IF procedures. */
+-#define DRIVER_VENDOR_ID      0x0525  // NetChip
+-#define DRIVER_PRODUCT_ID     0xa4a5  // Linux-USB File-backed Storage Gadget
++/*
++ * Replaced with ST ID
++ */
++#define DRIVER_VENDOR_ID      0x0483  // ST ID
++#define DRIVER_PRODUCT_ID     0x8815  // 0xa4a5 Linux-USB File-backed Storage Gadget
+ /*
+  * This driver assumes self-powered hardware and has no way for users to
+  * trigger remote wakeup.  It uses autoconfiguration to select endpoints
+@@ -371,11 +370,11 @@ static struct {
+ } mod_data = {                                        // Default values
+       .transport_parm         = "BBB",
+       .protocol_parm          = "SCSI",
+       .removable              = 0,
+-      .can_stall              = 1,
++      .can_stall              = 0, /* for nhk15 */
+       .vendor                 = DRIVER_VENDOR_ID,
+       .product                = DRIVER_PRODUCT_ID,
+       .release                = 0xffff,       // Use controller chip type
+       .buflen                 = 16384,
+       };
+@@ -3858,11 +3857,11 @@ static int __init fsg_bind(struct usb_ga
+       if ((rc = check_parameters(fsg)) != 0)
+               goto out;
+       if (mod_data.removable) {       // Enable the store_xxx attributes
+-              dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
++              dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0777; /*NHK15*/
+               dev_attr_ro.store = store_ro;
+               dev_attr_file.store = store_file;
+       }
+       /* Find out how many LUNs there should be */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/Kconfig
+@@ -0,0 +1,176 @@
++#
++# INVENTRA USB Host Controller Drivers
++#
++# $Revision: 1.13 $
++#
++config USB_INVENTRA_HCD
++      depends on USB
++      tristate 'Inventra HCD Controller Support'
++      help
++        Say Y here if you have the Inventra USB board on your system.
++
++        If you do not know what this is, please say N.
++
++        To compile this driver as a module, choose M here:  the
++        module will be called musb-hcd (host controller) or
++        musb-gcd (gadget controller) or musb-icd (interface
++        controller when OTG is enabled).
++
++choice
++prompt "Controller Mode"
++depends on USB_INVENTRA_HCD
++default USB_INVENTRA_HCD_HOST
++
++config USB_INVENTRA_HCD_HOST
++      bool 'Host Mode'
++
++config USB_INVENTRA_HCD_GADGET_API
++      bool 'GADGET API'
++      help
++        Say Y here if you want support for GADGET API; the module will
++        be called musb-gcd.ko
++
++        You will need to select the Inventra Controller in the Gadget
++        subsection.
++
++        If you do not know what this is, please say N.
++
++config USB_INVENTRA_HCD_OTG
++      bool 'On The Go'
++      help
++        Say Y here if you want support for USB On The Go.
++
++        The module will be called musb-icd.ko
++
++        If you do not know what this is, please say N.
++
++#config USB_INVENTRA_HCD_GSTORAGE
++#     bool 'Storage Demo'
++#     help
++#       Say Y here if you want the hcd driver compiled as
++#       like a mass storage device.
++#
++#       If you do not know what this is, please say N.
++
++config USB_INVENTRA_HCD_OTG_GSTORAGE
++      bool 'OTG Storage Demo'
++      help
++        Say Y here if you want the hcd driver compiled as
++        a mass storage device with OTG support.
++
++        If you do not know what this is, please say N.
++
++
++endchoice
++
++config USB_INVENTRA_STATIC_CONFIG
++      depends on USB_INVENTRA_HCD
++      bool 'Use static config (-DMUSB_STATIC_CONFIG)'
++      default true
++      help
++        Use the static configuration file. File must be called
++        hdrc_cnf.h and mut be generated from the board configuration
++        file. Please check directory install/configs for examples.
++
++        If usure please say please say N and make sure your controller
++        is using the standard configuration HB+8E(8K)+8DMA
++
++          NOTE: Make sure your board is using the corresponding core.
++
++config USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
++      depends on USB_INVENTRA_STATIC_CONFIG
++      string 'Endpoint FIFO configuration file (Advanced)'
++      default ''
++      help
++        Specify the file with the endpoint fifo configuration (Advanced). The
++        file shoud define an struct MUSB_EpFifoDescriptor array called
++        MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] containig the end point FIFO
++        configuration specs. Check musbdefs.h for more informations;
++
++              struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS]={
++
++                      {}, /* EP0 use the default */
++                      { MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
++                      { MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 }
++
++              };
++
++        gives the endpoint 0 its default value, and defines ep1/ep2 as bulk tx/rx
++        512 bytes in size each with double buffering disabled. The FIFO memory
++        allocated with this confoguration is 64+512+512=1088 bytes
++
++config USB_INVENTRA_DMA
++      depends on USB_INVENTRA_HCD
++      bool 'Use DMA when possible (-DMUSB_DMA)'
++      default true
++      help
++        Enable DMA transfers when DMA is possible
++
++config USB_INVENTRA_MUSB_HAS_AHB_ID
++      depends on USB_INVENTRA_HCD
++      bool 'Enable AHB_ID (-DMUSB_AHB_ID)'
++      default false
++      help
++        Disable auto core identification.
++
++          NOTE: Make sure your board is using the corresponding core.
++
++config USB_INVENTRA_MUSB_HDR_CCNF_FILE
++      depends on USB_INVENTRA_HCD
++      string 'Custom config file (Advanced)'
++      default ''
++      help
++        Specify a custom config file (Advanced)
++
++config USB_INVENTRA_MUSB_BOARD_FILE
++      depends on USB_INVENTRA_HCD
++      string 'Custom board file (Advanced)'
++      default ''
++      help
++        Specify a custom board file (Advanced)
++
++config USB_INVENTRA_TPL
++      depends on USB_INVENTRA_HCD_OTG
++      tristate '    Use TPL (-DMUSB_TPL)'
++      default false
++      help
++        Enable Target Peripheral List
++
++config USB_INVENTRA_PROC_TESTMUSB
++      depends on USB_INVENTRA_HCD && PROC_FS && ( USB_INVENTRA_HOSTMODE || USB_INVENTRA_OTG )
++      bool 'Enable /proc/testmusbhdrc*'
++      default false
++      help
++        Add /proc/testmusbhdrc<num> to control the
++
++        NOTE: this is different from supporting /proc filesystem;
++
++        If you do not know what this is, please say N.
++
++config        USB_INVENTRA_HCD_CUSTOM_OPTIONS
++      depends on USB_INVENTRA_HCD
++      string 'Custom compile options (Advanced)'
++      default ''
++      help
++        Specify a custom compile options (Advanced)
++
++config USB_INVENTRA_HCD_POLLING
++      depends on USB_INVENTRA_HCD
++      bool 'Use polling driver (debug only)'
++      default false
++      help
++        Enable polling mode (events won't be triggered by IRQs); usefule
++        for debugging.
++
++        If you do not know what this is, please say N.
++
++config        USB_INVENTRA_HCD_LOGGING
++      depends on USB_INVENTRA_HCD
++      int  'Logging Level (0 - none / 3 - annoying)'
++      default 0
++      help
++        Set the logging level. 0 disable the debugging altogether (no
++        code will be added to the)
++
++          If you do not know what this is, please say N.
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/Makefile
+@@ -0,0 +1,97 @@
++MUSB_VERSION=2.2.2
++HCD_TYPE=hcd
++
++
++obj-$(CONFIG_USB_INVENTRA_HCD) += musb-hcd.o
++
++
++
++ifeq ($(CONFIG_PROC_FS),y)
++      musb-$(HCD_TYPE)-objs += musb_procfs.o
++endif
++
++
++ifneq ($(CONFIG_USB_INVENTRA_MUSB_BOARD_FILE),"")
++        EXTRA_CFLAGS += -DMUSB_BOARD_FILE
++endif
++
++ifneq ($(CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE),"")
++EXTRA_CFLAGS += -DMUSB_HDR_CCNF_FILE
++endif
++
++ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
++ifneq ($(CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE),"")
++EXTRA_CFLAGS += -DMUSB_EPFIFOCONFIG_FILE
++endif
++endif
++
++ifneq ($(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS),"")
++EXTRA_CFLAGS += $(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS)
++endif
 +
-+#include <linux/io.h>
 +
-+#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
-+#define CONFIG_ONENAND_SIM_MANUFACTURER         0xec
-+#endif
-+#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
-+#define CONFIG_ONENAND_SIM_DEVICE_ID            0x04
-+#endif
-+#ifndef CONFIG_ONENAND_SIM_VERSION_ID
-+#define CONFIG_ONENAND_SIM_VERSION_ID           0x1e
-+#endif
++      EXTRA_CFLAGS += -DMUSB_C_DYNFIFO_DEF
++      EXTRA_CFLAGS += -DMUSB_EPDISCRIPTORS_FILE
 +
-+static int manuf_id   = CONFIG_ONENAND_SIM_MANUFACTURER;
-+static int device_id  = CONFIG_ONENAND_SIM_DEVICE_ID;
-+static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
++ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
++      EXTRA_CFLAGS += -DMUSB_AHB_ID
++endif
 +
-+struct onenand_flash {
-+      void __iomem *base;
-+      void __iomem *data;
-+};
++ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
++      EXTRA_CFLAGS += -DMUSB_DMA
++      musb-$(HCD_TYPE)-objs += musbhsdma.o
++endif
 +
-+#define ONENAND_CORE(flash)           (flash->data)
-+#define ONENAND_CORE_SPARE(flash, this, offset)                               \
-+      ((flash->data) + (this->chipsize) + (offset >> 5))
++EXTRA_CFLAGS += -DMUSB_VERSION='"$(MUSB_VERSION)"' -DHCD_NAME=$(HCD_NAME)
 +
-+#define ONENAND_MAIN_AREA(this, offset)                                       \
-+      (this->base + ONENAND_DATARAM + offset)
++ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
++      EXTRA_CFLAGS += -DMUSB_STATIC_CONFIG
++endif
 +
-+#define ONENAND_SPARE_AREA(this, offset)                              \
-+      (this->base + ONENAND_SPARERAM + offset)
++ifeq ($(CONFIG_USB_INVENTRA_HCD_OTG),y)
++  GADGET_API=y
++  MUSB_HOSTMODE=y
++  EXTRA_CFLAGS += -DMUSB_OTG
++  musb-$(HCD_TYPE)-objs += otg.o
++endif
 +
-+#define ONENAND_GET_WP_STATUS(this)                                   \
-+      (readw(this->base + ONENAND_REG_WP_STATUS))
++ifeq ($(CONFIG_USB_INVENTRA_HCD_GADGET_API),y)
++  GADGET_API=y
++endif
 +
-+#define ONENAND_SET_WP_STATUS(v, this)                                        \
-+      (writew(v, this->base + ONENAND_REG_WP_STATUS))
++#ifneq ($(GADGET_API),)
 +
-+/* It has all 0xff chars */
-+#define MAX_ONENAND_PAGESIZE          (2048 + 64)
-+static unsigned char *ffchars;
++#  GADGET_DIRS=y
++#    EXTRA_CFLAGS += -DMUSB_GADGET
++#      musb-$(HCD_TYPE)-objs += musb_gadgetcommon.o g_ep0.o musb_gadget.o
++#endif
 +
-+static struct mtd_partition os_partitions[] = {
-+      {
-+              .name           = "OneNAND simulator partition",
-+              .offset         = 0,
-+              .size           = MTDPART_SIZ_FULL,
-+      },
-+};
 +
-+/*
-+ * OneNAND simulator mtd
-+ */
-+struct onenand_info {
-+      struct mtd_info         mtd;
-+      struct mtd_partition    *parts;
-+      struct onenand_chip     onenand;
-+      struct onenand_flash    flash;
-+};
++ifeq ($(CONFIG_USB_INVENTRA_HCD_HOST),y)
++      MUSB_HOSTMODE=y
++endif
 +
-+static struct onenand_info *info;
 +
-+#define DPRINTK(format, args...)                                      \
-+do {                                                                  \
-+      printk(KERN_DEBUG "%s[%d]: " format "\n", __func__,             \
-+                         __LINE__, ##args);                           \
-+} while (0)
++ifeq ($(MUSB_HOSTMODE),y)
++  EXTRA_CFLAGS += -DMUSB_HOST
++  musb-$(HCD_TYPE)-objs += musb_virthub.o musb_host.o musb-hcd.o musb_plat_uds.o musb_bus_direct.o  musb_epfifocfg.o musb_ioctl.o nomadik_udc.o otg_pwm.o otg_func.o
 +
-+/**
-+ * onenand_lock_handle - Handle Lock scheme
-+ * @this:             OneNAND device structure
-+ * @cmd:              The command to be sent
-+ *
-+ * Send lock command to OneNAND device.
-+ * The lock scheme depends on chip type.
-+ */
-+static void onenand_lock_handle(struct onenand_chip *this, int cmd)
-+{
-+      int block_lock_scheme;
-+      int status;
++endif
 +
-+      status = ONENAND_GET_WP_STATUS(this);
-+      block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
++ifndef DEBUG
++  DEBUG=0
++endif
 +
-+      switch (cmd) {
-+      case ONENAND_CMD_UNLOCK:
-+              if (block_lock_scheme)
-+                      ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
-+              else
-+                      ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
-+              break;
++MUSB_DEBUG=$(CONFIG_USB_INVENTRA_HCD_LOGGING)
++ifeq ("$(strip $(MUSB_DEBUG))","")
++      MUSB_DEBUG:=$(DEBUG)
++endif
 +
-+      case ONENAND_CMD_LOCK:
-+              if (block_lock_scheme)
-+                      ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
-+              else
-+                      ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
-+              break;
 +
-+      case ONENAND_CMD_LOCK_TIGHT:
-+              if (block_lock_scheme)
-+                      ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
-+              else
-+                      ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
-+              break;
++ifneq ($(MUSB_DEBUG),0)
++      EXTRA_CFLAGS += -g
++      musb-$(HCD_TYPE)-objs += musb_debug.o
++endif
 +
-+      default:
-+              break;
-+      }
-+}
++EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
 +
-+/**
-+ * onenand_bootram_handle - Handle BootRAM area
-+ * @this:             OneNAND device structure
-+ * @cmd:              The command to be sent
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/board.h
+@@ -0,0 +1,58 @@
++/*
++ * linux/drivers/usb/nomadik/board.h
 + *
-+ * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
 + */
-+static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
-+{
-+      switch (cmd) {
-+      case ONENAND_CMD_READID:
-+              writew(manuf_id, this->base);
-+              writew(device_id, this->base + 2);
-+              writew(version_id, this->base + 4);
-+              break;
 +
-+      default:
-+              /* REVIST: Handle other commands */
-+              break;
-+      }
-+}
 +
-+/**
-+ * onenand_update_interrupt - Set interrupt register
-+ * @this:         OneNAND device structure
-+ * @cmd:          The command to be sent
++/*
++ * Example board-specific definitions.
++ * $Revision: 1.6 $
 + *
-+ * Update interrupt register. The status depends on command.
++ * It is suggested to:
++ * 1. Copy this file to one named after your target:
++ *    cp board.h board-mytarget.h
++ * 2. Save this file for future reference:
++ *    mv board.h board-example.h
++ * 3. Link board.h to yours:
++ *    ln -s board-mytarget.h board.h
++ * 4. Edit yours, providing, for each controller:
++ *    - controller type (MUSB_CONTROLLER_HDRC or MUSB_CONTROLLER_MHDRC)
++ *    - physical base address in kernel space
++ *    - interrupt number (interpretation is platform-specific)
 + */
-+static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
-+{
-+      int interrupt = ONENAND_INT_MASTER;
-+
-+      switch (cmd) {
-+      case ONENAND_CMD_READ:
-+      case ONENAND_CMD_READOOB:
-+              interrupt |= ONENAND_INT_READ;
-+              break;
-+
-+      case ONENAND_CMD_PROG:
-+      case ONENAND_CMD_PROGOOB:
-+              interrupt |= ONENAND_INT_WRITE;
-+              break;
 +
-+      case ONENAND_CMD_ERASE:
-+              interrupt |= ONENAND_INT_ERASE;
-+              break;
++/** Array of information about hard-wired controllers
++ * This will be liked to the first module that includes this file.
++ */
 +
-+      case ONENAND_CMD_RESET:
-+              interrupt |= ONENAND_INT_RESET;
-+              break;
++#ifndef __MUSB_LINUX_BOARD_H__
++#define __MUSB_LINUX_BOARD_H__
++#include <asm/arch/soc_devices.h>
 +
-+      default:
-+              break;
-+      }
++#include <asm/arch/irqs.h>
++#define INT_USBOTG IRQ_USBOTG
 +
-+      writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
-+}
++MUSB_LinuxController MUSB_aLinuxController[] =
++{
++    { MUSB_CONTROLLER_HDRC, (void*)NOMADIK_USB_BASE, INT_USBOTG }
++   /*
++    { MUSB_CONTROLLER_HDRC, (void*)0xc0000000, 9 }
++    */
++};
 +
-+/**
-+ * onenand_check_overwrite - Check if over-write happened
-+ * @dest:             The destination pointer
-+ * @src:              The source pointer
-+ * @count:            The length to be check
++#endif        /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/debug.h
+@@ -0,0 +1,104 @@
++/*
++ * linux/drivers/usb/nomadik/debug.h
 + *
-+ * Returns:           0 on same, otherwise 1
++ * Copyright 2007, STMicroelectronics
 + *
-+ * Compare the source with destination
++ * 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
 + */
-+static int onenand_check_overwrite(void *dest, void *src, size_t count)
-+{
-+      unsigned int *s = (unsigned int *) src;
-+      unsigned int *d = (unsigned int *) dest;
-+      int i;
-+
-+      count >>= 2;
-+      for (i = 0; i < count; i++)
-+              if ((*s++ ^ *d++) != 0)
-+                      return 1;
 +
-+      return 0;
-+}
++#ifndef __MUSB_LINUX_DEBUG_H__
++#define __MUSB_LINUX_DEBUG_H__
 +
-+/**
-+ * onenand_data_handle - Handle OneNAND Core and DataRAM
-+ * @this:             OneNAND device structure
-+ * @cmd:              The command to be sent
-+ * @dataram:          Which dataram used
-+ * @offset:           The offset to OneNAND Core
++/*
++ * Linux HCD (Host Controller Driver) for HDRC and/or MHDRC.
++ * Debug support routines
 + *
-+ * Copy data from OneNAND Core to DataRAM (read)
-+ * Copy data from DataRAM to OneNAND Core (write)
-+ * Erase the OneNAND Core (erase)
 + */
-+static void onenand_data_handle(struct onenand_chip *this, int cmd,
-+                              int dataram, unsigned int offset)
-+{
-+      struct mtd_info *mtd = &info->mtd;
-+      struct onenand_flash *flash = this->priv;
-+      int main_offset, spare_offset;
-+      void __iomem *src;
-+      void __iomem *dest;
-+      unsigned int i;
 +
-+      if (dataram) {
-+              main_offset = mtd->writesize;
-+              spare_offset = mtd->oobsize;
-+      } else {
-+              main_offset = 0;
-+              spare_offset = 0;
-+      }
++#define MUSB_MONITOR_DATA
 +
-+      switch (cmd) {
-+      case ONENAND_CMD_READ:
-+              src = ONENAND_CORE(flash) + offset;
-+              dest = ONENAND_MAIN_AREA(this, main_offset);
-+              memcpy(dest, src, mtd->writesize);
-+              /* Fall through */
++#define yprintk(facility, format, args...) do { printk(facility "%s %d: " format , \
++      __FUNCTION__, __LINE__ , ## args); } while (0)
++#define WARN(fmt, args...) yprintk(KERN_WARNING,fmt, ## args)
++#define INFO(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
++#define ERR(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
 +
-+      case ONENAND_CMD_READOOB:
-+              src = ONENAND_CORE_SPARE(flash, this, offset);
-+              dest = ONENAND_SPARE_AREA(this, spare_offset);
-+              memcpy(dest, src, mtd->oobsize);
-+              break;
++#if MUSB_DEBUG > 0
 +
-+      case ONENAND_CMD_PROG:
-+              src = ONENAND_MAIN_AREA(this, main_offset);
-+              dest = ONENAND_CORE(flash) + offset;
-+              /* To handle partial write */
-+              for (i = 0; i < (1 << mtd->subpage_sft); i++) {
-+                      int off = i * this->subpagesize;
-+                      if (!memcmp(src + off, ffchars, this->subpagesize))
-+                              continue;
-+                      if (memcmp(dest + off, ffchars, this->subpagesize) &&
-+                          onenand_check_overwrite(dest + off, src + off, this->subpagesize))
-+                              printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
-+                      memcpy(dest + off, src + off, this->subpagesize);
-+              }
-+              /* Fall through */
++#define STATIC
++#define MGC_GetDebugLevel()   (MGC_DebugLevel)
++#define MGC_EnableDebug()     do { MGC_DebugDisable=0; } while(0)
++#define MGC_DisableDebug()    do { MGC_DebugDisable=1; } while(0)
 +
-+      case ONENAND_CMD_PROGOOB:
-+              src = ONENAND_SPARE_AREA(this, spare_offset);
-+              /* Check all data is 0xff chars */
-+              if (!memcmp(src, ffchars, mtd->oobsize))
-+                      break;
++#define _dbg_level(level)  ( !MGC_DebugDisable && ((level>=-1 && MGC_GetDebugLevel()>=level) || MGC_GetDebugLevel()==level) )
 +
-+              dest = ONENAND_CORE_SPARE(flash, this, offset);
-+              if (memcmp(dest, ffchars, mtd->oobsize) &&
-+                  onenand_check_overwrite(dest, src, mtd->oobsize))
-+                      printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
-+                             offset);
-+              memcpy(dest, src, mtd->oobsize);
-+              break;
++#define xprintk(level, facility, format, args...) do { if ( _dbg_level(level) ) { \
++    printk(facility "%s %d: " format , __FUNCTION__, __LINE__ , ## args); } } while (0)
 +
-+      case ONENAND_CMD_ERASE:
-+              memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
-+              memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
-+                     (mtd->erasesize >> 5));
-+              break;
++#define PARANOID( x )         do {}  while (0)
++#define DBG(level,fmt,args...) xprintk(level,KERN_INFO,fmt, ## args)
++#define DEBUG_CODE(level, code)       do { if ( _dbg_level(level) ) { code }  } while (0)
++#define TRACE(n) DEBUG_CODE(n, printk(KERN_INFO "%s:%s:%d: trace\n", \
++      __FILE__, __FUNCTION__, __LINE__); )
 +
-+      default:
-+              break;
-+      }
-+}
++#define ASSERT_SPINLOCK_LOCKED(_x)
++#define ASSERT_SPINLOCK_UNLOCKED(_x)
++/* #define ASSERT_SPINLOCK_LOCKED(_x) do { if (!spin_is_locked(_x)) \
++      ERR("@pre clause failed, _x must be locked\n"); } while (0)
++#define ASSERT_SPINLOCK_UNLOCKED(_x) do { if (spin_is_locked(_x)) \
++      ERR("@pre clause failed, _x must be unlocked\n"); } while (0) */
 +
-+/**
-+ * onenand_command_handle - Handle command
-+ * @this:             OneNAND device structure
-+ * @cmd:              The command to be sent
-+ *
-+ * Emulate OneNAND command.
-+ */
-+static void onenand_command_handle(struct onenand_chip *this, int cmd)
-+{
-+      unsigned long offset = 0;
-+      int block = -1, page = -1, bufferram = -1;
-+      int dataram = 0;
++/* debug no defined */
 +
-+      switch (cmd) {
-+      case ONENAND_CMD_UNLOCK:
-+      case ONENAND_CMD_LOCK:
-+      case ONENAND_CMD_LOCK_TIGHT:
-+      case ONENAND_CMD_UNLOCK_ALL:
-+              onenand_lock_handle(this, cmd);
-+              break;
++#else
 +
-+      case ONENAND_CMD_BUFFERRAM:
-+              /* Do nothing */
-+              return;
++#define STATIC static
++#define MGC_GetDebugLevel()   0
++#define MGC_EnableDebug()
++#define MGC_DisableDebug()
 +
-+      default:
-+              block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
-+              if (block & (1 << ONENAND_DDP_SHIFT)) {
-+                      block &= ~(1 << ONENAND_DDP_SHIFT);
-+                      /* The half of chip block */
-+                      block += this->chipsize >> (this->erase_shift + 1);
-+              }
-+              if (cmd == ONENAND_CMD_ERASE)
-+                      break;
++#define PARANOID( x )         do {}  while (0)
++#define DBG(fmt,args...)      do {}  while (0)
++#define DEBUG_CODE(x, y)      do {}  while (0)
++#define TRACE(n)              do {}  while (0)
 +
-+              page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
-+              page = (page >> ONENAND_FPA_SHIFT);
-+              bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
-+              bufferram >>= ONENAND_BSA_SHIFT;
-+              bufferram &= ONENAND_BSA_DATARAM1;
-+              dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
-+              break;
-+      }
++#define ASSERT_SPINLOCK_LOCKED(_x)
++#define ASSERT_SPINLOCK_UNLOCKED(_x)
 +
-+      if (block != -1)
-+              offset += block << this->erase_shift;
++#endif
 +
-+      if (page != -1)
-+              offset += page << this->page_shift;
++/*----------------------- DEBUG function/macros -----------------------------*/
 +
-+      onenand_data_handle(this, cmd, dataram, offset);
++#if MUSB_DEBUG > 0
++struct usb_ep;
++struct list_head;
++struct usb_request;
++struct usb_ctrlrequest;
 +
-+      onenand_update_interrupt(this, cmd);
-+}
++extern int MGC_DebugLevel;
++extern int MGC_DebugDisable;
 +
-+/**
-+ * onenand_writew - [OneNAND Interface] Emulate write operation
-+ * @value:            value to write
-+ * @addr:             address to write
++extern void dump_urb(void *urb);
++extern char *decode_csr0(uint16_t csr0);
++extern char *decode_txcsr(uint16_t txcsr);
++extern char *decode_devctl(uint16_t devclt);
++extern char *decode_ep0stage(uint8_t stage);
++extern char *dump_node(struct list_head *node);
++extern char *decode_usb_ctrlrequest(const struct usb_ctrlrequest *pControlRequest);
++extern char *decode_request(struct usb_ctrlrequest*) ;
++extern void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd);
++#endif
++
++#endif //  __MUSB_LINUX_DEBUG_H__
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/dma.h
+@@ -0,0 +1,308 @@
++/*
++ * linux/drivers/usb/nomadik/dma.h
 + *
-+ * Write OneNAND register with value
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
 + */
-+static void onenand_writew(unsigned short value, void __iomem * addr)
-+{
-+      struct onenand_chip *this = info->mtd.priv;
 +
-+      /* BootRAM handling */
-+      if (addr < this->base + ONENAND_DATARAM) {
-+              onenand_bootram_handle(this, value);
-+              return;
-+      }
-+      /* Command handling */
-+      if (addr == this->base + ONENAND_REG_COMMAND)
-+              onenand_command_handle(this, value);
++#ifndef __MUSB_DMA_H__
++#define __MUSB_DMA_H__
 +
-+      writew(value, addr);
-+}
++/**
++ * Introduction.
++ * The purpose of the DMA Controller Abstraction (DCA) is to allow the ICD
++ * to use any DMA controller,
++ * since this is an option in the Inventra USB cores.
++ * The assumptions are:
++ * <ul>
++ * <li>A DMA controller will be tied to an Inventra USB core in the
++ * way specified in the Inventra core product specification.
++ * <li>A DMA controller's base address in the memory map correlates
++ * somehow to the Inventra USB core it serves.
++ * </ul>
++ * The responsibilities of an implementation include:
++ * <ul>
++ * <li>Allocating/releasing buffers for use with DMA
++ * (this may be specific to a DMA controller, intervening busses,
++ * and a target's capabilities,
++ * so the ICD cannot make assumptions or provide services here)
++ * <li>Handling the details of moving multiple USB packets
++ * in cooperation with the Inventra USB core.
++ * <li>Knowing the correlation between channels and the
++ * Inventra core's local endpoint resources and data direction,
++ * and maintaining a list of allocated/available channels.
++ * <li>Updating channel status on interrupts,
++ * whether shared with the Inventra core or separate.
++ * <li>If the DMA interrupt is shared with the Inventra core,
++ * handling it when called, and reporting whether it was the
++ * source of interrupt.
++ * </ul>
++ */
++
++/*************************** CONSTANTS ****************************/
 +
 +/**
-+ * flash_init - Initialize OneNAND simulator
-+ * @flash:            OneNAND simulator data strucutres
-+ *
-+ * Initialize OneNAND simulator.
++ * DMA channel status.
 + */
-+static int __init flash_init(struct onenand_flash *flash)
++typedef enum
 +{
-+      int density, size;
-+      int buffer_size;
++    /** A channel's status is unknown */
++    MGC_DMA_STATUS_UNKNOWN,
++    /** A channel is available (not busy and no errors) */
++    MGC_DMA_STATUS_FREE,
++    /** A channel is busy (not finished attempting its transactions) */
++    MGC_DMA_STATUS_BUSY,
++    /** A channel aborted its transactions due to a local bus error */
++    MGC_DMA_STATUS_BUS_ABORT,
++    /** A channel aborted its transactions due to a core error */
++    MGC_DMA_STATUS_CORE_ABORT
++} MGC_DmaChannelStatus;
 +
-+      flash->base = kzalloc(131072, GFP_KERNEL);
-+      if (!flash->base) {
-+              printk(KERN_ERR "Unable to allocate base address.\n");
-+              return -ENOMEM;
-+      }
++/***************************** TYPES ******************************/
 +
-+      density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
-+      size = ((16 << 20) << density);
++/**
++ * MGC_DmaChannel.
++ * A DMA channel.
++ * @field pPrivateData channel-private data; not to be interpreted by the ICD
++ * @field wMaxLength the maximum number of bytes the channel can move
++ * in one transaction (typically representing many USB maximum-sized packets)
++ * @field dwActualLength how many bytes have been transferred
++ * @field bStatus current channel status (updated e.g. on interrupt)
++ * @field bDesiredMode TRUE if mode 1 is desired; FALSE if mode 0 is desired
++ */
++typedef struct
++{
++    void* pPrivateData;
++    uint32_t dwMaxLength;
++    uint32_t dwActualLength;
++    MGC_DmaChannelStatus bStatus;
++    uint8_t bDesiredMode;
++} MGC_DmaChannel;
 +
-+      ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
-+      if (!ONENAND_CORE(flash)) {
-+              printk(KERN_ERR "Unable to allocate nand core address.\n");
-+              kfree(flash->base);
-+              return -ENOMEM;
-+      }
++/**
++ * Start a DMA controller.
++ * @param pPrivateData private data pointer from MGC_DmaController
++ * @return TRUE on success
++ * @return FALSE on failure (e.g. no DMAC appears present)
++ */
++typedef uint8_t (*MGC_pfDmaStartController)(void* pPrivateData);
 +
-+      memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
++/**
++ * Stop a DMA controller.
++ * @param pPrivateData the controller's private data pointer
++ * @return TRUE on success
++ * @return FALSE on failure; the ICD may try again
++ */
++typedef uint8_t (*MGC_pfDmaStopController)(void* pPrivateData);
 +
-+      /* Setup registers */
-+      writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
-+      writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
-+      writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
++/**
++ * Allocate a DMA channel.
++ * Allocate a DMA channel suitable for the given conditions.
++ * @param pPrivateData the controller's private data pointer
++ * @param bLocalEnd the local endpoint index (1-15)
++ * @param bTransmit TRUE for transmit; FALSE for receive
++ * @param bProtocol the USB protocol, as per USB 2.0 chapter 9
++ * (0 => control, 1 => isochronous, 2 => bulk, 3 => interrupt)
++ * @param wMaxPacketSize maximum packet size
++ * @return a non-NULL pointer on success
++ * @return NULL on failure (no channel available)
++ */
++typedef MGC_DmaChannel* (*MGC_pfDmaAllocateChannel)(
++    void* pPrivateData, uint8_t bLocalEnd,
++    uint8_t bTransmit, uint8_t bProtocol, uint16_t wMaxPacketSize);
 +
-+      if (density < 2)
-+              buffer_size = 0x0400;   /* 1KiB page */
-+      else
-+              buffer_size = 0x0800;   /* 2KiB page */
-+      writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
++/**
++ * Release a DMA channel.
++ * Release a previously-allocated DMA channel.
++ * The ICD guarantess to no longer reference this channel.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ */
++typedef void (*MGC_pfDmaReleaseChannel)(MGC_DmaChannel* pChannel);
 +
-+      return 0;
-+}
++/**
++ * Allocate DMA buffer.
++ * Allocate a buffer suitable for DMA operations with the given channel.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ * @param dwLength length, in bytes, desired for the buffer
++ * @return a non-NULL pointer to a suitable region (in processor space)
++ * on success
++ * @return NULL on failure
++ */
++typedef uint8_t* (*MGC_pfDmaAllocateBuffer)(MGC_DmaChannel* pChannel,
++                                           uint32_t dwLength);
 +
 +/**
-+ * flash_exit - Clean up OneNAND simulator
-+ * @flash:            OneNAND simulator data structures
-+ *
-+ * Clean up OneNAND simulator.
++ * Release DMA buffer.
++ * Release a DMA buffer previously acquiring by a successful call
++ * to pController->pfDmaAllocateBuffer.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ * @param pBuffer the buffer pointer
++ * @return TRUE on success
++ * @return FALSE on failure (e.g. the controller owns the buffer at present)
 + */
-+static void flash_exit(struct onenand_flash *flash)
-+{
-+      vfree(ONENAND_CORE(flash));
-+      kfree(flash->base);
-+}
++typedef uint8_t (*MGC_pfDmaReleaseBuffer)(MGC_DmaChannel* pChannel,
++                                         uint8_t* pBuffer);
 +
-+static int __init onenand_sim_init(void)
++/**
++ * Program a DMA channel.
++ * Program a DMA channel to move data at the core's request.
++ * The local core endpoint and direction should already be known,
++ * since they are specified in the pfDmaAllocateChannel call.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->pfDmaAllocateChannel
++ * @param wPacketSize the packet size
++ * @param bMode TRUE if mode 1; FALSE if mode 0
++ * @param pBuffer base address of data (in processor space)
++ * @param dwLength the number of bytes to transfer;
++ * guaranteed by the ICD to be no larger than the channel's reported dwMaxLength
++ * @return TRUE on success
++ * @return FALSE on error
++ */
++typedef uint8_t (*MGC_pfDmaProgramChannel)(MGC_DmaChannel* pChannel,
++                                          uint16_t wPacketSize, uint8_t bMode,
++                                          const uint8_t* pBuffer,
++                                          uint32_t dwLength);
++
++/**
++ * Get DMA channel status.
++ * Get the current status of a DMA channel, if the hardware allows.
++ * @param pChannel pointer to a channel obtained by
++ * a successful call to pController->DmaAllocateChannel
++ * @return current status
++ * (MGC_DMA_STATUS_UNKNOWN if hardware does not have readable status)
++ */
++typedef MGC_DmaChannelStatus (*MGC_pfDmaGetChannelStatus)(
++    MGC_DmaChannel* pChannel);
++
++/**
++ * DMA ISR.
++ * If present, this function is called by the ICD on every interrupt.
++ * This is necessary because with the built-in DMA controller
++ * (and probably some other configurations),
++ * the DMA interrupt is shared with other core interrupts.
++ * Therefore, this function should return quickly
++ * when there is no DMA interrupt.
++ * When there is a DMA interrupt, this function should
++ * perform any implementations-specific operations,
++ * and update the status of all appropriate channels.
++ * If the DMA controller has its own dedicated interrupt,
++ * this function should do nothing.
++ * This function is called BEFORE the ICD handles other interrupts.
++ * @param pPrivateData the controller's private data pointer
++ * @return TRUE if an interrupt was serviced
++ * @return FALSE if no interrupt required servicing
++ */
++typedef uint8_t (*MGC_pfDmaControllerIsr)(void* pPrivateData);
++
++/**
++ * MGC_DmaController.
++ * A DMA Controller.
++ * This is in a struct to allow the ICD to support
++ * multiple cores of different types,
++ * since each may use a different type of DMA controller.
++ * @field pPrivateData controller-private data;
++ * not to be interpreted by the ICD
++ * @field pfDmaStartController ICD calls this to start a DMA controller
++ * @field pfDmaStopController ICD calls this to stop a DMA controller
++ * @field pfDmaAllocateChannel ICD calls this to allocate a DMA channel
++ * @field pfDmaReleaseChannel ICD calls this to release a DMA channel
++ * @field pfDmaAllocateBuffer ICD calls this to allocate a DMA buffer
++ * @field pfDmaReleaseBuffer ICD calls this to release a DMA buffer
++ * @field pfDmaGetChannelStatus ICD calls this to get a DMA channel's status
++ * @field pfDmaControllerIsr ICD calls this (if non-NULL) from its ISR
++ */
++typedef struct
 +{
-+      /* Allocate all 0xff chars pointer */
-+      ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
-+      if (!ffchars) {
-+              printk(KERN_ERR "Unable to allocate ff chars.\n");
-+              return -ENOMEM;
-+      }
-+      memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
++    void* pPrivateData;
++    MGC_pfDmaStartController pfDmaStartController;
++    MGC_pfDmaStopController pfDmaStopController;
++    MGC_pfDmaAllocateChannel pfDmaAllocateChannel;
++    MGC_pfDmaReleaseChannel pfDmaReleaseChannel;
++    MGC_pfDmaAllocateBuffer pfDmaAllocateBuffer;
++    MGC_pfDmaReleaseBuffer pfDmaReleaseBuffer;
++    MGC_pfDmaProgramChannel pfDmaProgramChannel;
++    MGC_pfDmaGetChannelStatus pfDmaGetChannelStatus;
++    MGC_pfDmaControllerIsr pfDmaControllerIsr;
++} MGC_DmaController;
 +
-+      /* Allocate OneNAND simulator mtd pointer */
-+      info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
-+      if (!info) {
-+              printk(KERN_ERR "Unable to allocate core structures.\n");
-+              kfree(ffchars);
-+              return -ENOMEM;
-+      }
++/**
++ * A DMA channel has new status.
++ * This may be used to notify the ICD of channel status changes asynchronously.
++ * This is useful if the DMA interrupt is different from the USB controller's
++ * interrupt, so on some systems there may be no control over the order of
++ * USB controller and DMA controller assertion.
++ * @param pPrivateData the controller's private data pointer
++ * @param bLocalEnd the local endpoint index (1-15)
++ * @param bTransmit TRUE for transmit; FALSE for receive
++ * @return TRUE if an IRP was completed as a result of this call;
++ * FALSE otherwise
++ */
++typedef uint8_t (*MGC_pfDmaChannelStatusChanged)(
++    void* pPrivateData, uint8_t bLocalEnd,
++    uint8_t bTransmit);
 +
-+      /* Override write_word function */
-+      info->onenand.write_word = onenand_writew;
++/**
++ * Instantiate a DMA controller.
++ * Instantiate a software object representing a DMA controller.
++ * @param pfDmaChannelStatusChanged channel status change notification function.
++ * Normally, the ICD requests status in its interrupt handler.
++ * For some DMA controllers, this may not be the correct time.
++ * @param pDmaPrivate parameter for pfDmaChannelStatusChanged
++ * @param pCoreBase the base address (in kernel space) of the core
++ * It is assumed the DMA controller's registers' base address will be related
++ * to this in some way.
++ * @return non-NULL pointer on success
++ * @return NULL on failure (out of memory or exhausted
++ * a fixed number of controllers)
++ */
++typedef MGC_DmaController* (*MGC_pfNewDmaController)(
++    MGC_pfDmaChannelStatusChanged pfDmaChannelStatusChanged,
++    void* pDmaPrivate,
++    uint8_t* pCoreBase);
 +
-+      if (flash_init(&info->flash)) {
-+              printk(KERN_ERR "Unable to allocate flash.\n");
-+              kfree(ffchars);
-+              kfree(info);
-+              return -ENOMEM;
-+      }
++/**
++ * Destroy DMA controller.
++ * Destroy a previously-instantiated DMA controller.
++ */
++typedef void (*MGC_pfDestroyDmaController)(
++      MGC_DmaController* pController);
 +
-+      info->parts = os_partitions;
++/**
++ * MGC_DmaControllerFactory.
++ * A DMA controller factory.
++ * To allow for multi-core implementations and different
++ * types of cores and DMA controllers to co-exist,
++ * it is necessary to create them from factories.
++ * @field wCoreRegistersExtent the total size of the core's
++ * register region with the DMA controller present,
++ * for use in mapping the core into system memory.
++ * For example, the MHDRC core takes 0x200 bytes of address space.
++ * If your DMA controller starts at 0x200 and takes 0x100 bytes,
++ * set this to 0x300.
++ * @field pfNewDmaController create a DMA controller
++ * @field pfDestroyDmaController destroy a DMA controller
++ */
++typedef struct
++{
++    uint16_t wCoreRegistersExtent;
++    MGC_pfNewDmaController pfNewDmaController;
++    MGC_pfDestroyDmaController pfDestroyDmaController;
++} MGC_DmaControllerFactory;
 +
-+      info->onenand.base = info->flash.base;
-+      info->onenand.priv = &info->flash;
++#endif        /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/g_ep0.c
+@@ -0,0 +1,858 @@
++/*
++ * linux/drivers/usb/nomadik/g_ep0.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ */
 +
-+      info->mtd.name = "OneNAND simulator";
-+      info->mtd.priv = &info->onenand;
-+      info->mtd.owner = THIS_MODULE;
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++#include <linux/spinlock.h>
 +
-+      if (onenand_scan(&info->mtd, 1)) {
-+              flash_exit(&info->flash);
-+              kfree(ffchars);
-+              kfree(info);
-+              return -ENXIO;
-+      }
++#if defined(MUSB_V24) && !defined(MUSB_LINUX_MV21)
++/* dealing with Linux headers */
++struct usb_tt {
++      struct usb_device       *hub;   /* upstream highspeed hub */
++      int                     multi;  /* true means one TT per port */
++};
++#include "hcd.h"
++#endif
 +
-+      add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
++#include <linux/init.h>
++#include <linux/usb_ch9.h>
++#include "musbdefs.h"
++#include "musb_gadgetdefs.h"
 +
-+      return 0;
++
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Identifies a transmit request.
++ * @param pControlRequest the control request
++ * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE,
++ *            USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME
++ */
++uint8_t is_tx_request(const struct usb_ctrlrequest *pControlRequest)
++{
++    return ( pControlRequest->bRequestType & USB_DIR_IN );
 +}
 +
-+static void __exit onenand_sim_exit(void)
++/**
++ * Identifies a zero data request.
++ * @param pControlRequest the control request
++ * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
++ *    USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
++ *
++ */
++uint8_t is_zerodata_request(const struct usb_ctrlrequest *pControlRequest)
 +{
-+      struct onenand_chip *this = info->mtd.priv;
-+      struct onenand_flash *flash = this->priv;
++    return ( 0==pControlRequest->wLength ) && !is_tx_request(pControlRequest);
++}
 +
-+      onenand_release(&info->mtd);
-+      flash_exit(flash);
-+      kfree(ffchars);
-+      kfree(info);
++/**
++ * Identifies a receive request.
++ * @param pControlRequest the control request
++ * @return true for USB_REQ_SET_DESCRIPTOR
++ */
++uint8_t is_rx_request(const struct usb_ctrlrequest *pControlRequest)
++{
++    return pControlRequest->bRequest==USB_REQ_SET_DESCRIPTOR;
 +}
 +
-+module_init(onenand_sim_init);
-+module_exit(onenand_sim_exit);
++/* ---------------------------------------------------------------------- */
 +
-+MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
-+MODULE_DESCRIPTION("The OneNAND flash simulator");
-+MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/drivers/net/kgdboe.c ../new/linux-2.6.20/drivers/net/kgdboe.c
---- linux-2.6.20/drivers/net/kgdboe.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/kgdboe.c   2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,294 @@
-+/*
-+ * drivers/net/kgdboe.c
-+ *
-+ * A network interface for GDB.
-+ * Based upon 'gdbserial' by David Grothe <dave@gcom.com>
-+ * and Scott Foehner <sfoehner@engr.sgi.com>
-+ *
-+ * Maintainers: Amit S. Kale <amitkale@linsyssoft.com> and
-+ *            Tom Rini <trini@kernel.crashing.org>
++/**
++ * Forward a request to the driver.
 + *
-+ * 2004 (c) Amit S. Kale <amitkale@linsyssoft.com>
-+ * 2004-2005 (c) MontaVista Software, Inc.
-+ * 2005 (c) Wind River Systems, Inc.
++ * FROM: usb_gadget.h
++ * Accordingly, the driver's setup() callback must always implement all
++ * get_descriptor requests, returning at least a device descriptor and
++ * a configuration descriptor.  Drivers must make sure the endpoint
++ * descriptors match any hardware constraints. Some hardware also constrains
++ * other descriptors. (The pxa250 allows only configurations 1, 2, or 3).
 + *
-+ * Contributors at various stages not listed above:
-+ * San Mehat <nettwerk@biodome.org>, Robert Walsh <rjwalsh@durables.org>,
-+ * wangdi <wangdi@clusterfs.com>, Matt Mackall <mpm@selenic.com>,
-+ * Pavel Machek <pavel@suse.cz>, Jason Wessel <jason.wessel@windriver.com>
++ * The driver's setup() callback must also implement set_configuration,
++ * and should also implement set_interface, get_configuration, and
++ * get_interface.  Setting a configuration (or interface) is where
++ * endpoints should be activated or (config 0) shut down.
 + *
-+ * This file is licensed under the terms of the GNU General Public License
-+ * version 2. This program is licensed "as is" without any warranty of any
-+ * kind, whether express or implied.
++ * @param pControlRequest the usb control request to forward to the driver
 + */
++static int forward_to_driver(const struct usb_ctrlrequest *pControlRequest)
++{
++    int handled=-EOPNOTSUPP;
++    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
 +
-+#include <linux/kernel.h>
-+#include <linux/interrupt.h>
-+#include <linux/string.h>
-+#include <linux/kgdb.h>
-+#include <linux/netpoll.h>
-+#include <linux/init.h>
 +
-+#include <asm/atomic.h>
++    DBG(2, "<== pThis->pGadgetDriver=%p, pControlRequest=%p\n",
++              pThis->pGadgetDriver, pControlRequest);
 +
-+#define IN_BUF_SIZE 512               /* power of 2, please */
-+#define NOT_CONFIGURED_STRING "not_configured"
-+#define OUT_BUF_SIZE 30               /* We don't want to send too big of a packet. */
-+#define MAX_KGDBOE_CONFIG_STR 256
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
 +
-+static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE];
-+static int in_head, in_tail, out_count;
-+static atomic_t in_count;
-+/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */
-+static int configured;
-+static struct kgdb_io local_kgdb_io_ops;
-+static int use_dynamic_mac;
++    if ( pThis->pGadgetDriver ){
++              handled=pThis->pGadgetDriver->setup(pThis->pGadget,
++                      pControlRequest);
++    }
++    else{
++              printk("Error case\n");
++    }
 +
-+MODULE_DESCRIPTION("KGDB driver for network interfaces");
-+MODULE_LICENSE("GPL");
-+static char config[MAX_KGDBOE_CONFIG_STR] = NOT_CONFIGURED_STRING;
-+static struct kparam_string kps = {
-+      .string = config,
-+      .maxlen = MAX_KGDBOE_CONFIG_STR,
-+};
++    DBG(2, "==> handled=%d\n", handled);
++    return handled;
++}
 +
-+static void rx_hook(struct netpoll *np, int port, char *msg, int len,
-+                  struct sk_buff *skb)
-+{
-+      int i;
++/* ---------------------------------------------------------------------- */
 +
-+      np->remote_port = port;
++/**
++ * Service a receive request. Currently forward to the driver.
++ * @param pControlRequest the usb control request to service.
++ * @see is_rx_request
++ */
++static int service_rx_request(struct usb_ctrlrequest *pControlRequest)
++{
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
++    return forward_to_driver(pControlRequest);
++}
 +
-+      /* Copy the MAC address if we need to. */
-+      if (use_dynamic_mac) {
-+              memcpy(np->remote_mac, eth_hdr(skb)->h_source,
-+                              sizeof(np->remote_mac));
-+              use_dynamic_mac = 0;
-+      }
++/**
++ * Service a transmit request.
++ * @param pControlRequest the request to service
++ * @see is_tx_request
++ */
++void service_tx_status_request(const struct usb_ctrlrequest *pControlRequest)
++{
++    uint8_t handled=1;
++    uint8_t bResult[2], bEnd=0;
++    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK;
 +
-+      /*
-+       * This could be GDB trying to attach.  But it could also be GDB
-+       * finishing up a session, with kgdb_connected=0 but GDB sending
-+       * an ACK for the final packet.  To make sure we don't try and
-+       * make a breakpoint when GDB is leaving, make sure that if
-+       * !kgdb_connected the only len == 1 packet we allow is ^C.
-+       */
-+      if (!kgdb_connected && (len != 1 || msg[0] == 3) &&
-+          !atomic_read(&kgdb_setting_breakpoint)) {
-+              tasklet_schedule(&kgdb_tasklet_breakpoint);
-+      }
++      /* ack the request */
++      DBG(3, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
++      spin_lock(&pThis->Lock);
++      MGC_SelectEnd(pBase, 0);
++      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY);
++      spin_unlock(&pThis->Lock);
 +
-+      for (i = 0; i < len; i++) {
-+              if (msg[i] == 3)
-+                      tasklet_schedule(&kgdb_tasklet_breakpoint);
++    switch (bRecip) {
 +
-+              if (atomic_read(&in_count) >= IN_BUF_SIZE) {
-+                      /* buffer overflow, clear it */
-+                      in_head = in_tail = 0;
-+                      atomic_set(&in_count, 0);
-+                      break;
-+              }
-+              in_buf[in_head++] = msg[i];
-+              in_head &= (IN_BUF_SIZE - 1);
-+              atomic_inc(&in_count);
-+      }
-+}
++      case USB_RECIP_DEVICE:
++              DBG(3, "USB_RECIP_DEVICE()\n");
++              bResult[0] = pThis->bIsSelfPowered ? 1 : 0;
++              bResult[0] |= 2;
++              bResult[1] = 0;
++              MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult);
++              break;
 +
-+static struct netpoll np = {
-+      .dev_name = "eth0",
-+      .name = "kgdboe",
-+      .rx_hook = rx_hook,
-+      .local_port = 6443,
-+      .remote_port = 6442,
-+      .remote_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
-+};
++      case USB_RECIP_ENDPOINT:
++              {
++              uint16_t wTest;
 +
-+static void eth_pre_exception_handler(void)
-+{
-+      /* Increment the module count when the debugger is active */
-+      if (!kgdb_connected)
-+              try_module_get(THIS_MODULE);
-+      netpoll_set_trap(1);
-+}
++              DBG(3, "USB_RECIP_ENDPOINT()\n");
 +
-+static void eth_post_exception_handler(void)
-+{
-+      /* decrement the module count when the debugger detaches */
-+      if (!kgdb_connected)
-+              module_put(THIS_MODULE);
-+      netpoll_set_trap(0);
-+}
++              bEnd = (uint8_t)pControlRequest->wIndex;
 +
-+static int eth_get_char(void)
-+{
-+      int chr;
++              spin_lock(&pThis->Lock);
++              MGC_SelectEnd(pBase, bEnd);
++              wTest = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++              MGC_SelectEnd(pBase, 0);
++              bResult[0] = (wTest & MGC_M_TXCSR_P_SENDSTALL) ? 1 : 0;
++              bResult[1] = 0;
++              MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult);
++              spin_unlock(&pThis->Lock);
++              }
++              break;
 +
-+      while (atomic_read(&in_count) == 0)
-+              netpoll_poll(&np);
++      default:
++              handled=0;
++              break;
++    }
 +
-+      chr = in_buf[in_tail++];
-+      in_tail &= (IN_BUF_SIZE - 1);
-+      atomic_dec(&in_count);
-+      return chr;
-+}
++    /* send it out! (this will trigger the ep0 completition IRQ)
++       * serviced in interrupt_complete()  */
++    if ( handled ) {
++              pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT;
 +
-+static void eth_flush_buf(void)
-+{
-+      if (out_count && np.dev) {
-+              netpoll_send_udp(&np, out_buf, out_count);
-+              memset(out_buf, 0, sizeof(out_buf));
-+              out_count = 0;
-+      }
++              spin_lock(&pThis->Lock);
++              MGC_SelectEnd(pBase, bEnd);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_P_DATAEND);
++              spin_unlock(&pThis->Lock);
++    }
 +}
 +
-+static void eth_put_char(u8 chr)
++/**
++ * Service a transmit a request. End0 buffer contains the current
++ * request (a standard control request). Assumes the fifo to be at least
++ * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION,
++ * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS,
++ * USB_REQ_SYNC_FRAME.
++ *
++ * @param pControlRequest the request to service
++ * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not
++ * supprorted), > 0 when the request is processed
++ * @see is_tx_request
++ */
++static int service_tx_request(const struct usb_ctrlrequest *pControlRequest)
 +{
-+      out_buf[out_count++] = chr;
-+      if (out_count == OUT_BUF_SIZE)
-+              eth_flush_buf();
-+}
++    int handled=0; /* not handled */
 +
-+static int option_setup(char *opt)
-+{
-+      char opt_scratch[MAX_KGDBOE_CONFIG_STR];
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
 +
-+      /* If we're being given a new configuration, copy it in. */
-+      if (opt != config)
-+              strcpy(config, opt);
-+      /* But work on a copy as netpoll_parse_options will eat it. */
-+      strcpy(opt_scratch, opt);
-+      configured = !netpoll_parse_options(&np, opt_scratch);
++    if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) {
++              return forward_to_driver(pControlRequest);
++    }
 +
-+      use_dynamic_mac = 1;
++    switch (pControlRequest->bRequest) {
++      case USB_REQ_GET_CONFIGURATION:
++              DBG(3, "USB_REQ_GET_CONFIGURATION()\n");
++              break;
 +
-+      return 0;
-+}
-+__setup("kgdboe=", option_setup);
++      case USB_REQ_GET_INTERFACE:
++              DBG(3, "USB_REQ_GET_INTERFACE()\n");
++              break;
 +
-+/* With our config string set by some means, configure kgdboe. */
-+static int configure_kgdboe(void)
-+{
-+      /* Try out the string. */
-+      option_setup(config);
++      case USB_REQ_GET_DESCRIPTOR:
++              DBG(3, "USB_REQ_GET_DESCRIPTOR()\n");
++              break;
 +
-+      if (!configured) {
-+              printk(KERN_ERR "kgdboe: configuration incorrect - kgdboe not "
-+                     "loaded.\n");
-+              printk(KERN_ERR "  Usage: kgdboe=[src-port]@[src-ip]/[dev],"
-+                              "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
-+              return -EINVAL;
-+      }
++      case USB_REQ_GET_STATUS: {
++              DBG(3, "USB_REQ_GET_STATUS()\n");
++              service_tx_status_request(pControlRequest);
++              }
++              break;
 +
-+      /* Bring it up. */
-+      if (netpoll_setup(&np)) {
-+              printk(KERN_ERR "kgdboe: netpoll_setup failed kgdboe failed\n");
-+              return -EINVAL;
-+      }
++      /* case USB_REQ_SYNC_FRAME:
++              break; */
 +
-+      if (kgdb_register_io_module(&local_kgdb_io_ops)) {
-+              netpoll_cleanup(&np);
-+              return -EINVAL;
-+      }
++      default:
++              break;
++    }
 +
-+      configured = 2;
++    if ( !handled ) {
++              handled=forward_to_driver(pControlRequest);
++    }
 +
-+      return 0;
++      /* now tx! */
++    return handled;
 +}
 +
-+static int init_kgdboe(void)
++/**
++ * Service a zero data request.
++ * Called for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
++ * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE.
++ *
++ * @param pThis the controller instance
++ * @param pControlRequest the control request to service.
++ * @warning USB_REQ_SET_ADDRESS should be executed QUICKLY
++ * @see is_zerodata_request
++ */
++static int service_zero_data_request(MGC_LinuxCd* pThis,
++                                                                       struct usb_ctrlrequest *pControlRequest)
 +{
-+      int ret;
++    int handled=1; /* handled, DO NOT not pass down */
++    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK;
 +
-+      /* Already done? */
-+      if (configured == 2)
-+              return 0;
++    DBG(-1002, "<==\n");
 +
-+      /* OK, go ahead and do it. */
-+      ret = configure_kgdboe();
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
++#endif
 +
-+      if (configured == 2)
-+              printk(KERN_INFO "kgdboe: debugging over ethernet enabled\n");
++    /* non standard requests are piped to the gadget */
++    if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) {
++              return forward_to_driver(pControlRequest);
++    }
 +
-+      return ret;
-+}
++    /* zero data phase */
++    switch (pControlRequest->bRequest) {
 +
-+static void cleanup_kgdboe(void)
-+{
-+      netpoll_cleanup(&np);
-+      configured = 0;
-+      kgdb_unregister_io_module(&local_kgdb_io_ops);
-+}
++      case USB_REQ_SET_INTERFACE:
++              DBG(3, "USB_REQ_SET_INTERFACE()\n");
++              handled=0; /* pass it to the gadget */
++              break;
 +
-+static int param_set_kgdboe_var(const char *kmessage, struct kernel_param *kp)
-+{
-+      char kmessage_save[MAX_KGDBOE_CONFIG_STR];
-+      int msg_len = strlen(kmessage);
++      case USB_REQ_SET_CONFIGURATION:
++              /* remember state & handle on the end status stage interrupt */
++              DBG(3, "USB_REQ_SET_CONFIGURATION()\n");
++              pThis->bDeviceState = (pControlRequest->wValue & 0xff)
++                      ? MGC_STATE_CONFIGURED : MGC_STATE_ADDRESS;
++              handled=0; /* pass it to the gadget */
++              break;
 +
-+      if (msg_len + 1 > MAX_KGDBOE_CONFIG_STR) {
-+              printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
-+                     kp->name, MAX_KGDBOE_CONFIG_STR - 1);
-+              return -ENOSPC;
-+      }
++      case USB_REQ_SET_ADDRESS:
++              /* remember state & handle on the end status stage interrupt */
++              DBG(3, "USB_REQ_SET_ADDRESS(0x%x)\n",(uint8_t)
++                      (pControlRequest->wValue & 0x7f));
 +
-+      if (kgdb_connected) {
-+              printk(KERN_ERR "kgdboe: Cannot reconfigure while KGDB is "
-+                              "connected.\n");
-+              return 0;
-+      }
++              pThis->bSetAddress = TRUE;
++              pThis->bAddress = (uint8_t)(pControlRequest->wValue & 0x7f);
++              pThis->bDeviceState = MGC_STATE_ADDRESS;
++              break;
 +
-+      /* Start the reconfiguration process by saving the old string */
-+      strncpy(kmessage_save, config, sizeof(kmessage_save));
++      case USB_REQ_CLEAR_FEATURE:
++              DBG(3, "USB_REQ_CLEAR_FEATURE()\n");
 +
++              switch (bRecip) {
 +
-+      /* Copy in the new param and strip out invalid characters so we
-+       * can optionally specify the MAC.
-+       */
-+      strncpy(config, kmessage, sizeof(config));
-+      msg_len--;
-+      while (msg_len > 0 &&
-+                      (config[msg_len] < ',' || config[msg_len] > 'f')) {
-+              config[msg_len] = '\0';
-+              msg_len--;
-+      }
++              case USB_RECIP_DEVICE:
++                      DBG(3, "USB_RECIP_DEVICE()\n");
++                      break;
 +
-+      /* Check to see if we are unconfiguring the io module and that it
-+       * was in a fully configured state, as this is the only time that
-+       * netpoll_cleanup should get called
-+       */
-+      if (configured == 2 && strcmp(config, NOT_CONFIGURED_STRING) == 0) {
-+              printk(KERN_INFO "kgdboe: reverting to unconfigured state\n");
-+              cleanup_kgdboe();
-+              return 0;
-+      } else
-+              /* Go and configure with the new params. */
-+              configure_kgdboe();
++              case USB_RECIP_INTERFACE:
++                      DBG(3, "USB_RECIP_INTERFACE()\n");
++                      break;
 +
-+      if (configured == 2)
-+              return 0;
++              case USB_RECIP_ENDPOINT: {
++                      const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ;
++                      MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ];
 +
-+      /* If the new string was invalid, revert to the previous state, which
-+       * is at a minimum not_configured. */
-+      strncpy(config, kmessage_save, sizeof(config));
-+      if (strcmp(kmessage_save, NOT_CONFIGURED_STRING) != 0) {
-+              printk(KERN_INFO "kgdboe: reverting to prior configuration\n");
-+              /* revert back to the original config */
-+              strncpy(config, kmessage_save, sizeof(config));
-+              configure_kgdboe();
-+      }
-+      return 0;
-+}
++                      DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );
++                      MGC_GadgetSetHalt( &pEnd->end_point, 0);
++                      /* select ep0 again */
++                      MGC_SelectEnd(pBase, 0);
++                                                               }
++                      break;
 +
-+static struct kgdb_io local_kgdb_io_ops = {
-+      .read_char = eth_get_char,
-+      .write_char = eth_put_char,
-+      .init = init_kgdboe,
-+      .flush = eth_flush_buf,
-+      .pre_exception = eth_pre_exception_handler,
-+      .post_exception = eth_post_exception_handler
-+};
++              default:
++                      break;
++              }
++              break; /* END: CLEAR_FEATURE */
 +
-+module_init(init_kgdboe);
-+module_exit(cleanup_kgdboe);
-+module_param_call(kgdboe, param_set_kgdboe_var, param_get_string, &kps, 0644);
-+MODULE_PARM_DESC(kgdboe, " kgdboe=[src-port]@[src-ip]/[dev],"
-+               "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
-diff -Nauprw linux-2.6.20/drivers/net/Makefile ../new/linux-2.6.20/drivers/net/Makefile
---- linux-2.6.20/drivers/net/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/Makefile   2007-11-21 11:51:41.000000000 +0530
-@@ -213,6 +213,7 @@ obj-$(CONFIG_ETRAX_ETHERNET) += cris/
- obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
- obj-$(CONFIG_NETCONSOLE) += netconsole.o
-+obj-$(CONFIG_KGDBOE) += kgdboe.o
- obj-$(CONFIG_FS_ENET) += fs_enet/
-diff -Nauprw linux-2.6.20/drivers/net/smc91x.c ../new/linux-2.6.20/drivers/net/smc91x.c
---- linux-2.6.20/drivers/net/smc91x.c  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/smc91x.c   2007-11-21 11:51:41.000000000 +0530
-@@ -1,3 +1,4 @@
++              case USB_REQ_SET_FEATURE:
++                      DBG(3, "USB_REQ_SET_FEATURE()\n");
 +
- /*
-  * smc91x.c
-  * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
-@@ -65,7 +66,6 @@ static const char version[] =
- #define SMC_DEBUG             0
- #endif
--
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-@@ -90,6 +90,8 @@ static const char version[] =
- #include "smc91x.h"
-+#include <linux/delay.h>
++                      switch (bRecip) {
 +
- #ifdef CONFIG_ISA
- /*
-  * the LAN91C111 can be at any of the following port addresses.  To change,
-@@ -268,7 +270,6 @@ static void PRINT_PKT(u_char *buf, int l
- #define PRINT_PKT(x...)  do { } while(0)
- #endif
--
- /* this enables an interrupt in the interrupt mask register */
- #define SMC_ENABLE_INT(x) do {                                                \
-       unsigned char mask;                                             \
-@@ -308,7 +309,6 @@ static void PRINT_PKT(u_char *buf, int l
-       }                                                               \
- } while (0)
--
- /*
-  * this does a soft reset on the device
-  */
-@@ -494,8 +494,7 @@ static inline void  smc_rcv(struct net_d
-       SMC_GET_PKT_HDR(status, packet_len);
-       packet_len &= 0x07ff;  /* mask off top bits */
-       DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
--              dev->name, packet_number, status,
--              packet_len, packet_len);
-+          dev->name, packet_number, status, packet_len, packet_len);
-       back:
-       if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
-@@ -835,7 +834,6 @@ static void smc_tx(struct net_device *de
-       SMC_SELECT_BANK(2);
- }
--
- /*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
- static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
-@@ -927,7 +925,9 @@ static void smc_phy_write(struct net_dev
-       smc_mii_out(dev, 0xffffffff, 32);
-       /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */
--      smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
-+      smc_mii_out(dev,
-+                  5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata,
-+                  32);
-       /* Return to idle state */
-       SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
-@@ -961,8 +961,7 @@ static void smc_phy_detect(struct net_de
-               id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1);
-               id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2);
--              DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n",
--                      dev->name, id1, id2);
-+              DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n", dev->name, id1, id2);
-               /* Make sure it is a valid identifier */
-               if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
-@@ -1184,7 +1183,9 @@ static void smc_phy_configure(struct wor
-       /* Disable capabilities not selected by our user */
-       if (lp->ctl_rspeed != 100)
--              my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
-+              my_ad_caps &=
-+                  ~(ADVERTISE_100BASE4 | ADVERTISE_100FULL |
-+                    ADVERTISE_100HALF);
-       if (!lp->ctl_rfduplx)
-               my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
-@@ -1314,11 +1315,12 @@ static irqreturn_t smc_interrupt(int irq
-               status = SMC_GET_INT();
-               DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
--                      dev->name, status, mask,
--                      ({ int meminfo; SMC_SELECT_BANK(0);
-+                  dev->name, status, mask, ( {
-+                                            int meminfo;
-+                                            SMC_SELECT_BANK(0);
-                          meminfo = SMC_GET_MIR();
--                         SMC_SELECT_BANK(2); meminfo; }),
--                      SMC_GET_FIFO());
-+                                            SMC_SELECT_BANK(2);
-+                                            meminfo;}), SMC_GET_FIFO());
-               status &= mask;
-               if (!status)
-@@ -1354,10 +1356,18 @@ static irqreturn_t smc_interrupt(int irq
-                       /* multiple collisions */
-                       lp->stats.collisions += card_stats & 0xF;
-               } else if (status & IM_RX_OVRN_INT) {
--                      DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
--                             ({ int eph_st; SMC_SELECT_BANK(0);
--                                eph_st = SMC_GET_EPH_STATUS();
--                                SMC_SELECT_BANK(2); eph_st; }) );
-+                      DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, ( {
-+                                                                             int
-+                                                                             eph_st;
-+                                                                             SMC_SELECT_BANK
-+                                                                             (0);
-+                                                                             eph_st
-+                                                                             =
-+                                                                             SMC_GET_EPH_STATUS
-+                                                                             ();
-+                                                                             SMC_SELECT_BANK
-+                                                                             (2);
-+                                                                             eph_st;}));
-                       SMC_ACK_INT(IM_RX_OVRN_INT);
-                       lp->stats.rx_errors++;
-                       lp->stats.rx_fifo_errors++;
-@@ -1500,7 +1510,8 @@ static void smc_set_multicast_list(struc
-               struct dev_mc_list *cur_addr;
-               /* table for flipping the order of 3 bits */
--              static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7};
-+              static const unsigned char invert3[] =
-+                  { 0, 4, 2, 6, 1, 5, 3, 7 };
-               /* start with a table of all zeros: reject all */
-               memset(multicast_table, 0, sizeof(multicast_table));
-@@ -1553,14 +1564,12 @@ static void smc_set_multicast_list(struc
-       spin_unlock_irq(&lp->lock);
- }
--
- /*
-  * Open and Initialize the board
-  *
-  * Set up everything, reset the card, etc..
-  */
--static int
--smc_open(struct net_device *dev)
-+static int smc_open(struct net_device *dev)
- {
-       struct smc_local *lp = netdev_priv(dev);
-@@ -1659,8 +1668,7 @@ smc_ethtool_getsettings(struct net_devic
-               spin_unlock_irq(&lp->lock);
-       } else {
-               cmd->supported = SUPPORTED_10baseT_Half |
--                               SUPPORTED_10baseT_Full |
--                               SUPPORTED_TP | SUPPORTED_AUI;
-+                  SUPPORTED_10baseT_Full | SUPPORTED_TP | SUPPORTED_AUI;
-               if (lp->ctl_rspeed == 10)
-                       cmd->speed = SPEED_10;
-@@ -1670,7 +1678,8 @@ smc_ethtool_getsettings(struct net_devic
-               cmd->autoneg = AUTONEG_DISABLE;
-               cmd->transceiver = XCVR_INTERNAL;
-               cmd->port = 0;
--              cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
-+              cmd->duplex =
-+                  lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
-               ret = 0;
-       }
-@@ -1691,8 +1700,8 @@ smc_ethtool_setsettings(struct net_devic
-       } else {
-               if (cmd->autoneg != AUTONEG_DISABLE ||
-                   cmd->speed != SPEED_10 ||
--                  (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
--                  (cmd->port != PORT_TP && cmd->port != PORT_AUI))
-+                  (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
-+                  || (cmd->port != PORT_TP && cmd->port != PORT_AUI))
-                       return -EINVAL;
- //            lp->port = cmd->port;
-@@ -1712,7 +1721,8 @@ smc_ethtool_getdrvinfo(struct net_device
- {
-       strncpy(info->driver, CARDNAME, sizeof(info->driver));
-       strncpy(info->version, version, sizeof(info->version));
--      strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
-+      strncpy(info->bus_info, dev->class_dev.dev->bus_id,
-+              sizeof(info->bus_info));
- }
- static int smc_ethtool_nwayreset(struct net_device *dev)
-@@ -1839,7 +1849,7 @@ static int __init smc_findirq(void __iom
-  * o  actually GRAB the irq.
-  * o  GRAB the region
-  */
--static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
-+int __init smc_probe(struct net_device *dev, void __iomem * ioaddr)
- {
-       struct smc_local *lp = netdev_priv(dev);
-       static int version_printed = 0;
-@@ -1880,6 +1890,8 @@ static int __init smc_probe(struct net_d
-        * register
-        */
-       SMC_SELECT_BANK(1);
-+      mdelay(100);
-+      val = SMC_CURRENT_BANK();
-       val = SMC_GET_BASE();
-       val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
-       if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
-@@ -1918,6 +1930,7 @@ static int __init smc_probe(struct net_d
-       /* Get the MAC address */
-       SMC_SELECT_BANK(1);
++                      case USB_RECIP_DEVICE:
++                              DBG(3, "USB_RECIP_DEVICE()\n");
 +
-       SMC_GET_MAC_ADDR(dev->dev_addr);
-       /* now, reset the chip, and put it into a known state */
-@@ -2005,7 +2018,11 @@ static int __init smc_probe(struct net_d
-       }
-       /* Grab the IRQ */
--              retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
-+      printk("dev->irq = %d\n", dev->irq);
++                              switch (pControlRequest->wValue) {
 +
-+      retval =
-+          request_irq(dev->irq, smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
++                              case 1:
++                                      DBG(3, "REMOTE_WAKEUP()\n");
++                                      while (0) { } /* remote wakeup */
++                                      break;
 +
-               if (retval)
-                       goto err_out;
-@@ -2045,7 +2062,8 @@ static int __init smc_probe(struct net_d
-               if (lp->phy_type == 0) {
-                       PRINTK("%s: No PHY found\n", dev->name);
-               } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) {
--                      PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name);
-+                      PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n",
-+                             dev->name);
-               } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
-                       PRINTK("%s: PHY LAN83C180\n", dev->name);
-               }
-@@ -2066,7 +2084,8 @@ static int smc_enable_device(struct plat
-       void __iomem *addr;
-       struct resource * res;
--      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-+      res =
-+          platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-       if (!res)
-               return 0;
-@@ -2122,7 +2141,8 @@ static int smc_enable_device(struct plat
- static int smc_request_attrib(struct platform_device *pdev)
- {
--      struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-+      struct resource *res =
-+          platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-       if (!res)
-               return 0;
-@@ -2135,7 +2155,8 @@ static int smc_request_attrib(struct pla
- static void smc_release_attrib(struct platform_device *pdev)
- {
--      struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-+      struct resource *res =
-+          platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
-       if (res)
-               release_mem_region(res->start, ATTRIB_SIZE);
-@@ -2159,8 +2180,12 @@ static inline void smc_request_datacs(st
-       }
- }
--static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
-+static void smc_release_datacs(struct platform_device *pdev,
-+                             struct net_device *ndev)
- {
-+//    struct smc_local *lp = netdev_priv(ndev);
-+//    struct resource *res =
-+//        platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
-       if (SMC_CAN_USE_DATACS) {
-               struct smc_local *lp = netdev_priv(ndev);
-               struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
-@@ -2201,7 +2226,6 @@ static int smc_drv_probe(struct platform
-               goto out;
-       }
--
-       if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
-               ret = -EBUSY;
-               goto out;
-@@ -2240,6 +2264,7 @@ static int smc_drv_probe(struct platform
-       }
-       platform_set_drvdata(pdev, ndev);
++                              case 2:
++                                      if (pControlRequest->wIndex & 0xff) {
++                                              handled=-EINVAL;
++                                      } else {
++                                              uint16_t wTest;
 +
-       ret = smc_probe(ndev, addr);
-       if (ret != 0)
-               goto out_iounmap;
-@@ -2278,7 +2303,6 @@ static int smc_drv_remove(struct platfor
-       platform_set_drvdata(pdev, NULL);
-       unregister_netdev(ndev);
--
-       free_irq(ndev->irq, ndev);
- #ifdef SMC_USE_PXA_DMA
-@@ -2348,8 +2372,6 @@ static int __init smc_init(void)
- #ifdef CONFIG_ISA
-       if (io == -1)
-               printk(KERN_WARNING
--                      "%s: You shouldn't use auto-probing with insmod!\n",
--                      CARDNAME);
- #endif
- #endif
-diff -Nauprw linux-2.6.20/drivers/net/smc91x.h ../new/linux-2.6.20/drivers/net/smc91x.h
---- linux-2.6.20/drivers/net/smc91x.h  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/net/smc91x.h   2007-11-21 11:51:41.000000000 +0530
-@@ -34,7 +34,6 @@
- #ifndef _SMC91X_H_
- #define _SMC91X_H_
--
- /*
-  * Define your architecture specific bus configuration parameters here.
-  */
-@@ -163,8 +162,7 @@
- #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
- /* We actually can't write halfwords properly if not word aligned */
--static inline void
--SMC_outw(u16 val, void __iomem *ioaddr, int reg)
-+static inline void SMC_outw(u16 val, void __iomem * ioaddr, int reg)
- {
-       if (reg & 2) {
-               unsigned int v = val << 16;
-@@ -199,6 +197,77 @@ SMC_outw(u16 val, void __iomem *ioaddr, 
-               || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
-       ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
-+#elif defined(CONFIG_ARCH_NOMADIK)
++                                              DBG(3, "ENTERING TESTMODE\n");
++                                              pThis->bTestMode = TRUE;
++                                              wTest = (uint8_t)pControlRequest->wIndex >> 8;
++                                              switch(wTest) {
 +
-+#include <asm/hardware.h>
++                                              case 1:
++                                                      DBG(3, "TEST_J\n");
++                                                      /* TEST_J */
++                                                      pThis->bTestModeValue = MGC_M_TEST_J;
++                                                      break;
 +
-+#define SMC_CAN_USE_8BIT      0
-+#define SMC_CAN_USE_16BIT     1
-+#define SMC_CAN_USE_32BIT     0
-+#define SMC_IO_SHIFT          0
-+#define SMC_NOWAIT            0
++                                              case 2:
++                                                      /* TEST_K */
++                                                      DBG(3, "TEST_K\n");
++                                                      pThis->bTestModeValue = MGC_M_TEST_K;
++                                                      break;
 +
-+#define SMC_inb(a, r)         readb((a) + (r))
-+#define SMC_outb(v, a, r)     writeb(v, (a) + (r))
-+#define SMC_inw(a, r)         readw((a) + (r))
-+#define SMC_outw(v, a, r)     writew(v, (a) + (r))
-+#define SMC_insw(a, r, p, l)  readsw((a) + (r), p, l)
-+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
-+#define SMC_inl(a, r)         readl((a) + (r))
-+#define SMC_outl(v, a, r)     writel(v, (a) + (r))
-+#define SMC_insl(a, r, p, l)  readsl((a) + (r), p, l)
-+#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
++                                              case 3:
++                                                      /* TEST_SE0_NAK */
++                                                      DBG(3, "TEST_SE0_NAK\n");
++                                                      pThis->bTestModeValue = MGC_M_TEST_SE0_NAK;
++                                                      break;
 +
-+#ifdef CONFIG_NOMADIK_NHK15
-+#define SMC_IRQ_FLAGS           SA_TRIGGER_RISING
-+#else
-+#define SMC_IRQ_FLAGS         (SA_SHIRQ)
++                                              case 4:
++                                                      /* TEST_PACKET */
++                                                      DBG(3, "TEST_PACKET\n");
++                                                      pThis->bTestModeValue = MGC_M_TEST_PACKET;
++                                                      break;
++
++                                              default:
++                                                      /* my gadget might know what to do with it */
++                                                      break;
++                                              }
++                                      }
++                                      break;
++#ifdef MUSB_OTG
++                              case 3:
++                                      GADGET_SET_B_HNP_ENABLE(pThis->pGadget, 1);
++                                      MGC_OtgMachineSetFeature(&(pThis->OtgMachine),
++                                              pControlRequest->wValue);
++                                      break;
++
++                              case 4:
++                                      GADGET_SET_A_HNP_SUPPORT(pThis->pGadget, 1);
++                                      MGC_OtgMachineSetFeature(&(pThis->OtgMachine),
++                                              pControlRequest->wValue);
++                                      break;
++
++                              case 5:
++                                      GADGET_SET_A_ALT_HNP_SUPPORT(pThis->pGadget, 1);
++                                      MGC_OtgMachineSetFeature(&(pThis->OtgMachine),
++                                              pControlRequest->wValue);
++                                      break;
 +#endif
++                              }
++                              break;
 +
-+static unsigned char new_mac_addr[MAX_ADDR_LEN] =
-+    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
++                              case USB_RECIP_INTERFACE:
++                                      DBG(3, "USB_RECIP_INTERFACE()\n");
++                                      break;
 +
-+static int smc_mac_setup(char *opt)
-+{
-+      char *cur = opt, *delim;
-+      if (*cur != 0) {
-+              /* Get the new MAC address */
-+              if ((delim = strchr(cur, ':')) == NULL)
-+                      goto parse_failed;
-+              *delim = 0;
-+              new_mac_addr[0] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+              new_mac_addr[0] &= 0xFE;        /* clear multicast bit */
-+              new_mac_addr[0] |= 0x02;        /* set local assignment bit (IEEE802) */
-+              cur = delim + 1;
-+              if ((delim = strchr(cur, ':')) == NULL)
-+                      goto parse_failed;
-+              *delim = 0;
-+              new_mac_addr[1] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+              cur = delim + 1;
-+              if ((delim = strchr(cur, ':')) == NULL)
-+                      goto parse_failed;
-+              *delim = 0;
-+              new_mac_addr[2] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+              cur = delim + 1;
-+              if ((delim = strchr(cur, ':')) == NULL)
-+                      goto parse_failed;
-+              *delim = 0;
-+              new_mac_addr[3] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+              cur = delim + 1;
-+              if ((delim = strchr(cur, ':')) == NULL)
-+                      goto parse_failed;
-+              *delim = 0;
-+              new_mac_addr[4] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+              cur = delim + 1;
-+              new_mac_addr[5] = (*cur - '0') * 16 + (*(cur + 1) - '0');
-+      }
-+      return 0;
-+parse_failed:
-+      printk(KERN_INFO "mac=: couldn't parse config at %s!\n", cur);
-+      return -1;
++                              case USB_RECIP_ENDPOINT: {
++                                      const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ;
++                                      MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ];
++
++                                      DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );
++                                      MGC_GadgetSetHalt(&pEnd->end_point, 1);
++
++                                      /* select ep0 again */
++                                      MGC_SelectEnd(pBase, 0);
++                                                                               }
++                                      break;
++
++                      }
++                      break; /* END: SET_FEATURE */
++
++                      default:
++                              handled=0;
++                              break;
++    }
++
++    /* standard request not handed by this code go to the gadget */
++    if ( !handled ) {
++              handled=forward_to_driver(pControlRequest);
++    }
++
++    DBG(-1002, "==>\n");
++    return handled;
 +}
 +
-+__setup("mac=", smc_mac_setup);
- #elif defined(CONFIG_SH_SH4202_MICRODEV)
-@@ -477,7 +546,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- }
- #endif  /* SMC_USE_PXA_DMA */
--
- /*
-  * Everything a particular hardware setup needs should have been defined
-  * at this point.  Add stubs for the undefined cases, mainly to avoid
-@@ -485,12 +553,14 @@ smc_pxa_dma_irq(int dma, void *dummy)
-  * use of them.
-  */
-+#if 0 /*Vaibhav*/
- #if ! SMC_CAN_USE_32BIT
- #define SMC_inl(ioaddr, reg)          ({ BUG(); 0; })
- #define SMC_outl(x, ioaddr, reg)      BUG()
- #define SMC_insl(a, r, p, l)          BUG()
- #define SMC_outsl(a, r, p, l)         BUG()
- #endif
-+#endif
- #if !defined(SMC_insl) || !defined(SMC_outsl)
- #define SMC_insl(a, r, p, l)          BUG()
-@@ -522,14 +592,18 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #endif
-+#if 0 /*Vaibhav*/
- #if !defined(SMC_insw) || !defined(SMC_outsw)
- #define SMC_insw(a, r, p, l)          BUG()
- #define SMC_outsw(a, r, p, l)         BUG()
- #endif
-+#endif
- #if ! SMC_CAN_USE_8BIT
-+#if 0 /*Vaibhav*/
- #define SMC_inb(ioaddr, reg)          ({ BUG(); 0; })
- #define SMC_outb(x, ioaddr, reg)      BUG()
-+#endif
- #define SMC_insb(a, r, p, l)          BUG()
- #define SMC_outsb(a, r, p, l)         BUG()
- #endif
-@@ -569,7 +643,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- */
- #define BANK_SELECT           (14 << SMC_IO_SHIFT)
--
- // Transmit Control Register
- /* BANK 0  */
- #define TCR_REG       SMC_REG(0x0000, 0)
-@@ -588,7 +661,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- /* the default settings for the TCR register : */
- #define TCR_DEFAULT   (TCR_ENABLE | TCR_PAD_EN)
--
- // EPH Status Register
- /* BANK 0  */
- #define EPH_STATUS_REG        SMC_REG(0x0002, 0)
-@@ -607,7 +679,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define ES_LINK_OK    0x4000  // Driven by inverted value of nLNK pin
- #define ES_TXUNRN     0x8000  // Tx Underrun
--
- // Receive Control Register
- /* BANK 0  */
- #define RCR_REG               SMC_REG(0x0004, 0)
-@@ -624,17 +695,14 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define RCR_DEFAULT   (RCR_STRIP_CRC | RCR_RXEN)
- #define RCR_CLEAR     0x0     // set it to a base state
--
- // Counter Register
- /* BANK 0  */
- #define COUNTER_REG   SMC_REG(0x0006, 0)
--
- // Memory Information Register
- /* BANK 0  */
- #define MIR_REG               SMC_REG(0x0008, 0)
--
- // Receive/Phy Control Register
- /* BANK 0  */
- #define RPC_REG               SMC_REG(0x000A, 0)
-@@ -661,14 +729,12 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
--
- /* Bank 0 0x0C is reserved */
- // Bank Select Register
- /* All Banks */
- #define BSR_REG               0x000E
--
- // Configuration Reg
- /* BANK 1 */
- #define CONFIG_REG    SMC_REG(0x0000, 1)
-@@ -680,24 +746,20 @@ smc_pxa_dma_irq(int dma, void *dummy)
- // Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
- #define CONFIG_DEFAULT        (CONFIG_EPH_POWER_EN)
--
- // Base Address Register
- /* BANK 1 */
- #define BASE_REG      SMC_REG(0x0002, 1)
--
- // Individual Address Registers
- /* BANK 1 */
- #define ADDR0_REG     SMC_REG(0x0004, 1)
- #define ADDR1_REG     SMC_REG(0x0006, 1)
- #define ADDR2_REG     SMC_REG(0x0008, 1)
--
- // General Purpose Register
- /* BANK 1 */
- #define GP_REG                SMC_REG(0x000A, 1)
--
- // Control Register
- /* BANK 1 */
- #define CTL_REG               SMC_REG(0x000C, 1)
-@@ -710,7 +772,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define CTL_RELOAD    0x0002 // When set reads EEPROM into registers
- #define CTL_STORE     0x0001 // When set stores registers into EEPROM
--
- // MMU Command Register
- /* BANK 2 */
- #define MMU_CMD_REG   SMC_REG(0x0000, 2)
-@@ -724,18 +785,15 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define MC_ENQUEUE    (6<<5)  // Enqueue the packet for transmit
- #define MC_RSTTXFIFO  (7<<5)  // Reset the TX FIFOs
--
- // Packet Number Register
- /* BANK 2 */
- #define PN_REG                SMC_REG(0x0002, 2)
--
- // Allocation Result Register
- /* BANK 2 */
- #define AR_REG                SMC_REG(0x0003, 2)
- #define AR_FAILED     0x80    // Alocation Failed
--
- // TX FIFO Ports Register
- /* BANK 2 */
- #define TXFIFO_REG    SMC_REG(0x0004, 2)
-@@ -755,17 +813,14 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define PTR_AUTOINC   0x4000 // Auto increment the pointer on each access
- #define PTR_READ      0x2000 // When 1 the operation is a read
--
- // Data Register
- /* BANK 2 */
- #define DATA_REG      SMC_REG(0x0008, 2)
--
- // Interrupt Status/Acknowledge Register
- /* BANK 2 */
- #define INT_REG               SMC_REG(0x000C, 2)
--
- // Interrupt Mask Register
- /* BANK 2 */
- #define IM_REG                SMC_REG(0x000D, 2)
-@@ -778,7 +833,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define IM_TX_INT     0x02 // Transmit Interrupt
- #define IM_RCV_INT    0x01 // Receive Interrupt
--
- // Multicast Table Registers
- /* BANK 3 */
- #define MCAST_REG1    SMC_REG(0x0000, 3)
-@@ -786,7 +840,6 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define MCAST_REG3    SMC_REG(0x0004, 3)
- #define MCAST_REG4    SMC_REG(0x0006, 3)
--
- // Management Interface Register (MII)
- /* BANK 3 */
- #define MII_REG               SMC_REG(0x0008, 3)
-@@ -796,13 +849,11 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define MII_MDI               0x0002 // MII Input, pin MDI
- #define MII_MDO               0x0001 // MII Output, pin MDO
--
- // Revision Register
- /* BANK 3 */
- /* ( hi: chip id   low: rev # ) */
- #define REV_REG               SMC_REG(0x000A, 3)
--
- // Early RCV Register
- /* BANK 3 */
- /* this is NOT on SMC9192 */
-@@ -810,12 +861,10 @@ smc_pxa_dma_irq(int dma, void *dummy)
- #define ERCV_RCV_DISCRD       0x0080 // When 1 discards a packet being received
- #define ERCV_THRESHOLD        0x001F // ERCV Threshold Mask
--
- // External Register
- /* BANK 7 */
- #define EXT_REG               SMC_REG(0x0000, 7)
--
- #define CHIP_9192     3
- #define CHIP_9194     4
- #define CHIP_9195     5
-@@ -834,8 +883,8 @@ static const char * chip_ids[ 16 ] =  {
-       /* 8 */ "SMC91C100FD",
-       /* 9 */ "SMC91C11xFD",
-       NULL, NULL, NULL,
--      NULL, NULL, NULL};
--
-+      NULL, NULL, NULL
-+};
- /*
-  . Receive status bits
-@@ -849,7 +898,6 @@ static const char * chip_ids[ 16 ] =  {
- #define RS_MULTICAST  0x0001
- #define RS_ERRORS     (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
--
- /*
-  * PHY IDs
-  *  LAN83C183 == LAN91C111 Internal PHY
-@@ -879,7 +927,6 @@ static const char * chip_ids[ 16 ] =  {
- #define PHY_CFG1_TLVL_MASK    0x003C
- #define PHY_CFG1_TRF_MASK     0x0003  // Transmitter Rise/Fall time
--
- // PHY Configuration Register 2
- #define PHY_CFG2_REG          0x11
- #define PHY_CFG2_APOLDIS      0x0020  // 1=Auto Polarity Correction disabled
-@@ -904,7 +951,6 @@ static const char * chip_ids[ 16 ] =  {
- #define PHY_MASK_REG          0x13    // Interrupt Mask
- // Uses the same bit definitions as PHY_INT_REG
--
- /*
-  * SMC91C96 ethernet config and status registers.
-  * These are in the "attribute" space.
-@@ -922,7 +968,6 @@ static const char * chip_ids[ 16 ] =  {
- #define ATTRIB_SIZE           ((64*1024) << SMC_IO_SHIFT)
--
- /*
-  * Macros to abstract register access according to the data bus
-  * capabilities.  Please use those and not the in/out primitives.
-@@ -1089,7 +1134,13 @@ static const char * chip_ids[ 16 ] =  {
- #define SMC_SET_TCR(x)                SMC_outw(x, ioaddr, TCR_REG)
- #ifndef SMC_GET_MAC_ADDR
-+#ifdef CONFIG_ARCH_NOMADIK
- #define SMC_GET_MAC_ADDR(addr)                                                \
-+      if (new_mac_addr[0] == 0xFF) {                                  \
-+              printk("%s: Setting Random MAC addr\n", CARDNAME);      \
-+              random_ether_addr(new_mac_addr);                        \
-+      }                                                               \
-+      SMC_SET_MAC_ADDR(new_mac_addr);                                 \
-       do {                                                            \
-               unsigned int __v;                                       \
-               __v = SMC_inw( ioaddr, ADDR0_REG );                     \
-@@ -1099,6 +1150,18 @@ static const char * chip_ids[ 16 ] =  {
-               __v = SMC_inw( ioaddr, ADDR2_REG );                     \
-               addr[4] = __v; addr[5] = __v >> 8;                      \
-       } while (0)
-+#else
-+#define SMC_GET_MAC_ADDR(addr)                                                \
-+      do {                                                            \
-+              unsigned int __v;                                       \
-+              __v = SMC_inw( ioaddr, ADDR0_REG );                     \
-+              addr[0] = __v; addr[1] = __v >> 8;                      \
-+              __v = SMC_inw( ioaddr, ADDR1_REG );                     \
-+              addr[2] = __v; addr[3] = __v >> 8;                      \
-+              __v = SMC_inw( ioaddr, ADDR2_REG );                     \
-+              addr[4] = __v; addr[5] = __v >> 8;                      \
-+      } while (0)
-+#endif
- #endif
- #define SMC_SET_MAC_ADDR(addr)                                                \
-diff -Nauprw linux-2.6.20/drivers/serial/amba-pl011.c ../new/linux-2.6.20/drivers/serial/amba-pl011.c
---- linux-2.6.20/drivers/serial/amba-pl011.c   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/serial/amba-pl011.c    2007-11-21 11:51:41.000000000 +0530
-@@ -52,13 +52,32 @@
- #include <asm/io.h>
- #include <asm/sizes.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
--#define UART_NR                       14
-+/*
-+ * Definations here is used instead of this which is defined in platform.h
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Complete a request on enpdpoint 0. This is called after a competition
++ * IRQ on ep0 has occourred.
++ * @warning Executed @ interrupt time; complete CANNOT sleep.
 + */
++void mgc_complete_ep0_request(void)
++{
++    struct usb_request *pRequest;
++    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
 +
-+#ifndef UART_NR
-+#define UART_NR                       14      /*default generic value */
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_LOCKED(&MGC_aGadgetLocalEnd[0]);
 +#endif
 +
-+#ifndef UART_FIFO_SIZE
-+#define UART_FIFO_SIZE          16    /*default generic value */
-+#endif
++    spin_lock( &MGC_aGadgetLocalEnd[0].Lock );
++    pRequest=MGC_CurrentRequest( &MGC_aGadgetLocalEnd[0] );
 +
-+#ifndef UART_PER_ID
-+#define UART_PER_ID           0x00041011      /*default uart peripharal id */
++    DBG(3, "completing request pRequest=%p\n", pRequest);
++
++    /* this is interrupt code, it cannot sleep! */
++    if ( pRequest ) {
++              list_del( &pRequest->list );
++              INIT_LIST_HEAD( &MGC_aGadgetLocalEnd[0].req_list );
++
++              spin_unlock( &MGC_aGadgetLocalEnd[0].Lock );
++              if ( pRequest->complete ) {
++                      pRequest->complete(&MGC_aGadgetLocalEnd[0].end_point,
++                              pRequest);
++              }
++    } else {
++              spin_unlock( &MGC_aGadgetLocalEnd[0].Lock );
++    }
++
++    pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
++}
++
++/**
++ * handle the completition interrupt on endpoint 0.
++ */
++static void handle_ep0_completition_irq(void)
++{
++    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++    DBG(3, "<==\n");
++    DBG(4, "post event interrupts ep0stage=%s\n",
++              decode_ep0stage(pThis->bEnd0Stage));
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]);
 +#endif
 +
-+#ifndef UART_PER_MASK
-+#define UART_PER_MASK         0x000fffff      /*default uart peripharal mask */
++    switch (pThis->bEnd0Stage) {
++
++              /* end of sequence #2 (RX state) or #3 (no data) */
++      case MGC_END0_STAGE_STATUSIN:
++              DBG(-1001, "MGC_END0_STAGE_STATUSIN request\n");
++
++              /* update address (if needed) only @ the end of the
++               * status phase per standard. The guide is WRONG!
++               */
++              if(pThis->bSetAddress) {
++                      pThis->bSetAddress = FALSE;
++                      MGC_Write8(pBase, MGC_O_HDRC_FADDR, pThis->bAddress);
++#ifdef MUSB_MONITOR_DATA
++                      MGC_EnableDebug();
 +#endif
- #define SERIAL_AMBA_MAJOR     204
- #define SERIAL_AMBA_MINOR     64
- #define SERIAL_AMBA_NR                UART_NR
--
- #define AMBA_ISR_PASS_LIMIT   256
- #define UART_DR_ERROR         (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
-@@ -102,9 +121,16 @@ static void pl011_stop_rx(struct uart_po
- static void pl011_enable_ms(struct uart_port *port)
- {
-       struct uart_amba_port *uap = (struct uart_amba_port *)port;
-+      unsigned cr;
--      uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
-+      uap->im |=
-+          UART011_RIMIM | UART011_CTSMIM | UART011_DCDMIM | UART011_DSRMIM;
-       writew(uap->im, uap->port.membase + UART011_IMSC);
++              }
 +
-+      cr = readw(uap->port.membase + UART011_CR);
-+      barrier();
-+      cr = cr | UART_CONTROL_MASK_CTSFLOW | UART_CONTROL_MASK_RTSFLOW;
-+      writew(cr, uap->port.membase + UART011_CR);
- }
- static void pl011_rx_chars(struct uart_amba_port *uap)
-@@ -115,6 +141,7 @@ static void pl011_rx_chars(struct uart_a
-       status = readw(uap->port.membase + UART01x_FR);
-       while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
-               ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
++              /* enter test mode if needed */
++              if(pThis->bTestMode) {
++                      DBG(-1001, "entering TESTMODE\n");
 +
-               flag = TTY_NORMAL;
-               uap->port.icount.rx++;
-@@ -174,7 +201,9 @@ static void pl011_tx_chars(struct uart_a
-       }
-       count = uap->port.fifosize >> 1;
++                      if (MGC_M_TEST_PACKET == pThis->bTestModeValue) {
++                              MGC_HdrcLoadFifo(pBase, 0, sizeof(MGC_aTestPacket),
++                                      MGC_aTestPacket);
++                      }
 +
-       do {
++                      spin_lock(&pThis->Lock);
++                      MGC_SelectEnd(pBase, 0); /* select ep0 */
++                      MGC_Write8(pBase, MGC_O_HDRC_TESTMODE,
++                              pThis->bTestModeValue);
++                      spin_unlock(&pThis->Lock);
++              }
 +
-               writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
-               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               uap->port.icount.tx++;
-@@ -318,6 +347,7 @@ static int pl011_startup(struct uart_por
-       struct uart_amba_port *uap = (struct uart_amba_port *)port;
-       unsigned int cr;
-       int retval;
-+      int status, ch;
-       /*
-        * Try to enable the clock producer.
-@@ -331,12 +361,19 @@ static int pl011_startup(struct uart_por
-       /*
-        * Allocate the IRQ
-        */
--      retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
-+      retval =
-+          request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap);
-       if (retval)
-               goto clk_dis;
--      writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
--             uap->port.membase + UART011_IFLS);
-+      /*      
-+       *writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
-+       *uap->port.membase + UART011_IFLS);
-+       */
++              DBG(-1001, "completing posted request (if any)\n");
++              mgc_complete_ep0_request();
++              break;
 +
-+      writew(UART_TX_RX_HALF, uap->port.membase + UART011_IFLS);
-+      /* Clearing interrupts */
-+      writew(0x7ff, uap->port.membase + UART011_ICR);
-       /*
-        * Provoke TX FIFO interrupt into asserting.
-@@ -346,7 +383,11 @@ static int pl011_startup(struct uart_por
-       writew(0, uap->port.membase + UART011_FBRD);
-       writew(1, uap->port.membase + UART011_IBRD);
-       writew(0, uap->port.membase + UART011_LCRH);
--      writew(0, uap->port.membase + UART01x_DR);
-+      writew('Z', uap->port.membase + UART01x_DR);
++              /* sequence #1: write to host (TX state)  */
++      case MGC_END0_STAGE_STATUSOUT:
++              DBG(-1001, "completing posted request (if any)\n");
++              mgc_complete_ep0_request();
++              break;
 +
-+      barrier();
-+      ch = readw(uap->port.membase + UART01x_DR);
++      case MGC_END0_STAGE_TX:
++              DBG(-1001, "TX changeing ep status\n");
++              if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) {
++                      pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT;
++              }
++              break;
 +
-       while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
-               barrier();
-@@ -356,7 +397,14 @@ static int pl011_startup(struct uart_por
-       /*
-        * initialise the old status of the modem signals
-        */
--      uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
-+      uap->old_status =
-+          readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
++      case MGC_END0_STAGE_RX:
++              DBG(-1001, "RX changeing ep status\n");
++              if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) {
++                      pThis->bEnd0Stage=MGC_END0_STAGE_STATUSIN;
++              }
++              break;
 +
-+      status = readw(uap->port.membase + UART01x_FR);
-+      while ((status & UART01x_FR_RXFE) == 0) {
-+              ch = readw(uap->port.membase + UART01x_DR);
-+              status = readw(uap->port.membase + UART01x_FR);
-+      }
-       /*
-        * Finally, enable interrupts
-@@ -396,7 +444,8 @@ static void pl011_shutdown(struct uart_p
-       /*
-        * disable the port
-        */
--      writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
-+      writew(UART01x_CR_UARTEN | UART011_CR_TXE,
-+             uap->port.membase + UART011_CR);
-       /*
-        * disable break condition and fifos
-@@ -658,6 +707,7 @@ static int __init pl011_console_setup(st
-        * if so, search for the first available port that does have
-        * console support.
-        */
++      default: /* IT WAS STALLED */
++              DBG(-1002, "recovering from stall? ep0stage=%s\n",
++                      decode_ep0stage(pThis->bEnd0Stage));
++              pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
++              break;
++    }
 +
-       if (co->index >= UART_NR)
-               co->index = 0;
-       uap = amba_ports[co->index];
-@@ -700,6 +750,28 @@ static struct uart_driver amba_reg = {
-       .cons                   = AMBA_CONSOLE,
- };
-+#ifdef CONFIG_PM
-+static int pl011_suspend(struct amba_device *dev, pm_message_t state)
-+{
-+      struct uart_amba_port *uap = amba_get_drvdata(dev);
++    DBG(3, "==>\n");
++}
 +
-+      if (uap)
-+              uart_suspend_port(&amba_reg, &uap->port);
 +
-+      return 0;
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Handle ep0 in receive state. Called to start a receie and on each interrupt
++ * when receiving data on ep0.
++ */
++int ep0_rxstate(void) {
++    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]);
++    struct usb_request *pRequest=MGC_CurrentRequest(pEnd);
++
++      /* nothign for now */
++    DBG(-1002, "<==\n");
++
++    if ( pRequest->actual==0 ) {
++              /* ack the request first */
++              DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
++              spin_lock(&pThis->Lock);
++              MGC_SelectEnd(pBase, 0);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      MGC_M_CSR0_P_SVDRXPKTRDY);
++              spin_unlock(&pThis->Lock);
++    }
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_LOCKED(&pEnd->Lock);
++#endif
++
++    DBG(-1002, "==>\n");
++
++    return 0;
 +}
 +
-+static int pl011_resume(struct amba_device *dev)
++/**
++ * Handle ep0 in transmit state. Called to start a receie and on each interrupt
++ * when transmitting data on ep0.
++ */
++int ep0_txstate(void)
 +{
-+      struct uart_amba_port *uap = amba_get_drvdata(dev);
++    unsigned long flags;
++    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
++    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]);
++    struct usb_request *pRequest=MGC_CurrentRequest(pEnd);
++    uint16_t wCsrVal = MGC_M_CSR0_TXPKTRDY;
++    uint8_t* pFifoSource;
++    uint8_t wFifoCount;
 +
-+      if (uap)
-+              uart_resume_port(&amba_reg, &uap->port);
++    DBG(-1002, "<==\n");
 +
-+      return 0;
-+}
++#ifdef MUSB_PARANOID
++    if ( !pThis || !pRequest )  {
++        ERR("pThis=%p, pRequest=%p", pThis, pRequest);
++        return -EINVAL;
++    }
 +#endif
 +
- static int pl011_probe(struct amba_device *dev, void *id)
- {
-       struct uart_amba_port *uap;
-@@ -739,9 +811,10 @@ static int pl011_probe(struct amba_devic
-       uap->port.membase = base;
-       uap->port.iotype = UPIO_MEM;
-       uap->port.irq = dev->irq[0];
--      uap->port.fifosize = 16;
-+      uap->port.fifosize = UART_FIFO_SIZE;
-       uap->port.ops = &amba_pl011_pops;
-       uap->port.flags = UPF_BOOT_AUTOCONF;
-+
-       uap->port.line = i;
-       amba_ports[i] = uap;
-@@ -782,8 +855,8 @@ static int pl011_remove(struct amba_devi
- static struct amba_id pl011_ids[] __initdata = {
-       {
--              .id     = 0x00041011,
--              .mask   = 0x000fffff,
-+       .id = UART_PER_ID,
-+       .mask = UART_PER_MASK,
-       },
-       { 0, 0 },
- };
-@@ -795,6 +868,10 @@ static struct amba_driver pl011_driver =
-       .id_table       = pl011_ids,
-       .probe          = pl011_probe,
-       .remove         = pl011_remove,
-+#ifdef CONFIG_PM
-+      .suspend = pl011_suspend,
-+      .resume = pl011_resume,
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock);
++      ASSERT_SPINLOCK_LOCKED(&pEnd->Lock);
 +#endif
- };
- static int __init pl011_init(void)
-diff -Nauprw linux-2.6.20/drivers/spi/Kconfig ../new/linux-2.6.20/drivers/spi/Kconfig
---- linux-2.6.20/drivers/spi/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/spi/Kconfig    2007-11-21 11:51:41.000000000 +0530
-@@ -65,6 +65,14 @@ config SPI_BITBANG
-         need it.  You only need to select this explicitly to support driver
-         modules that aren't part of this kernel tree.
-+config NOMADIK_SPI
-+      tristate "Nomadik SPI master"
-+      depends on SPI_MASTER && EXPERIMENTAL
-+      default y
-+      help
-+        This enables using the Nomadik SPI controller in master
-+        mode.
 +
- config SPI_BUTTERFLY
-       tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
-       depends on SPI_MASTER && PARPORT && EXPERIMENTAL
-diff -Nauprw linux-2.6.20/drivers/spi/Makefile ../new/linux-2.6.20/drivers/spi/Makefile
---- linux-2.6.20/drivers/spi/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/spi/Makefile   2007-11-21 11:51:41.000000000 +0530
-@@ -12,6 +12,8 @@ obj-$(CONFIG_SPI_MASTER)             += spi.o
- # SPI master controller drivers (bus)
- obj-$(CONFIG_SPI_BITBANG)             += spi_bitbang.o
-+obj-$(CONFIG_NOMADIK_SPI)             += nmdkmod_spi.o
-+nmdkmod_spi-objs                      := spi-nomadik.o
- obj-$(CONFIG_SPI_BUTTERFLY)           += spi_butterfly.o
- obj-$(CONFIG_SPI_PXA2XX)              += pxa2xx_spi.o
- obj-$(CONFIG_SPI_MPC83xx)             += spi_mpc83xx.o
-diff -Nauprw linux-2.6.20/drivers/spi/spi-nomadik.c ../new/linux-2.6.20/drivers/spi/spi-nomadik.c
---- linux-2.6.20/drivers/spi/spi-nomadik.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/spi/spi-nomadik.c      2008-07-04 23:45:22.000000000 +0530
-@@ -0,0 +1,1000 @@
++      spin_lock_irqsave(&pThis->Lock, flags);
++      MGC_SelectEnd(pBase, 0);
++
++    if ( pRequest->actual==0 ) {
++              /* ack the request first */
++              DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      MGC_M_CSR0_P_SVDRXPKTRDY);
++    }
++
++    /* load the data */
++    pFifoSource = (uint8_t*)pRequest->buf+pRequest->actual;
++    wFifoCount =min((int)MGC_END0_FIFOSIZE, (int)(pRequest->length-pRequest->actual));
++    MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoSource);
++    pRequest->actual+=wFifoCount; /* done */
++
++    /* update the flags */
++    if ( wFifoCount < MUSB_MAX_END0_PACKET ) {
++              wCsrVal |= MGC_M_CSR0_P_DATAEND;
++              pRequest->status=0; /* done */
++    }
++
++    /* send it out! (this will trigger the ep0 completition IRQ)
++       * serviced in interrupt_complete()
++       */
++    DBG(4, "wrote wFifoCount=%d bytes, wCsrVal=%s\n", wFifoCount,
++              decode_csr0(wCsrVal) );
++    MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
++    spin_unlock_irqrestore(&pThis->Lock, flags);
++
++    DBG(-1002, "==>\n");
++    return 0;
++}
++
++/* ---------------------------------------------------------------------- */
++
++/**
++ * Handle ep0 interrupt of a device, lock & release pThis. This is the main
++ * entry point of the gadget Ep0 handling code.
++ * @param pThis the controller
++ */
++uint8_t MGC_HdrcServiceFunctionEp0(MGC_LinuxCd* pThis)
++{
++    uint16_t wCsrVal; /* */
++    uint16_t wCount; /* bytes available */
++    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++    DBG(2, "<==\n");
++
++    spin_lock(&pThis->Lock);
++    MGC_SelectEnd(pBase, 0); /* select ep0 */
++    wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0);
++    wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
++
++    DEBUG_CODE(4, { uint8_t myaddr=MGC_Read8(pBase, MGC_O_HDRC_FADDR); \
++        uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); \
++              printk(KERN_INFO "%s: wCrsVal=0x%x, wCount=%d, myaddr=%0x, mode=%s, ep0stage=%s\n", \
++              __FUNCTION__, wCsrVal, wCount, myaddr, decode_devctl(devctl), \
++              decode_ep0stage(pThis->bEnd0Stage) ); } );
++
++    /* I sent a stall.. need to acknowledge it now.. */
++    if(wCsrVal & MGC_M_CSR0_P_SENTSTALL) {
++              DBG(-1002, "acking stall while in ep0stage=%s\n",
++                      decode_ep0stage(pThis->bEnd0Stage));
++
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      wCsrVal & ~MGC_M_CSR0_P_SENTSTALL );
++              pThis->bEnd0Stage=MGC_END0_STAGE_SETUP;
++    }
++
++    /* setup ended prematurely, abort it  */
++    if (wCsrVal & MGC_M_CSR0_P_SETUPEND) {
++              DBG(-1002, "acking setupend while in ep0stage=%s\n",
++                      decode_ep0stage(pThis->bEnd0Stage));
++
++              /* clearing it */
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      MGC_M_CSR0_P_SVDSETUPEND );
++              pThis->bEnd0Stage=MGC_END0_STAGE_SETUP;
++    }
++
++    spin_unlock(&pThis->Lock);
++
++    /* handle completition interrupt */
++    if ( !wCsrVal && !wCount ) {
++              handle_ep0_completition_irq();
++              return TRUE;
++    }
++
++    switch( pThis->bEnd0Stage ) {
++              /* done transmitting */
++      case MGC_END0_STAGE_STATUSOUT:
++      case MGC_END0_STAGE_STATUSIN:
++              mgc_complete_ep0_request();
++              break;
++    }
++
++    switch( pThis->bEnd0Stage ) {
++              /* im alrewady writing to host, TX state,
++               * sequence #1 initiated during the setup
++               */
++      case MGC_END0_STAGE_TX:
++              if (  wCsrVal & MGC_M_CSR0_TXPKTRDY  ) {
++                      DBG(-1001, "MGC_END0_STAGE_TX\n");
++                      ep0_txstate();
++              } break;
++
++              /* im alrewady receiving from host, RX state,
++               * sequence #2 initiated during the setup
++               */
++      case MGC_END0_STAGE_RX:
++              if (  wCsrVal & MGC_M_CSR0_RXPKTRDY  ) {
++                      DBG(-1001, "MGC_END0_STAGE_RX\n");
++                      ep0_rxstate();
++              }
++              break;
++
++              /* received from host, RX State, header */
++      case MGC_END0_STAGE_SETUP:
++              if ( wCsrVal & MGC_M_CSR0_RXPKTRDY ) {
++                      int count=0, handled=0;
++
++                      count=MGC_ReadUSBControlRequest(pThis, wCount);
++                      if ( count<0 ) {
++                              /* ack the request */
++                              ERR("error reading the control request: this is bad (tm)\n");
++                      } else if ( 0==count ) { /* I got the full packet, GREAT! */
++                              struct usb_ctrlrequest *pControlRequest=(struct usb_ctrlrequest*)
++                                      pThis->pEnd0Buffer;
++
++                              DBG(-1002, "%s\n", decode_request(pControlRequest));
++
++                              /* sequence #3 */
++                              if ( is_zerodata_request(pControlRequest) ) {
++                                      uint16_t wCsrVal= MGC_M_CSR0_P_SVDRXPKTRDY
++                                              | MGC_M_CSR0_P_DATAEND;
++
++                                      pThis->bEnd0Stage = MGC_END0_STAGE_STATUSIN;
++                                      handled=service_zero_data_request(pThis,
++                                              pControlRequest);
++                                      if ( handled<0 && handled!=-EOPNOTSUPP ) {
++                                              wCsrVal |= MGC_M_CSR0_P_SENDSTALL;
++                                      }
++
++                                      /* ack the request */
++                                      DBG(3, "handled=%d, wCsrVal=%s, ep0stage=%s\n", handled,
++                                              decode_csr0(wCsrVal),
++                                              decode_ep0stage(pThis->bEnd0Stage) );
++
++                                      spin_lock(&pThis->Lock);
++                                      MGC_SelectEnd(pBase, 0);
++                                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
++                                      spin_unlock(&pThis->Lock);
++                              } else {
++                                      /* sequence #1 */
++                                      if ( is_tx_request(pControlRequest) ) {
++                                              /* write to host, a request is posted on ep0 */
++                                              pThis->bEnd0Stage=MGC_END0_STAGE_TX;
++                                              handled=service_tx_request(pControlRequest);
++                                              /* sequence #2, a request is posted on ep0 */
++                                      } else if ( is_rx_request(pControlRequest) ) {
++                                              pThis->bEnd0Stage=MGC_END0_STAGE_RX;
++                                              handled=service_rx_request(pControlRequest);
++                                      }
++
++                                      if ( handled<0 ) {
++                                              /* stall it!!! application stall */
++                                              spin_lock(&pThis->Lock);
++                                              MGC_SelectEnd(pBase, 0);
++                                              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                                                      MGC_M_CSR0_P_SVDRXPKTRDY | MGC_M_CSR0_P_SENDSTALL);
++                                              spin_unlock(&pThis->Lock);
++                                      }
++                              }
++
++                      }
++              } else {
++
++              }
++              break;
++
++
++              /* handle the application stall on Ep0 */
++      default:
++              {
++              uint16_t wCsrVal = MGC_M_CSR0_P_SENDSTALL;
++
++              switch ( pThis->bEnd0Stage & ~MGC_END0_STAGE_STALL_BIT ) {
++
++              case MGC_END0_STAGE_TX:
++                      wCsrVal|=MGC_M_CSR0_TXPKTRDY;
++                      break;
++
++              case MGC_END0_STAGE_RX:
++                      wCsrVal|=MGC_M_CSR0_RXPKTRDY;
++                      break;
++
++              }
++
++              DBG(3, "Application stall from ep0stage=%s\n",
++                      decode_ep0stage(pThis->bEnd0Stage));
++              spin_lock(&pThis->Lock);
++              MGC_SelectEnd(pBase, 0);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
++              spin_unlock(&pThis->Lock);
++
++              pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
++              }
++              break;
++    }
++
++    return 1;
++}
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/logx
+@@ -0,0 +1 @@
++make: *** No rule to make target `vmlinux'.  Stop.
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c
+@@ -0,0 +1,371 @@
 +/*
-+ * drivers/spi/spi-nomadik.c
-+ *
-+ * Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
++ * linux/drivers/usb/nomadik/musb_bus_direct.c
 + *
-+ * Author:    Sachin Verma <sachin.verma@st.com>
-+ *            Vaibhav Agarwal <vaibhav.agarwal@st.com
-+ * Initial version inspired by:
-+ *    linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
++ * Copyright 2007, STMicroelectronics
 + *
 + * 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
@@ -189506,1054 +193347,695 @@ diff -Nauprw linux-2.6.20/drivers/spi/spi-nomadik.c ../new/linux-2.6.20/drivers/
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/ioport.h>
-+#include <linux/errno.h>
-+#include <linux/platform_device.h>
-+#include <linux/amba/bus.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
 +
++#include "musbdefs.h"
 +#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/delay.h>
 +
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/defs.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/spi.h>
-+#include <asm/arch/debug.h>
-+#include <asm/arch/ssp-spi.h>
-+#include <asm/arch/msp-spi.h>
-+#include <asm/arch/msp.h>
++#ifdef MUSB_BOARD_FILE
++#include CONFIG_USB_INVENTRA_MUSB_BOARD_FILE
++#else
++#include "board.h"
++#endif
 +
-+/***************************************************************************/
++#ifndef MUSB_BOARD_DEFAULT_SIZE
++#define MUSB_DEFAULT_ADDRESS_SPACE_SIZE 0x00001000
++#endif
 +
-+#define NMDK_SPI_NAME         "NOMADIK_SPI"
++#ifdef MUSB_V26
++#include <linux/device.h>
++#endif
 +
-+#ifndef SPI_DEBUG
-+#define SPI_DEBUG 0
++/****************************** sysfs stuff *****************************/
++
++#define kobj_to_direct_driver(obj) container_of(obj, struct device_driver, kobj)
++#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
++
++/**************************** instance vars *****************************/
++
++#ifndef MUSB_USE_HCD_DRIVER
++static int MGC_InstancesCount=0;
++static MGC_LinuxCd** MGC_DriverInstances;
 +#endif
 +
-+#define NMDK_DEBUG    SPI_DEBUG       /* enables/disables nmdk_dbg msgs */
-+#define NMDK_DEBUG_PFX  NMDK_SPI_NAME /* msg header represents this module */
-+#define NMDK_DBG      KERN_ERR        /* message level */
++void *g_pDevice;
++/********************* under 26 thigs changes a bit *************************/
 +
-+/***************************************************************************/
++#ifdef MUSB_V26
++#if 1
++struct device MGC_ControllerDevice =
++{
 +
-+#define FALSE                                 (0)
-+#define TRUE                          (1)
++};
 +
-+#define DO_NOT_QUEUE_DMA      (0)
-+#define QUEUE_DMA             (1)
++struct device_driver MGC_ControllerDriver=
++{
++      .name = "musb-hcd",
++};
++#endif
 +
-+/*#######################################################################
-+      Queue State
-+#########################################################################
-+ */
-+#define QUEUE_RUNNING                   (0)
-+#define QUEUE_STOPPED                   (1)
++#ifndef MUSB_USE_HCD_DRIVER
 +
-+/***************************************************************************/
-+static void print_dma_info(u32 xfer_type, struct chip_data *chip){
-+      nmdk_dbg("Rx Pipe : mode = %08x\n", chip->dma_info->rx_dma_info.mode);
-+      nmdk_dbg("Rx Pipe : config = %08x\n", chip->dma_info->rx_dma_info.config);
-+      nmdk_dbg("Rx Pipe : srcdevtype = %s\n", chip->dma_info->rx_dma_info.srcdevtype);
-+      nmdk_dbg("Rx Pipe : destdevtype = %s\n", chip->dma_info->rx_dma_info.destdevtype);
++static inline ssize_t
++store_new_id(struct device_driver *driver, const char *buf, size_t count);
 +
-+      nmdk_dbg("Tx Pipe : mode = %08x\n", chip->dma_info->tx_dma_info.mode);
-+      nmdk_dbg("Tx Pipe : config = %08x\n", chip->dma_info->tx_dma_info.config);
-+      nmdk_dbg("Tx Pipe : srcdevtype = %s\n", chip->dma_info->tx_dma_info.srcdevtype);
-+      nmdk_dbg("Tx Pipe : destdevtype = %s\n", chip->dma_info->tx_dma_info.destdevtype);
-+}
-+/***************************************************************************/
++
++static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
++
++static ssize_t driver_count=0;
++
++/* probably we don't need to be a system device in this case */
++struct device MGC_ControllerDevice =
++{
++
++};
++
++struct device_driver MGC_ControllerDriver=
++{
++      .name = "musb-hcd",
++};
 +
 +/**
-+ * null_cs_control - Dummy chip select function
-+ * @command: select/delect the chip
++ * store_new_id
 + *
-+ * If no chip select function is provided by client this is used as dummy
-+ * chip select
++ * Adds a new dynamic device ID to this driver,
++ * and causes the driver to probe for all devices again.
 + */
-+void null_cs_control(u32 command)
++static inline ssize_t
++store_new_id(struct device_driver *driver, const char *buf, size_t count)
 +{
-+      nmdk_dbg_ftrace();
-+      nmdk_dbg("::::Dummy chip select control\n");
++      return driver_count++;
 +}
-+EXPORT_SYMBOL(null_cs_control);
 +
-+void nomadik_spi_tasklet(unsigned long param)
++
++static ssize_t
++direct_driver_attr_store(struct kobject * kobj, struct attribute *attr,
++                    const char *buf, size_t count)
 +{
-+      struct driver_data *drv_data = (struct driver_data *)param;
-+      struct spi_message *msg = drv_data->cur_msg;
-+      struct spi_transfer *previous = NULL;
-+      /*DMA complete. schedule next xfer */
-+      /*DISABLE DMA, and flush FIFO of SPI Controller */
-+      drv_data->execute_cmd(drv_data, DISABLE_DMA);
-+      drv_data->execute_cmd(drv_data, FLUSH_FIFO);
-+      msg->actual_length += drv_data->cur_transfer->len;
-+      if (drv_data->cur_transfer->cs_change)
-+              drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
-+      msg->state = next_transfer(drv_data);
-+      if (msg->state == ERROR_STATE)
-+              goto handle_dma_error;
-+      else if (msg->state == DONE_STATE) {
-+              drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+              msg->status = 0;
-+              giveback(msg, drv_data);
-+              return ;
-+      }
-+      /* Delay if requested at end of transfer */
-+      else if (msg->state == RUNNING_STATE) {
-+              previous =
-+                      list_entry(drv_data->cur_transfer->transfer_list.
-+                                      prev, struct spi_transfer,
-+                                      transfer_list);
-+              if (previous->delay_usecs)
-+                      udelay(previous->delay_usecs);
-+              if (previous->cs_change)
-+                      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+      } else  goto handle_dma_error;
++      struct device_driver *driver = kobj_to_direct_driver(kobj);
++      struct driver_attribute *dattr = attr_to_driver_attribute(attr);
++      ssize_t ret = 0;
 +
-+      if (drv_data->cur_transfer->tx_dma) {
-+              atomic_inc(&drv_data->dma_cnt);
-+              __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach, (dma_addr_t) (drv_data->cur_transfer->tx_dma));
-+              __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
-+                              (dma_addr_t) (drv_data->master_info->dma_srcaddr));
-+              set_dma_count(drv_data->cur_chip->dma_info->tx_dmach, (drv_data->cur_transfer->len));
-+              enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
-+      }
-+      if (drv_data->cur_transfer->rx_dma) {
-+              atomic_inc(&drv_data->dma_cnt);
-+              __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
-+                              (dma_addr_t) (drv_data->master_info->dma_destaddr));
-+              __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach, (dma_addr_t) (drv_data->cur_transfer->rx_dma));
-+              set_dma_count(drv_data->cur_chip->dma_info->rx_dmach, (drv_data->cur_transfer->len));
-+              enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
++      if (get_driver(driver)) {
++              if (dattr->store)
++                      ret = dattr->store(driver, buf, count);
++              put_driver(driver);
 +      }
-+      /*Enable DMA for this chip */
-+      drv_data->execute_cmd(drv_data, ENABLE_DMA);
-+      return ;
-+
-+      handle_dma_error:
-+         atomic_set(&drv_data->dma_cnt, 0);
-+        drv_data->execute_cmd(drv_data, DISABLE_DMA);
-+        msg->status = -EIO;
-+        giveback(msg, drv_data);
-+        return ;
++      return ret;
 +}
-+EXPORT_SYMBOL(nomadik_spi_tasklet);
 +
-+/**
-+ * spi_dma_callback_handler - This function is invoked when dma xfer is complete
-+ * @param: context data which is drivers private data
-+ * @event: Status of current DMA transfer
-+ *
-+ * This function checks if DMA transfer is complete for current transfer
-+ * It fills the Rx Tx buffer pointers again and launch dma for next
-+ * transfer from this callback handler itself
-+ *
-+ */
-+irqreturn_t spi_dma_callback_handler(int irq, void *param)
++static ssize_t
++direct_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
 +{
-+        struct driver_data *drv_data = (struct driver_data *)param;
-+      int flag = 0;
-+
-+        nmdk_dbg_ftrace();
++      struct device_driver *driver = kobj_to_direct_driver(kobj);
++      struct driver_attribute *dattr = attr_to_driver_attribute(attr);
++      ssize_t ret = 0;
 +
-+        smp_mb();
-+        if (atomic_dec_and_test(&drv_data->dma_cnt)) {
-+                flag = 1;
-+        }
-+        smp_mb();
-+        if (flag == 1) {
-+      tasklet_schedule(&drv_data->spi_dma_tasklet);
++      if ( get_driver(driver) ) {
++              if (dattr->show)
++                      ret = dattr->show(driver, buf);
++              put_driver(driver);
 +      }
-+      return IRQ_HANDLED;
++      return ret;
 +}
-+EXPORT_SYMBOL(spi_dma_callback_handler);
 +
-+/**
-+ * giveback - current spi_message is over, schedule next spi_message and call callback of this msg
-+ * @message: current SPI message 
-+ * @drv_data: spi driver private data structure
-+ *
-+ */
-+void giveback(struct spi_message *message, struct driver_data *drv_data)
++static struct sysfs_ops direct_driver_sysfs_ops = {
++      .show = direct_driver_attr_show,
++      .store = direct_driver_attr_store,
++};
++static struct kobj_type direct_driver_kobj_type = {
++      .sysfs_ops = &direct_driver_sysfs_ops,
++};
++
++static int
++direct_create_newid_file(struct device_driver *drv)
 +{
-+      struct spi_transfer *last_transfer;
-+      unsigned long flags;
-+      struct spi_message *msg;
-+      void (*curr_cs_control) (u32 command);
++      int error = 0;
++      if (drv->probe != NULL)
++              error = sysfs_create_file(&drv->kobj,
++                      &driver_attr_new_id.attr);
++      return error;
++}
 +
-+      spin_lock_irqsave(&drv_data->lock, flags);
-+      msg = drv_data->cur_msg;
++static int
++direct_populate_driver_dir(struct device_driver *drv)
++{
++      return direct_create_newid_file(drv);
++}
 +
-+      curr_cs_control = drv_data->cur_chip->cs_control;
-+      drv_data->cur_msg = NULL;
-+      drv_data->cur_transfer = NULL;
-+      drv_data->cur_chip = NULL;
-+#ifdef SPI_WORKQUEUE  
-+      queue_work(drv_data->workqueue, &drv_data->spi_work);
-+#endif        
-+      spin_unlock_irqrestore(&drv_data->lock, flags);
-+      
-+      schedule_work(&drv_data->spi_work);
++/* ------------------------ let the ball rolling -------------------------*/
 +
-+      last_transfer = list_entry(msg->transfers.prev,
-+                                 struct spi_transfer, transfer_list);
-+      if (!last_transfer->cs_change)
-+              curr_cs_control(SPI_CHIP_DESELECT);
-+      msg->state = NULL;
-+      if (msg->complete)
-+              msg->complete(msg->context);
-+      drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
++/* customize for different behavior */
++static int direct_hotplug (struct device *dev, char **envp, int num_envp,
++    char *buffer, int buffer_size)
++{
++      return -ENODEV;
 +}
-+EXPORT_SYMBOL(giveback);
 +
-+/**
-+ * next_transfer - Move to the Next transfer in the current spi message
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function moves though the linked list of spi transfers in the 
-+ * current spi message and returns with the state of current spi
-+ * message i.e whether its last transfer is done(DONE_STATE) or 
-+ * Next transfer is ready(RUNNING_STATE)
-+ */
-+void *next_transfer(struct driver_data *drv_data)
++static int direct_device_suspend(struct device * dev, u32 state)
 +{
-+      struct spi_message *msg = drv_data->cur_msg;
-+      struct spi_transfer *trans = drv_data->cur_transfer;
-+      /* Move to next transfer */
-+      if (trans->transfer_list.next != &msg->transfers) {
-+              drv_data->cur_transfer =
-+                  list_entry(trans->transfer_list.next,
-+                             struct spi_transfer, transfer_list);
-+              return RUNNING_STATE;
-+      }
-+      return DONE_STATE;
++      return 0;
 +}
-+EXPORT_SYMBOL(next_transfer);
 +
-+/**
-+ * ssp_null_writer - To Write Dummy Data in Data register
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function is set as a write function for transfer which have 
-+ * Tx transfer buffer as NULL. It simply writes '0' in the Data
-+ * register
-+ */
-+static void ssp_null_writer(struct driver_data *drv_data)
++/* customize for different behavior */
++static int direct_device_resume(struct device * dev)
 +{
-+      while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_TNF)
-+             && (drv_data->tx < drv_data->tx_end)) {
-+              /*Write '0' Data to Data Register */
-+              writel(0x0, SSP_DR(drv_data->regs));
-+              drv_data->tx += (drv_data->cur_chip->n_bytes);
-+      }
++      return 0;
 +}
 +
-+/**
-+ * ssp_null_reader - To read data from Data register and discard it
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function is set as a reader function for transfer which have
-+ * Rx Transfer buffer as null. Read Data is rejected
-+ *
-+ */
-+static void ssp_null_reader(struct driver_data *drv_data)
-+{
-+      while ((readl(SSP_SR(drv_data->regs)) & SSP_SR_MASK_RNE)
-+             && (drv_data->rx < drv_data->rx_end)) {
-+              readl(SSP_DR(drv_data->regs));
-+              drv_data->rx += (drv_data->cur_chip->n_bytes);
-+      }
++static int direct_bus_match(struct device * dev, struct device_driver * drv) {
++      return (&MGC_ControllerDriver==drv)?1:0;
 +}
 +
++struct bus_type direct_bus_type = {
++      .name           = "system",
++      .match          = direct_bus_match,
++      .hotplug        = direct_hotplug,
++      .suspend        = direct_device_suspend,
++      .resume         = direct_device_resume,
++};
++
 +/**
-+ * msp_null_writer - To Write Dummy Data in Data register
-+ * @drv_data: spi driver private data structure
++ * direct_register_driver - register a new driver
++ * @drv: the driver structure to register
 + *
-+ * This function is set as a write function for transfer which have 
-+ * Tx transfer buffer as NULL. It simply writes '0' in the Data
-+ * register
++ * Adds the driver structure to the list of registered drivers
++ * Returns the number of devices which were claimed by the driver
++ * during registration.  The driver remains registered even if the
++ * return value is zero.
 + */
-+static void msp_null_writer(struct driver_data *drv_data)
++static int
++direct_register_driver(struct device_driver *drv, struct bus_type *btype)
 +{
-+      u32 cur_write = 0;
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
-+              if((status & MSP_FLR_MASK_TFU) || (drv_data->tx >= drv_data->tx_end))
-+                      return;
-+              writel( 0x0, MSP_DR(drv_data->regs));
-+              drv_data->tx += (drv_data->cur_chip->n_bytes);
-+              cur_write ++;
-+              if(cur_write == 8)
-+                      return;
-+      }
++    int count = 0;
++
++    /* initialize common driver fields */
++    drv->bus = (btype)?btype:&direct_bus_type;
++    drv->kobj.ktype = &direct_driver_kobj_type;
++
++    /* register with core */
++    count = driver_register( drv );
++    if (count >= 0) {
++          direct_populate_driver_dir( drv );
++    }
++
++    return count ? count : 1;
 +}
 +
 +/**
-+ * msp_null_reader - To read data from Data register and discard it
-+ * @drv_data: spi driver private data structure
-+ *
-+ * This function is set as a reader function for transfer which have
-+ * Rx Transfer buffer as null. Read Data is rejected
++ * unregister_driver - unregister a driver
++ * @drv: the driver structure to unregister
 + *
++ * Deletes the driver structure from the list of registered drivers,
++ * gives it a chance to clean up by calling its remove() function for
++ * each device it was responsible for, and marks those devices as
++ * driverless.
 + */
-+static void msp_null_reader(struct driver_data *drv_data)
++
++static void
++direct_unregister_driver(struct device_driver *drv)
 +{
-+      u32 status;
-+      while(1){
-+              status = readl(MSP_FLR(drv_data->regs));
-+              if( (status & MSP_FLR_MASK_RFE) || ( drv_data->rx >= drv_data->rx_end))
-+                      return;
-+              readl(MSP_DR(drv_data->regs));
-+              drv_data->rx += (drv_data->cur_chip->n_bytes);
-+      }
++    driver_unregister( drv );
 +}
 +
++#endif
++#endif
++
++/* ------------------------------------------------------------------- */
++/* ------------------------------------------------------------------- */
++/* ------------------------------------------------------------------- */
++
++#ifdef MUSB_CUSTOM_DIRECT_BUS_FILE
++#include MUSB_CUSTOM_DIRECT_BUS_FILE
++#else
 +/**
-+ * pump_transfers - Tasklet function which schedules next interrupt xfer
-+ * @data: spi driver private data structure
-+ *
++ * Discover and initialize the drivers on the direct bus.
 + */
-+static void pump_transfers(unsigned long data)
-+{
-+      struct driver_data *drv_data = (struct driver_data *)data;
-+      struct spi_message *message = NULL;
-+      struct spi_transfer *transfer = NULL;
-+      struct spi_transfer *previous = NULL;
-+      
-+      nmdk_dbg_ftrace();
++int
++direct_bus_init(void) {
 +
-+      message = drv_data->cur_msg;
-+      /* Handle for abort */
-+      if (message->state == ERROR_STATE) {
-+              message->status = -EIO;
-+              giveback(message, drv_data);
-+              return;
-+      }
-+      /* Handle end of message */
-+      if (message->state == DONE_STATE) {
-+              message->status = 0;
-+              giveback(message, drv_data);
-+              return;
++    int rc= -1;
++    char name[32];
++    void* pDevice = NULL;
++
++#ifdef MUSB_USE_HCD_DRIVER
++      MGC_LinuxCd* pThis;
++
++      /* already initialized */
++      if ( MGC_nIndex ) {
++              return 0;
 +      }
-+      transfer = drv_data->cur_transfer;
-+      /* Delay if requested at end of transfer */
-+      if (message->state == RUNNING_STATE) {
-+              previous =
-+                  list_entry(transfer->transfer_list.prev,
-+                             struct spi_transfer, transfer_list);
-+              if (previous->delay_usecs)
-+                      udelay(previous->delay_usecs);
-+              if (previous->cs_change)
-+                      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+      } else {
-+              /* START_STATE */
-+              message->state = RUNNING_STATE;
++      snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
++
++      pDevice = &MGC_ControllerDevice;
++      g_pDevice=pDevice;
++      kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
++
++      rc = kobject_register(&((struct device*)pDevice)->kobj);
++
++      if(rc < 0){
++              ERR("failed to register:%d\n", rc);
++              return rc;
 +      }
-+      drv_data->tx = (void *)transfer->tx_buf;
-+      drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
-+      drv_data->rx = (void *)transfer->rx_buf;
-+      drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
 +
-+      if(drv_data->master->bus_num == SSP_CONTROLLER){
-+              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
-+              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
++      INIT_LIST_HEAD( (struct list_head*)&((struct device*)pDevice)->klist_children );
++
++      ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
++
++      sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);
++
++      pThis = MGC_LinuxInitController(pDevice, MUSB_CONTROLLER_HDRC, INT_USBOTG,
++              ioremap(NOMADIK_USB_BASE, 0x100000), 0x00100000, name);
++
++      if(pThis) {
++              DBG(3, "MGC_LinuxInitController success MGC_struct:0x%p \n", pThis);
++              rc = 0;
++              MGC_VirtualHubStart( &(pThis->RootHub) );
 +      }
-+      else{
-+              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
-+              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
++      return(rc);
++
++#else
++      const int nCount = sizeof(MUSB_aLinuxController)
++              / sizeof(MUSB_LinuxController);
++    int nIndex;
++
++      INFO("Probing direct bus [direct=%d]\n", nCount);
++
++      if ( !nCount ) {
++              return 0;
++    }
++
++    KMALLOC(MGC_DriverInstances, nCount*sizeof(MGC_LinuxCd*), GFP_ATOMIC);
++    if ( !MGC_DriverInstances ) {
++        return -ENOMEM;
++    }
++
++#ifdef MUSB_V26
++    pDevice = &MGC_ControllerDevice;
++      kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
++      rc = kobject_register(&((struct device*)pDevice)->kobj);
++      if(rc < 0){
++              ERR("failed to register:%d\n", rc);
++              return rc;
 +      }
 +
-+      drv_data->execute_cmd(drv_data, FLUSH_FIFO);
-+      drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
++      INIT_LIST_HEAD( &((struct device*)pDevice)->children );
++
++      ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
++      sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);
++    bus_register( &direct_bus_type );
++    direct_register_driver(&MGC_ControllerDriver, NULL);
++#endif
++
++    /* NON PCI machines */
++    for (nIndex = 0; !rc && nIndex < nCount; nIndex++) {
++              MUSB_LinuxController* pStaticController=&(MUSB_aLinuxController[nIndex]);
++
++        snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
++              MGC_DriverInstances[nIndex]=MGC_LinuxInitController(pDevice,
++                      pStaticController->wType, pStaticController->dwIrq,
++                      pStaticController->pBase,
++                      (pStaticController->dwSize)? pStaticController->dwSize
++                      : MUSB_DEFAULT_ADDRESS_SPACE_SIZE, name);
++
++              if( MGC_DriverInstances[nIndex] ) {
++#ifdef MUSB_VIRTHUB
++                      MGC_VirtualHubStart( &(MGC_DriverInstances[nIndex]->RootHub) );
++#endif
++                      MGC_InstancesCount++;
++              } else {
++                      ERR("controller %d failed to initialize\n", nIndex);
++                      direct_bus_shutdown();
++                      rc=-1;
++              }
++    }
++    return MGC_InstancesCount;
++#endif
++
 +}
 +
 +/**
-+ * do_dma_transfer - It handles transfers of the current message if it is DMA xfer
-+ * @data: spi driver's private data structure
-+ *
-+ *
 + *
 + */
-+static void do_dma_transfer(void *data)
++void direct_bus_shutdown(void)
 +{
-+        struct driver_data *drv_data = (struct driver_data *)data;
++#ifdef MUSB_USE_HCD_DRIVER
++      kobject_unregister(&((struct device*)g_pDevice)->kobj); /* shoudl check the hcd drivers */
 +
-+        atomic_set(&drv_data->dma_cnt, 0);
-+        drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
 +
-+        if ((drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_MEM) ||
-+            (drv_data->cur_chip->dma_info->dma_xfer_type == SPI_WITH_PERIPH)) {
-+                if (drv_data->cur_chip->dma_info->tx_dmach >= 0) {
-+                        atomic_inc(&drv_data->dma_cnt);
-+                        __set_dma_srcaddr(drv_data->cur_chip->dma_info->tx_dmach,
-+                            (dma_addr_t) (drv_data->cur_transfer->tx_dma));
-+                        __set_dma_destaddr(drv_data->cur_chip->dma_info->tx_dmach,
-+                            (dma_addr_t) (drv_data->master_info->dma_srcaddr));
-+                        set_dma_count(drv_data->cur_chip->dma_info->tx_dmach,
-+                            (drv_data->cur_transfer->len));
-+                      enable_dma(drv_data->cur_chip->dma_info->tx_dmach);
-+                }
-+                if (drv_data->cur_chip->dma_info->rx_dmach >= 0) {
-+                        atomic_inc(&drv_data->dma_cnt);
-+                        __set_dma_srcaddr(drv_data->cur_chip->dma_info->rx_dmach,
-+                            (dma_addr_t) (drv_data->master_info->dma_destaddr));
-+                        __set_dma_destaddr(drv_data->cur_chip->dma_info->rx_dmach,
-+                            (dma_addr_t) (drv_data->cur_transfer->rx_dma));
-+                        set_dma_count(drv_data->cur_chip->dma_info->rx_dmach,
-+                            (drv_data->cur_transfer->len));
-+                        enable_dma(drv_data->cur_chip->dma_info->rx_dmach);
-+                }
-+                if((drv_data->cur_chip->dma_info->tx_dma_info.mode & DMA_INFINITE_XFER) &&
-+                        (drv_data->cur_chip->dma_info->rx_dma_info.mode & DMA_INFINITE_XFER)){
-+                        /*Only if it is an infinite transfer, we will deploy mechanism to stop it*/
-+                        nmdk_dbg("Only if it is an infinite transfer, we will deploy mechanism to stop it");
-+                        drv_data->dma_ongoing = 1;
-+                }
-+        } else {
-+                nmdk_dbg(":::: Invalid DMA xfer type \n");
-+                goto err_dma_transfer;
-+        }
-+        /*Enable SPI Controller */
-+        drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
-+        return;
++#else
++    int nIndex=0;
 +
-+      err_dma_transfer:
-+        drv_data->cur_msg->state = ERROR_STATE;
-+        drv_data->cur_msg->status = -EIO;
-+        giveback(drv_data->cur_msg, drv_data);
-+        return;
-+}
++      /* free the instances */
++    for (nIndex = 0; nIndex < MGC_InstancesCount; nIndex++) {
++              MGC_LinuxCdFree( MGC_DriverInstances[nIndex] );
++    }
 +
-+static void do_interrupt_transfer(void *data)
-+{
-+      struct driver_data *drv_data = (struct driver_data *)data;
++      KFREE(MGC_DriverInstances);
++#ifdef MUSB_V26
++      direct_unregister_driver(&MGC_ControllerDriver);
++#endif
++#endif
 +
-+      drv_data->tx = (void *)drv_data->cur_transfer->tx_buf;
-+      drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
-+      drv_data->rx = (void *)drv_data->cur_transfer->rx_buf;
-+      drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
++}
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_cross.h
+@@ -0,0 +1,131 @@
++/*
++ * linux/drivers/usb/nomadik/musb_cross.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ */
 +
-+      if(drv_data->master->bus_num == SSP_CONTROLLER){
-+              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
-+              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
-+      }
-+      else{
-+              drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
-+              drv_data->read = drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
-+      }
++#ifndef __MUSB_CROSS_H
++#define __MUSB_CROSS_H
 +
-+      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
++#include <linux/version.h>
 +
-+      drv_data->execute_cmd(drv_data, ENABLE_ALL_INTERRUPT);
-+      drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
-+}
++/****************************** KERNEL VERSION MACROS ************************/
 +
-+static void do_polling_transfer(void *data)
-+{
-+      struct driver_data *drv_data = (struct driver_data *)data;
-+      struct spi_message *message = NULL;
-+      struct spi_transfer *transfer = NULL;
-+      struct spi_transfer *previous = NULL;
-+      struct chip_data *chip;
-+      unsigned long limit = 0;
++#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
++#undef MUSB_V26
 +
-+      chip = drv_data->cur_chip;
-+      message = drv_data->cur_msg;
++#ifndef MUSB_V24
++#define MUSB_V24
++#endif
 +
-+      while (message->state != DONE_STATE) {
-+              /* Handle for abort */
-+              if (message->state == ERROR_STATE)
-+                      break;
-+              transfer = drv_data->cur_transfer;
++#endif
 +
-+              /* Delay if requested at end of transfer */
-+              if (message->state == RUNNING_STATE) {
-+                      previous =
-+                          list_entry(transfer->transfer_list.prev,
-+                                     struct spi_transfer, transfer_list);
-+                      if (previous->delay_usecs)
-+                              udelay(previous->delay_usecs);
-+                      if (previous->cs_change)
-+                              drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+              } else {
-+                      /* START_STATE */
-+                      message->state = RUNNING_STATE;
-+                      drv_data->cur_chip->cs_control(SPI_CHIP_SELECT);
-+              }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#undef MUSB_V24
++#ifndef MUSB_V26
++#define MUSB_V26
++#endif
++#endif
 +
-+              /*Configuration Changing Per Transfer */
-+              drv_data->tx = (void *)transfer->tx_buf;
-+              drv_data->tx_end = drv_data->tx + drv_data->cur_transfer->len;
-+              drv_data->rx = (void *)transfer->rx_buf;
-+              drv_data->rx_end = drv_data->rx + drv_data->cur_transfer->len;
-+              
-+              if(drv_data->master->bus_num == SSP_CONTROLLER){
-+                      drv_data->write = drv_data->tx ? drv_data->cur_chip->write : ssp_null_writer;
-+                      drv_data->read =  drv_data->rx ? drv_data->cur_chip->read : ssp_null_reader;
-+              }
-+              else{
-+                      drv_data->write = drv_data->tx ? drv_data->cur_chip->write : msp_null_writer;
-+                      drv_data->read =  drv_data->rx ? drv_data->cur_chip->read : msp_null_reader;
-+              }
++#ifdef MUSB_V26
 +
-+              drv_data->execute_cmd(drv_data, FLUSH_FIFO);
-+              drv_data->execute_cmd(drv_data, ENABLE_CONTROLLER);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
++#ifndef MUSB_V26_POST10
++#define MUSB_V26_POST10
++#endif
++#endif
 +
-+              nmdk_dbg(":::: POLLING TRANSFER ONGOING ... \n");
-+              while (drv_data->tx < drv_data->tx_end) {
-+                      drv_data->read(drv_data);
-+                      drv_data->write(drv_data);
-+              }
-+                      
-+              limit = loops_per_jiffy << 1;
-+              
-+              while ((drv_data->rx < drv_data->rx_end) && (limit--)){
-+                      drv_data->read(drv_data);
-+              }
 +
-+              /* Update total byte transfered */
-+              message->actual_length += drv_data->cur_transfer->len;
-+              if (drv_data->cur_transfer->cs_change)
-+                      drv_data->cur_chip->cs_control(SPI_CHIP_DESELECT);
-+              drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+              
-+              /* Move to next transfer */
-+              message->state = next_transfer(drv_data);
-+      }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
++#ifndef MUSB_USE_HCD_DRIVER
++#define MUSB_USE_HCD_DRIVER
++#endif
++#endif
 +
-+      /* Handle end of message */
-+      if (message->state == DONE_STATE)
-+              message->status = 0;
-+      else
-+              message->status = -EIO;
++#endif
 +
-+      giveback(message, drv_data);
-+      return;
-+}
-+/**
-+ * pump_messages - Workqueue function which processes spi message queue
-+ * @data: pointer to private data of spi driver
-+ *
-+ * This function checks if there is any spi message in the queue that
-+ * needs processing and delegate control to appropriate function
-+ * do_polling_transfer()/do_interrupt_transfer()/do_dma_transfer()
-+ * based on the kind of the transfer
-+ *
-+ */
-+static void pump_messages(struct work_struct *work)
-+{
-+      struct driver_data *drv_data = container_of(work, struct driver_data,spi_work);
-+      unsigned long flags;
 +
-+      /* Lock queue and check for queue work */
-+      spin_lock_irqsave(&drv_data->lock, flags);
-+      if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
-+              nmdk_dbg(":::: work_queue: Queue Empty\n");
-+              drv_data->busy = 0;
-+              spin_unlock_irqrestore(&drv_data->lock, flags);
-+              return;
-+      }
-+      /* Make sure we are not already running a message */
-+      if (drv_data->cur_msg) {
-+              spin_unlock_irqrestore(&drv_data->lock, flags);
-+              return;
-+      }
++/*********************************** WEIRDNESS ******************************/
 +
-+      /* Extract head of queue */
-+      drv_data->cur_msg =
-+          list_entry(drv_data->queue.next, struct spi_message, queue);
++#ifdef MUSB_V26_POST10
++#define MUSB_MEMFLAG_TYPE     unsigned int
++#else
++#define MUSB_MEMFLAG_TYPE     int
++#endif
 +
-+      list_del_init(&drv_data->cur_msg->queue);
-+      drv_data->busy = 1;
-+      spin_unlock_irqrestore(&drv_data->lock, flags);
++/****************************** SYSTEM PROPERTIES ***************************/
 +
-+      /* Initial message state */
-+      drv_data->cur_msg->state = START_STATE;
-+      drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
-+                                          struct spi_transfer, transfer_list);
++#if defined(MUSB_V26) || defined(MUSB_V24)
++#define MUSB_HAS_BUSNAME
++#endif
 +
-+      /* Setup the SPI using the per chip configuration */
-+      drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
-+      drv_data->execute_cmd(drv_data, RESTORE_STATE);
-+      drv_data->execute_cmd(drv_data, FLUSH_FIFO);
++#ifndef MUSB_LINUX_MV21
++#define HAS_USB_TT_MULTI
++#endif
 +
-+      if (drv_data->cur_chip->xfer_type == POLLING_TRANSFER)
-+              do_polling_transfer(drv_data);
-+      else if (drv_data->cur_chip->xfer_type == INTERRUPT_TRANSFER)
-+              do_interrupt_transfer(drv_data);
-+      else /* DMA_TRANSFER*/
-+              do_dma_transfer(drv_data);
-+}
++#ifdef CONFIG_PREEMPT
++/* warning??? */
++#endif
 +
-+int init_queue(struct driver_data *drv_data)
-+{
-+      INIT_LIST_HEAD(&drv_data->queue);
-+      spin_lock_init(&drv_data->lock);
++/* gstorage is liked to the driver: the init code lives there */
++#ifdef MUSB_GSTORAGE
++#define MUSB_SKIP_INIT
++#endif
 +
-+      drv_data->run = QUEUE_STOPPED;
-+      drv_data->busy = 0;
++/* When compiled in the kernel, the init function is needed only when gadget
++ * gadget API is not compiled (usb_register_driver takes care of the init)
++ */
++#if defined(MUSB_BUILTIN) && !defined(MUSB_GADGET)
++#ifndef MUSB_SKIP_INIT
++#define MUSB_SKIP_INIT
++#endif
++#endif
 +
-+      tasklet_init(&drv_data->pump_transfers, pump_transfers,
-+                   (unsigned long)drv_data);
-+      INIT_WORK(&drv_data->spi_work, pump_messages);
-+#ifdef SPI_WORKQUEUE
-+      drv_data->workqueue = create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id);
-+      if (drv_data->workqueue == NULL)
-+            return -EBUSY;
-+#endif        
-+      return 0;
-+}
-+EXPORT_SYMBOL(init_queue);
++/* -------------------------------- OTG ----------------------------- */
 +
-+int start_queue(struct driver_data *drv_data)
-+{
-+      unsigned long flags;
-+      spin_lock_irqsave(&drv_data->lock, flags);
-+      if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
-+              spin_unlock_irqrestore(&drv_data->lock, flags);
-+              return -EBUSY;
-+      }
-+      drv_data->run = QUEUE_RUNNING;
-+      drv_data->cur_msg = NULL;
-+      drv_data->cur_transfer = NULL;
-+      drv_data->cur_chip = NULL;
-+      spin_unlock_irqrestore(&drv_data->lock, flags);
-+      /*queue_work(drv_data->workqueue, &drv_data->pump_messages);*/
-+      /*schedule_work(&drv_data->spi_work);*/
-+      return 0;
-+}
-+EXPORT_SYMBOL(start_queue);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
++#define MUSB_HAS_OTG
++#define HAS_HNP_SUPPORT
++#endif
 +
-+int stop_queue(struct driver_data *drv_data)
-+{
-+      unsigned long flags;
-+      unsigned limit = 500;
-+      int status = 0;
++/* -------------------------------- DMA ----------------------------- */
 +
-+      spin_lock_irqsave(&drv_data->lock, flags);
++#define       DMA_ADDR_INVALID        (~(dma_addr_t)0)
 +
-+      /* This is a bit lame, but is optimized for the common execution path.
-+       * A wait_queue on the drv_data->busy could be used, but then the common
-+       * execution path (pump_messages) would be required to call wake_up or
-+       * friends on every SPI message. Do this instead */
-+      drv_data->run = QUEUE_STOPPED;
-+      while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
-+              spin_unlock_irqrestore(&drv_data->lock, flags);
-+              msleep(10);
-+              spin_lock_irqsave(&drv_data->lock, flags);
-+      }
-+      if (!list_empty(&drv_data->queue) || drv_data->busy)
-+              status = -EBUSY;
++/* MVL21 doesn't support DMA */
++#if defined(MUSB_LINUX_MV21)
++#ifdef MUSB_DMA
++#error "DMA Mode not supported in MontaVista 2.1"
++#endif
 +
-+      spin_unlock_irqrestore(&drv_data->lock, flags);
++/* DMA supported from 2.4 'till 2.6.10 */
++#elif defined(MUSB_V24) || (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
++#ifndef MUSB_HAS_DMA_URBS
++#define MUSB_HAS_DMA_URBS
++#endif
 +
-+      return status;
-+}
-+EXPORT_SYMBOL(stop_queue);
++/* DMA not supported on versions >= 2.6.10 */
++#elif ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) )
 +
-+int destroy_queue(struct driver_data *drv_data)
-+{
-+      int status;
-+      status = stop_queue(drv_data);
-+      if (status != 0)
-+              return status;
-+#ifdef SPI_WORKQUEUE  
-+      destroy_workqueue(drv_data->workqueue);
-+#endif        
-+      return 0;
-+}
-+EXPORT_SYMBOL(destroy_queue);
++#ifdef MUSB_DMA
++#error "DMA Mode MIGHT not be supported in kernels > 2.6.10"
++#endif
 +
-+/**
-+ * nomadik_spi_transfer - transfer function registered to SPI master framework
-+ * @spi: spi device which is requesting transfer
-+ * @msg: spi message which is to handled is queued to driver queue
++#endif
++
++/* -------------------------------- GADGETS ----------------------------- */
++#endif
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_debug.c
+@@ -0,0 +1,190 @@
++/*
++ * linux/drivers/usb/nomadik/musb_debug.c
 + *
-+ * This function is registered to the SPI framework for this SPI master 
-+ * controller. It will queue the spi_message in the queue of driver if
-+ * the queue is not stopped and return.
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
 + */
-+int nomadik_spi_transfer(struct spi_device *spi, struct spi_message *msg)
-+{
-+      struct driver_data *drv_data = spi_master_get_devdata(spi->master);
-+      unsigned long flags;
 +
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+      struct spi_master *master;
-+      int status = 0; 
-+#endif
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/completion.h>
++#include <linux/interrupt.h>
 +
-+      nmdk_dbg_ftrace();
++#include <linux/usb.h>
 +
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+      master = drv_data->master;
-+      switch(master->bus_num) {
-+              case MSP_0_CONTROLLER: if(drv_data->flag_msp0->user != SPI_USER_MSP) {
-+                              status = -EINVAL;
-+                              printk("MSP0 already in use in %d mode", drv_data->flag_msp0->user);
-+                      }
-+                      break;
-+              case MSP_1_CONTROLLER: if(drv_data->flag_msp1->user != SPI_USER_MSP) {
-+                              status = -EINVAL;
-+                              printk("MSP1 already in use in %d mode", drv_data->flag_msp1->user);
-+                      }
-+                      break;
-+              case MSP_2_CONTROLLER: if(drv_data->flag_msp2->user != SPI_USER_MSP) {
-+                              status = -EINVAL;
-+                              printk("MSP2 already in use in %d mode", drv_data->flag_msp2->user);
-+                      }
-+                      break;
-+      }
-+      if(status)
-+              return status;
-+#endif
-+      spin_lock_irqsave(&drv_data->lock, flags);
++#include "debug.h"
++#include "musbdefs.h"
 +
-+      
-+      if (drv_data->run == QUEUE_STOPPED) {
-+              spin_unlock_irqrestore(&drv_data->lock, flags);
-+              return -ESHUTDOWN;
-+      }
-+      if(drv_data->dma_ongoing){
-+              struct chip_data *chip;
-+              chip = spi_get_ctldata(spi);
-+              nmdk_dbg(":::: Current chip(%p), Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip, chip->chip_id);        
-+              nmdk_dbg(":::: Current chip Id (doing infinite DMA): %d -- Chip Id Requesting New Xfer: %d\n", drv_data->cur_chip->chip_id, chip->chip_id);     
-+              if(drv_data->cur_chip->chip_id != chip->chip_id){
-+                      nmdk_dbg(":::: Chip_id are not same, Hence current DMA xfer not disabled \n");
-+              }
-+              else{   
-+                      nmdk_dbg(":::: Chip_id are same. Disabling current infinite DMA xfer\n");
-+                      
-+                      drv_data->dma_ongoing = 0;
-+                      
-+                      if (drv_data->cur_chip->dma_info->tx_dmach != -1) {
-+                              free_dma(drv_data->cur_chip->dma_info->tx_dmach);
-+                              drv_data->cur_chip->dma_info->tx_dmach = -1;
-+                      }
-+                      if (drv_data->cur_chip->dma_info->rx_dmach != -1) {
-+                              free_dma(drv_data->cur_chip->dma_info->rx_dmach);
-+                              drv_data->cur_chip->dma_info->rx_dmach = -1;
-+                      }
-+                      drv_data->execute_cmd(drv_data, DISABLE_DMA);
-+                      drv_data->execute_cmd(drv_data, DISABLE_CONTROLLER);
-+                      drv_data->cur_msg = NULL;
-+                      drv_data->cur_transfer = NULL;
-+                      drv_data->cur_chip = NULL;
-+#ifdef SPI_WORKQUEUE          
-+                      queue_work(drv_data->workqueue, &drv_data->spi_work);
-+#else         
-+                      schedule_work(&drv_data->spi_work);
-+#endif        
-+              }
-+              spin_unlock_irqrestore(&drv_data->lock, flags);
-+              return 0;
-+      }
-+      
-+      nmdk_dbg(":::: Regular request (No infinite DMA ongoing)\n");
-+      
-+      msg->actual_length = 0;
-+      msg->status = -EINPROGRESS;
-+      msg->state = START_STATE;
++#define IPRINTF(_f, _m)       printk(KERN_INFO "%s"_f, indent, _m)
++#define isspace(c)    (c==' ' || c=='\t')
++#define LABEL KERN_INFO "dump: "
 +
-+      list_add_tail(&msg->queue, &drv_data->queue);
-+      if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
-+#ifdef SPI_WORKQUEUE          
-+              queue_work(drv_data->workqueue, &drv_data->spi_work);
-+#else         
-+              schedule_work(&drv_data->spi_work);
-+#endif        
++/******************************************************************/
 +
-+      spin_unlock_irqrestore(&drv_data->lock, flags);
-+      return 0;
++int MGC_DebugLevel=MUSB_DEBUG;
++int MGC_DebugDisable=0;
++
++/******************************************************************/
++
++/* Decode CSR0 value to a string. Not reentrant
++ */
++char *decode_csr0(uint16_t csr0) {
++    static char buf[64];
++    sprintf(buf, "(%s%s%s%s)",
++          csr0&MGC_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"",
++          csr0&MGC_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"",
++          csr0&MGC_M_CSR0_P_SENDSTALL ? "[stalled]":"",
++          csr0&MGC_M_CSR0_P_DATAEND ? "[dataend]":"");
++    return buf;
 +}
-+EXPORT_SYMBOL(nomadik_spi_transfer);
 +
-+int calculate_effective_freq(int freq, t_ssp_clock_params * clk_freq)
-+{
-+      /*Lets calculate the frequency parameters */
-+      uint32 cpsdvsr = 2;
-+      uint32 scr = 0;
-+      bool_t freq_found = FALSE;
-+      uint32 max_tclk;
-+      uint32 min_tclk;
-+      
-+      nmdk_dbg_ftrace();
++/* Decode a value to binary.
++ */
++char *decode_bits(uint16_t value) {
++    int i=0;
++    static char buf[64];
 +
-+      max_tclk = (NMDK_SSP_CLOCK_FREQ / (MIN_CPSDVR * (1 + MIN_SCR)));        /* cpsdvscr = 2 & scr 0 */
-+      min_tclk = (NMDK_SSP_CLOCK_FREQ / (MAX_CPSDVR * (1 + MAX_SCR)));        /* cpsdvsr = 254 & scr = 255 */
++    for (; i<16;i++) {
++      buf[15-i]=(value&(1<<i))?'1':'0';
++    }
 +
-+      if ((freq <= max_tclk) && (freq >= min_tclk)) {
-+              while (cpsdvsr <= MAX_CPSDVR && !freq_found) {
-+                      while (scr <= MAX_SCR && !freq_found) {
-+                              if ((NMDK_SSP_CLOCK_FREQ /
-+                                   (cpsdvsr * (1 + scr))) > freq)
-+                                      scr += 1;
-+                              else {
-+                                      /* This bool is made TRUE when effective frequency >= target frequency is found */
-+                                      freq_found = TRUE;
-+                                      if ((NMDK_SSP_CLOCK_FREQ /
-+                                           (cpsdvsr * (1 + scr))) != freq) {
-+                                              if (scr == MIN_SCR) {
-+                                                      cpsdvsr -= 2;
-+                                                      scr = MAX_SCR;
-+                                              } else
-+                                                      scr -= 1;
-+                                      }
-+                              }
-+                      }
-+                      if (!freq_found) {
-+                              cpsdvsr += 2;
-+                              scr = MIN_SCR;
-+                      }
-+              }
-+              if (cpsdvsr != 0) {
-+                      nmdk_dbg(":::: SSP Effective Frequency is %ld\n",    (NMDK_SSP_CLOCK_FREQ / (cpsdvsr * (1 + scr))));
-+                      clk_freq->cpsdvsr = (uint8) (cpsdvsr & 0xFF);
-+                      clk_freq->scr = (uint8) (scr & 0xFF);
-+                      nmdk_dbg(":::: SSP cpsdvsr = %d, scr = %d\n",
-+                          clk_freq->cpsdvsr, clk_freq->scr);
-+              }
-+      } else {
-+              /*User is asking for out of range Freq. */
-+              nmdk_dbg(":::: setup - controller data is incorrect: Out of Range Frequency");
-+              return -EINVAL;
-+      }
-+      return 0;
++    return buf;
 +}
-+EXPORT_SYMBOL(calculate_effective_freq);
 +
-+/**
-+ * process_dma_info - Processes the DMA info provided by client drivers
-+ * @chip_info: chip info provided by client device
-+ * @chip: Runtime state maintained by the spi controller for each spi device
-+ *
-+ * This function processes and stores DMA config provided by client driver
-+ * into the runtime state maintained by the spi controller driver
++/* Decode TXCSR register.
 + */
-+int process_dma_info(struct nmdk_spi_config_chip *chip_info,
-+                          struct chip_data *chip, void * data)
-+{
-+      struct driver_data *drv_data = (struct driver_data *)data;
++char *decode_txcsr(uint16_t txcsr) {
++    static char buf[256];
++    sprintf(buf, "%s (%s%s%s%s)",
++          decode_bits(txcsr),
++          txcsr&MGC_M_TXCSR_TXPKTRDY ? "[TXPKTRDY]":"",
++          txcsr&MGC_M_TXCSR_AUTOSET ? "[MGC_M_TXCSR_AUTOSET]":"",
++          txcsr&MGC_M_TXCSR_DMAENAB ? "[MGC_M_TXCSR_DMAENAB]":"",
++          txcsr&MGC_M_TXCSR_DMAMODE ? "[MGC_M_TXCSR_DMAMODE]":"");
++    return buf;
++}
 +
-+      /* default setup required for any SPI dma transfer*/
-+        chip->dma_info->rx_dma_info.srcdevtype = drv_data->master_info->dma_srcdevtype;
-+      chip->dma_info->rx_dma_info.config = 0;
++/*
++ */
++char *decode_devctl(uint16_t devctl) {
++    return (devctl&MGC_M_DEVCTL_HM)?"host":"function";
++}
 +
-+      chip->dma_info->tx_dma_info.destdevtype = drv_data->master_info->dma_destdevtype;
-+      chip->dma_info->tx_dma_info.config = 0;
-+      
-+      if (chip_info->dma_xfer_type == SPI_WITH_MEM) {
-+              chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_MEM);
-+              chip->dma_info->rx_dma_info.destdevtype = "mem";
-+                
-+              chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(MEM_TO_PERIPH);
-+              chip->dma_info->tx_dma_info.srcdevtype = "mem";
-+              if (chip_info->dma_config) {
-+                      chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+                      chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+                      if (chip_info->dma_config->tx_client_dmadev_config) {
-+                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
-+                      }
-+                      if (chip_info->dma_config->rx_client_dmadev_config) {
-+                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
-+                      }
-+                      if (chip_info->dma_config->tx_master_dmadev_config) {
-+                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
-+                      }
-+                      if (chip_info->dma_config->rx_master_dmadev_config) {
-+                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
-+                      }
-+              }
-+      } else { /*SPI_WITH_PERIPH*/
-+              chip->dma_info->rx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
-+                chip->dma_info->tx_dma_info.mode = FLOW_CNTRL_DMA(PERIPH_TO_PERIPH);
-+              if (chip_info->dma_config) {
-+                      chip->dma_info->rx_dma_info.mode |= chip_info->dma_config->tx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+                      chip->dma_info->tx_dma_info.mode |= chip_info->dma_config->rx_dma_mode & ~(FLOW_CNTRL_DEST_PERIPH(PERIPH_TO_PERIPH));
-+                      if (chip_info->dma_config->tx_client_dmadev_config) {
-+                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->tx_client_dmadev_config->config);
-+                              chip->dma_info->rx_dma_info.destdevtype = chip_info->dma_config->tx_client_dmadev_config->devtype;              
-+                      }
-+                      if (chip_info->dma_config->rx_client_dmadev_config) {
-+                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_DEST(chip_info->dma_config->rx_client_dmadev_config->config);
-+                              chip->dma_info->tx_dma_info.srcdevtype = chip_info->dma_config->rx_client_dmadev_config->devtype;               
-+                      }
-+                      if (chip_info->dma_config->tx_master_dmadev_config) {
-+                              chip->dma_info->rx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->tx_master_dmadev_config->config);
-+                      }
-+                      if (chip_info->dma_config->rx_master_dmadev_config) {
-+                              chip->dma_info->tx_dma_info.config |= DMA_DEVCONFIG_SRC(chip_info->dma_config->rx_master_dmadev_config->config);
-+                      }
-+              } else return -EINVAL;
-+      }
 +
-+      print_dma_info(chip_info->dma_xfer_type, chip);
-+      return 0;
++/*
++ */
++char *decode_ep0stage(uint8_t stage) {
++    static char buff[64];
++    uint8_t stallbit=stage&MGC_END0_STAGE_STALL_BIT;
++
++    stage=stage&~stage&MGC_END0_STAGE_STALL_BIT;
++    sprintf(buff, "%s%s", (stallbit)? "stall-" : "",
++      (stage==MGC_END0_STAGE_SETUP)
++      ? "setup" :
++      (stage==MGC_END0_STAGE_TX)
++      ? "tx" :
++      (stage==MGC_END0_STAGE_RX)
++      ? "rx" :
++      (stage==MGC_END0_STAGE_STATUSIN)
++      ? "statusin" :
++      (stage==MGC_END0_STAGE_STATUSOUT)
++      ? "statusout" : "error");
++    return buff;
 +}
 +
-+EXPORT_SYMBOL(process_dma_info);
 +
-+/**
-+ * nomadik_spi_cleanup - cleanup function registered to SPI master framework
-+ * @spi: spi device which is requesting cleanup
-+ *
-+ * This function is registered to the SPI framework for this SPI master 
-+ * controller. It will free the runtime state of chip.
++/*
 + */
-+void nomadik_spi_cleanup(const struct spi_device *spi)
++void dump_urb (void *pUrb)
 +{
-+      struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
-+      struct driver_data *drv_data = spi_master_get_devdata(spi->master);
-+      struct spi_master *master;
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+      int status =0;
++      struct urb* purb=(struct urb*)pUrb;
++
++      printk (LABEL "urb                   :%p\n", purb);
++      printk (LABEL "urb_list                          :%s\n", dump_node(&purb->urb_list));
++#ifdef V24
++      printk (LABEL "next                  :%p\n", purb->next);
 +#endif
-+      nmdk_dbg_ftrace();
++      printk (LABEL "dev                   :%p\n", purb->dev);
++      printk (LABEL "pipe                  :%08X\n", purb->pipe);
++      printk (LABEL "status                :%d\n", purb->status);
++      printk (LABEL "transfer_flags        :%08X\n", purb->transfer_flags);
++      printk (LABEL "transfer_buffer       :%p\n", purb->transfer_buffer);
++      printk (LABEL "transfer_buffer_length:%d\n", purb->transfer_buffer_length);
++      printk (LABEL "actual_length         :%d\n", purb->actual_length);
++      printk (LABEL "setup_packet          :%p\n", purb->setup_packet);
++      printk (LABEL "start_frame           :%d\n", purb->start_frame);
++      printk (LABEL "number_of_packets     :%d\n", purb->number_of_packets);
++      printk (LABEL "interval              :%d\n", purb->interval);
++      printk (LABEL "error_count           :%d\n", purb->error_count);
++      printk (LABEL "context               :%p\n", purb->context);
++      printk (LABEL "complete              :%p\n", purb->complete);
++}
 +
-+      master = drv_data->master;
++/**
++ * Dump core registers whose reads are non-destructive.
++ * @param pThis
++ * @param bEnd
++ */
++void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd)
++{
++    MGC_SelectEnd(pBase, bEnd);
 +
-+#if (defined(CONFIG_NOMADIK_MSP) || defined(CONFIG_NOMADIK_MSP_MODULE))
-+      switch(master->bus_num) {
-+              case MSP_0_CONTROLLER:  if(drv_data->flag_msp0->user == SPI_USER_MSP) {
-+                                              down(&drv_data->flag_msp0->lock);
-+                                              drv_data->flag_msp0->user = SPI_NO_MSP_USER;
-+                                              up(&drv_data->flag_msp0->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP0\n");
-+                                      }
-+                                      else {
-+                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", (drv_data->flag_msp0->user));
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+              case MSP_1_CONTROLLER:  if(drv_data->flag_msp1->user == SPI_USER_MSP) {
-+                                              down(&drv_data->flag_msp1->lock);
-+                                              drv_data->flag_msp1->user = SPI_NO_MSP_USER;
-+                                              up(&drv_data->flag_msp1->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP1\n");
-+                                      }
-+                                      else {
-+                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp1->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+              case MSP_2_CONTROLLER:  if(drv_data->flag_msp2->user == SPI_USER_MSP) {
-+                                              down(&drv_data->flag_msp2->lock);
-+                                              drv_data->flag_msp2->user = SPI_NO_MSP_USER;
-+                                              up(&drv_data->flag_msp2->lock);
-+                                              nmdk_dbg("Flag cleanup for MSP2\n");
-+                                      }
-+                                      else {
-+                                              printk("Error in nomadik_spi_cleanup Trying to free MSP from SPI-mode , already configured in mode%d\n", drv_data->flag_msp2->user);
-+                                              status = -EFAULT;
-+                                      }
-+                                      break;
-+      }
-+      if(status)
-+              return ;
-+#endif
-+      if((master->bus_num == MSP_0_CONTROLLER) ||(master->bus_num == MSP_1_CONTROLLER) || (master->bus_num == MSP_2_CONTROLLER)) {
-+              nomadik_gpio_altfuncdisable(drv_data->master_info->gpio_alt_func, drv_data->master_info->device_name);
-+              free_irq(drv_data->adev->irq[0], drv_data);
-+      }
-+        if (chip){
-+                if(chip->dma_info) {
-+                        if (chip->dma_info->tx_dmach != -1) {
-+                                free_dma(chip->dma_info->tx_dmach);
-+                                chip->dma_info->tx_dmach = -1;
-+                        }
-+                        if (chip->dma_info->rx_dmach != -1) {
-+                                free_dma(chip->dma_info->rx_dmach);
-+                                chip->dma_info->rx_dmach = -1;
-+                        }
-+                        kfree(chip->dma_info);
-+                }
-+                kfree(chip);
-+        }
++    if(!bEnd) {
++              printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n",
++             MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_TYPE0, 0),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0));
++    } else {
++              printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n",
++             bEnd,
++             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
++             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd));
++              printk(KERN_INFO "    RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n",
++             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
++             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
++             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd),
++             MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd));
++    }
++
++    if( multipoint) {
++              printk(KERN_INFO "    TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n",
++                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR)),
++                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR)),
++                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT)));
++              printk(KERN_INFO "    RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n",
++                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR)),
++                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR)),
++                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT)));
++    }
 +}
-+EXPORT_SYMBOL(nomadik_spi_cleanup);
 +
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Sachin Verma <sachin.verma@st.com> : Vaibhav Agarwal <vaibhav.agarwal@st.com");
-+MODULE_DESCRIPTION("Nomadik SPI driver");
-diff -Nauprw linux-2.6.20/drivers/usb/gadget/file_storage.c ../new/linux-2.6.20/drivers/usb/gadget/file_storage.c
---- linux-2.6.20/drivers/usb/gadget/file_storage.c     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/gadget/file_storage.c      2008-08-08 19:15:19.000000000 +0530
-@@ -272,12 +272,11 @@ MODULE_DESCRIPTION(DRIVER_DESC);
- MODULE_AUTHOR("Alan Stern");
- MODULE_LICENSE("Dual BSD/GPL");
--/* Thanks to NetChip Technologies for donating this product ID.
-- *
-- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
-- * Instead:  allocate your own, using normal USB-IF procedures. */
--#define DRIVER_VENDOR_ID      0x0525  // NetChip
--#define DRIVER_PRODUCT_ID     0xa4a5  // Linux-USB File-backed Storage Gadget
++
++/* list related */
++
 +/*
-+ * Replaced with ST ID
++ * NOT REENTRANT!
 + */
-+#define DRIVER_VENDOR_ID      0x0483  // ST ID
-+#define DRIVER_PRODUCT_ID     0x8815  // 0xa4a5 Linux-USB File-backed Storage Gadget
- /*
-@@ -373,7 +372,7 @@ static struct {
-       .transport_parm         = "BBB",
-       .protocol_parm          = "SCSI",
-       .removable              = 0,
--      .can_stall              = 1,
-+      .can_stall              = 0, /* for nhk15 */ 
-       .vendor                 = DRIVER_VENDOR_ID,
-       .product                = DRIVER_PRODUCT_ID,
-       .release                = 0xffff,       // Use controller chip type
-@@ -3860,7 +3859,7 @@ static int __init fsg_bind(struct usb_ga
-               goto out;
-       if (mod_data.removable) {       // Enable the store_xxx attributes
--              dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
-+              dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0777; /*NHK15*/
-               dev_attr_ro.store = store_ro;
-               dev_attr_file.store = store_file;
-       }
-diff -Nauprw linux-2.6.20/drivers/usb/Kconfig ../new/linux-2.6.20/drivers/usb/Kconfig
---- linux-2.6.20/drivers/usb/Kconfig   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/Kconfig    2008-07-04 23:45:22.000000000 +0530
-@@ -133,5 +133,7 @@ source "drivers/usb/atm/Kconfig"
- source "drivers/usb/gadget/Kconfig"
-+source "drivers/usb/nomadik/Kconfig"
++char *dump_node(struct list_head *node) {
++    static char buf[64];
++    sprintf(buf, "[n=%p,p=%p]", node->next, node->prev);
++    return buf;
++}
 +
- endmenu
-diff -Nauprw linux-2.6.20/drivers/usb/Makefile ../new/linux-2.6.20/drivers/usb/Makefile
---- linux-2.6.20/drivers/usb/Makefile  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/Makefile   2008-07-04 23:45:23.000000000 +0530
-@@ -67,6 +67,7 @@ obj-$(CONFIG_USB_SISUSBVGA)  += misc/
- obj-$(CONFIG_USB_TEST)                += misc/
- obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/
- obj-$(CONFIG_USB_USS720)      += misc/
-+obj-y                         += nomadik/
- obj-$(CONFIG_USB_ATM)         += atm/
- obj-$(CONFIG_USB_SPEEDTOUCH)  += atm/
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/board.h ../new/linux-2.6.20/drivers/usb/nomadik/board.h
---- linux-2.6.20/drivers/usb/nomadik/board.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/board.h    2008-07-28 15:20:49.000000000 +0530
-@@ -0,0 +1,58 @@
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h
+@@ -0,0 +1,48 @@
 +/*
-+ * linux/drivers/usb/nomadik/board.h
++ * linux/drivers/usb/nomadik/musb_epdescriptors.h
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -190569,53 +194051,42 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/board.h ../new/linux-2.6.20/driver
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
++struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] = {
 +
-+/*
-+ * Example board-specific definitions.
-+ * $Revision: 1.6 $
-+ *
-+ * It is suggested to:
-+ * 1. Copy this file to one named after your target: 
-+ *    cp board.h board-mytarget.h
-+ * 2. Save this file for future reference: 
-+ *    mv board.h board-example.h
-+ * 3. Link board.h to yours: 
-+ *    ln -s board-mytarget.h board.h
-+ * 4. Edit yours, providing, for each controller:
-+ *    - controller type (MUSB_CONTROLLER_HDRC or MUSB_CONTROLLER_MHDRC)
-+ *    - physical base address in kernel space
-+ *    - interrupt number (interpretation is platform-specific)
-+ */
++{}, /* EP0 use the default */
++{ MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
++{ MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 },
++{ MUSB_EPD_T_INTR, MUSB_EPD_D_RX, 512 }
++};
 +
-+/** Array of information about hard-wired controllers
-+ * This will be liked to the first module that includes this file.
-+ */
++/**
++struct MGC_EpFifoDescriptor {
++    uint8_t bType;    0 for autoconfig, CNTR, ISOC, BULK, INTR
++    uint8_t bDir;     0 for autoconfig, INOUT, IN, OUT
++    uint16_t wSize;           0 for autoconfig, or the size
++      uint 8_t bDbe;  double buffering  0 disabled, 1 enabled
++};
 +
-+#ifndef __MUSB_LINUX_BOARD_H__
-+#define __MUSB_LINUX_BOARD_H__
-+#include <asm/arch/soc_devices.h>
++#define MUSB_EPD_AUTOCONFIG   0
 +
-+#include <asm/arch/irqs.h>
-+#define INT_USBOTG IRQ_USBOTG
++#define MUSB_EPD_T_CNTRL      1
++#define MUSB_EPD_T_ISOC               2
++#define MUSB_EPD_T_BULK               3
++#define MUSB_EPD_T_INTR               4
 +
-+MUSB_LinuxController MUSB_aLinuxController[] =
-+{
-+    { MUSB_CONTROLLER_HDRC, (void*)NOMADIK_USB_BASE, INT_USBOTG }
-+   /*
-+    { MUSB_CONTROLLER_HDRC, (void*)0xc0000000, 9 }
-+    */
-+};
++#define MUSB_EPD_D_INOUT      0
++#define MUSB_EPD_D_TX         1
++#define MUSB_EPD_D_RX         2
++*/
 +
-+#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/debug.h ../new/linux-2.6.20/drivers/usb/nomadik/debug.h
---- linux-2.6.20/drivers/usb/nomadik/debug.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/debug.h    2008-07-28 15:20:49.000000000 +0530
-@@ -0,0 +1,104 @@
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c
+@@ -0,0 +1,429 @@
 +/*
-+ * linux/drivers/usb/nomadik/debug.h
++ * linux/drivers/usb/nomadik/musb_epfifocfg.c
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -190631,411 +194102,423 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/debug.h ../new/linux-2.6.20/driver
 + *
 + * 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 __MUSB_LINUX_DEBUG_H__
-+#define __MUSB_LINUX_DEBUG_H__
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++  */
 +
-+/*
-+ * Linux HCD (Host Controller Driver) for HDRC and/or MHDRC.
-+ * Debug support routines
++#include "musbdefs.h"
++#include "musb_epdescriptors.h"
++
++#ifdef MUSB_EPFIFOCONFIG_FILE
++#include CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
++#endif
++
++#define DYN_FIFO_SIZE (1<<(MUSB_C_RAM_BITS+2))
++#define CONFIGURE_FIFO(_pThis, _pEnd, _Dsc, _wFifoOffset) \
++      configure_fifo(_pThis, _pEnd, (_Dsc)->bDir, (_Dsc)->wSize, (_Dsc)->bDbe, _wFifoOffset)
++
++
++/* force array based */
++#ifdef MUSB_C_DYNFIFO_DEF
++
++#ifdef MUSB_EPDISCRIPTORS_FILE
++/**
++ * configure the fifo and make sure the pThis endmask is updated.
 + *
++ * @param pThis
++ * @param pEnd the end to configure
++ * @param bDir the direction (in, out, inout)
++ * @param wSize the fifo size, real fifo size
++ * @param bDbe double buffering enabled?
++ * @param wFifoOffset the current offset
++ */
++static uint16_t configure_fifo(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd,
++      uint8_t bDir, uint16_t wSize, uint8_t bDbe, uint16_t wFifoOffset)
++{
++      uint16_t offset=wSize;
++    void* pBase = pThis->pRegs;
++      uint8_t szValue=wSize>>3;
++      uint16_t addValue=wFifoOffset>>3;
++
++      /* when double buffering is enabled endpoint needs twice the size */
++      if (bDbe) {
++              szValue |= (1<<4);
++              offset*=2;
++      }
++
++      /* configure the FIFO */
++      MGC_SelectEnd(pBase, pEnd->bEnd);
++      switch ( bDir ) {
++              case MUSB_EPD_D_TX:
++                      MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 0x6);
++                      MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 64 >> 3);
++
++                      pEnd->wMaxPacketSizeTx = wSize;
++                      pEnd->wMaxPacketSizeRx = 0;
++                      pEnd->bIsSharedFifo = FALSE;
++              break;
++              case MUSB_EPD_D_RX:
++                      MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 0x6);
++                      MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, (64 + 512 ) >> 3);
++
++                      pEnd->wMaxPacketSizeTx = 0;
++                      pEnd->wMaxPacketSizeRx = wSize;
++                      pEnd->bIsSharedFifo = FALSE;
++              break;
++              case MUSB_EPD_D_INOUT:
++                      MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, szValue);
++                      MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, addValue);
++
++                      MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, szValue);
++                      MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, addValue);
++
++                      pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=wSize;
++                      pEnd->bIsSharedFifo = TRUE;
++              break;
++
++              default:
++                      ERR("direction %d not supported\n", bDir);
++                      offset=0;
++              break;
++      }
++
++      /* make sure the endmask is right */
++      if ( offset ) {
++              pThis->wEndMask |= (1 << pEnd->bEnd);
++      }
++
++      /* TODO: flush the FIFO after an ep size change */
++
++
++      return offset;
++}
++
++/**
++ * Configure the end points for DYNAMIC FIFO: array based End point
++ * configuration.
++ * @param pThis the controller
 + */
++void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
++    uint8_t bEnd, bSkip;
++    MGC_LinuxLocalEnd* pEnd;
++    uint16_t wFifoOffset=0;
++
++      /* use the defined end points */
++      pThis->bEndCount=MUSB_C_NUM_EPS;
++
++#ifdef MUSB_PARANOID
++      if ( MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_T_CNTRL
++              && MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_AUTOCONFIG)
++      {
++              WARN("ep0 must be control with fixed size of %d\n",
++                      MGC_END0_FIFOSIZE);
++      }
++#endif
++
++      /* entry 0 is ep0, the default control endpoint */
++      for (bEnd=0; bEnd<MUSB_C_NUM_EPS; bEnd++) {
++              bSkip=0;
++              pEnd = &(pThis->aLocalEnd[bEnd]);
++              pEnd->bEnd=bEnd;
++              pEnd->bIsSharedFifo = FALSE;
++              pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=0;
++
++              switch ( MUSB_aEpFifoDescriptors[bEnd].bType ) {
++                      case MUSB_EPD_T_CNTRL:
++                              if ( bEnd ) {
++                                      bSkip=1;
++                                      WARN("Control ep when ep!=0 (ep%d); skipping\n", bEnd);
++                              }
++                      break;
++
++                      case MUSB_EPD_T_ISOC: break;
++
++                      case MUSB_EPD_T_BULK:
++                              switch ( MUSB_aEpFifoDescriptors[bEnd].bDir ) {
++                                      case MUSB_EPD_D_TX: pThis->bBulkTxEnd = bEnd; break;
++                                      case MUSB_EPD_D_RX: pThis->bBulkRxEnd = bEnd; break;
++                                      case MUSB_EPD_D_INOUT:
++                                              WARN("INOUTBULK: sharing ep%d\n", bEnd);
++                                      break;
++                                      default:
++                                              bSkip=1;
++                                              ERR("direction %d not supported for ep%d\n",
++                                                      MUSB_aEpFifoDescriptors[bEnd].bDir, bEnd);
++                                      break;
++                              }
++                      break;
 +
-+#define MUSB_MONITOR_DATA
++                      case MUSB_EPD_T_INTR: break;
++                      case MUSB_EPD_AUTOCONFIG: break;
 +
-+#define yprintk(facility, format, args...) do { printk(facility "%s %d: " format , \
-+      __FUNCTION__, __LINE__ , ## args); } while (0)  
-+#define WARN(fmt, args...) yprintk(KERN_WARNING,fmt, ## args)
-+#define INFO(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
-+#define ERR(fmt,args...) yprintk(KERN_INFO,fmt, ## args)
++                      default:
++                              bSkip=1;
++                              ERR("ep%d type %d not supported\n", bEnd,
++                                      MUSB_aEpFifoDescriptors[bEnd].bType);
++                      break;
++              }
 +
-+#if MUSB_DEBUG > 0
++              if ( !MUSB_aEpFifoDescriptors[bEnd].wSize ) {
++                      continue; /* postpone to autoconfig */
++              }
 +
-+#define STATIC
-+#define MGC_GetDebugLevel()   (MGC_DebugLevel)
-+#define MGC_EnableDebug()     do { MGC_DebugDisable=0; } while(0) 
-+#define MGC_DisableDebug()    do { MGC_DebugDisable=1; } while(0)
++              if ( !bSkip ) {
++                      uint16_t offset=CONFIGURE_FIFO(pThis, &(pThis->aLocalEnd[bEnd]),
++                              &MUSB_aEpFifoDescriptors[bEnd], wFifoOffset );
++                      if ( offset ) {
++                              wFifoOffset += offset;
++                      }
++              }
 +
-+#define _dbg_level(level)  ( !MGC_DebugDisable && ((level>=-1 && MGC_GetDebugLevel()>=level) || MGC_GetDebugLevel()==level) )
++      }
 +
-+#define xprintk(level, facility, format, args...) do { if ( _dbg_level(level) ) { \
-+    printk(facility "%s %d: " format , __FUNCTION__, __LINE__ , ## args); } } while (0)
-+      
-+#define PARANOID( x )         do {}  while (0)
-+#define DBG(level,fmt,args...) xprintk(level,KERN_INFO,fmt, ## args)
-+#define DEBUG_CODE(level, code)       do { if ( _dbg_level(level) ) { code }  } while (0)
-+#define TRACE(n) DEBUG_CODE(n, printk(KERN_INFO "%s:%s:%d: trace\n", \
-+      __FILE__, __FUNCTION__, __LINE__); )
++#ifdef MUSB_PARANOID
++      if ( wFifoOffset > 64 ) {
++              ERR("Allocated %d bytes, more than the allowed %d\n",
++                      wFifoOffset, 64);
++      } else {
++              INFO("Allocated %d bytes, out of %d\n", wFifoOffset,
++                      64);
++      }
++#endif
 +
-+#define ASSERT_SPINLOCK_LOCKED(_x) 
-+#define ASSERT_SPINLOCK_UNLOCKED(_x) 
-+/* #define ASSERT_SPINLOCK_LOCKED(_x) do { if (!spin_is_locked(_x)) \
-+      ERR("@pre clause failed, _x must be locked\n"); } while (0) 
-+#define ASSERT_SPINLOCK_UNLOCKED(_x) do { if (spin_is_locked(_x)) \
-+      ERR("@pre clause failed, _x must be unlocked\n"); } while (0) */
++}
 +
-+/* debug no defined */
++#else
++/**
++ * Configure the end points for DYNAMIC FIFO (old method).
++ * @param pThis the controller
++ */
++void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
++    uint8_t bEnd=1;
++    MGC_LinuxLocalEnd* pEnd;
++    void* pBase = pThis->pRegs;
++    uint16_t wFifoOffset=MGC_END0_FIFOSIZE;
 +
-+#else 
++    DBG(2, "<==\n");
 +
-+#define STATIC static
-+#define MGC_GetDebugLevel()   0
-+#define MGC_EnableDebug()
-+#define MGC_DisableDebug()
++      /* use the defined end points */
++      pThis->bEndCount=MUSB_C_NUM_EPS;
 +
-+#define PARANOID( x )         do {}  while (0)
-+#define DBG(fmt,args...)      do {}  while (0)
-+#define DEBUG_CODE(x, y)      do {}  while (0)
-+#define TRACE(n)              do {}  while (0)
++    /* Dynamic FIFO sizing: use pre-computed values for EP0 */
++    MGC_SelectEnd(pBase, 0);
++    MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 3);
++    MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 3);
++    MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 0);
++    MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, 0);
++      pThis->wEndMask = 1;
 +
-+#define ASSERT_SPINLOCK_LOCKED(_x) 
-+#define ASSERT_SPINLOCK_UNLOCKED(_x) 
++#if MGC_DFIFO_ISO_TX >= 0
++    MGC_SelectEnd(pBase, bEnd);
++    pEnd = &(pThis->aLocalEnd[bEnd]);
++      pEnd->bEnd=bEnd;
 +
++    /* reserve ISO Tx */
++    MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ISO_TX_VAL);
++    pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_ISO_TX_VAL & 0xf)+3+(MGC_DFIFO_ISO_TX_VAL>>4));
++    pEnd->wMaxPacketSizeRx = 0;
++    MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
++    /* move to next */
++    wFifoOffset += pEnd->wMaxPacketSizeTx;
++    pEnd->bIsSharedFifo = FALSE;
++      pThis->wEndMask |= (1 << bEnd);
++    bEnd++;
 +#endif
 +
-+/*----------------------- DEBUG function/macros -----------------------------*/
-+
-+#if MUSB_DEBUG > 0
-+struct usb_ep;
-+struct list_head;
-+struct usb_request;
-+struct usb_ctrlrequest;
++#if MGC_DFIFO_ISO_RX >= 0
++    MGC_SelectEnd(pBase, bEnd);
++    pEnd = &(pThis->aLocalEnd[bEnd]);
++      pEnd->bEnd=bEnd;
 +
-+extern int MGC_DebugLevel;
-+extern int MGC_DebugDisable;
++    /* reserve ISO Rx */
++    MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ISO_RX_VAL);
++    pEnd->wMaxPacketSizeTx = 0;
++    pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_ISO_RX_VAL & 0xf)+3+(MGC_DFIFO_ISO_RX_VAL>>4));
++    MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
 +
-+extern void dump_urb(void *urb);
-+extern char *decode_csr0(uint16_t csr0);
-+extern char *decode_txcsr(uint16_t txcsr);
-+extern char *decode_devctl(uint16_t devclt);
-+extern char *decode_ep0stage(uint8_t stage);
-+extern char *dump_node(struct list_head *node);
-+extern char *decode_usb_ctrlrequest(const struct usb_ctrlrequest *pControlRequest);
-+extern char *decode_request(struct usb_ctrlrequest*) ;
-+extern void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd);
++    /* move to next */
++    wFifoOffset += pEnd->wMaxPacketSizeRx;
++    pEnd->bIsSharedFifo = FALSE;
++      pThis->wEndMask |= (1 << bEnd);
++    bEnd++;
 +#endif
 +
-+#endif //  __MUSB_LINUX_DEBUG_H__
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/dma.h ../new/linux-2.6.20/drivers/usb/nomadik/dma.h
---- linux-2.6.20/drivers/usb/nomadik/dma.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/dma.h      2008-07-28 15:20:50.000000000 +0530
-@@ -0,0 +1,308 @@
-+/*
-+ * linux/drivers/usb/nomadik/dma.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 
-+ */
++    MGC_SelectEnd(pBase, bEnd);
++    pEnd = &(pThis->aLocalEnd[bEnd]);
++      pEnd->bEnd=bEnd;
 +
-+#ifndef __MUSB_DMA_H__
-+#define __MUSB_DMA_H__
++      /* reserve bulk */
++      pEnd->wMaxPacketSizeRx= 0;
++    pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
++    MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_BLK_VAL);
++    MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
++    pThis->bBulkTxEnd = bEnd;
++    /* move to next */
++    wFifoOffset += pEnd->wMaxPacketSizeTx;
++      pThis->wEndMask |= (1 << bEnd);
++    bEnd++;
 +
-+/**
-+ * Introduction.
-+ * The purpose of the DMA Controller Abstraction (DCA) is to allow the ICD
-+ * to use any DMA controller, 
-+ * since this is an option in the Inventra USB cores.
-+ * The assumptions are:
-+ * <ul>
-+ * <li>A DMA controller will be tied to an Inventra USB core in the
-+ * way specified in the Inventra core product specification.
-+ * <li>A DMA controller's base address in the memory map correlates
-+ * somehow to the Inventra USB core it serves.
-+ * </ul>
-+ * The responsibilities of an implementation include:
-+ * <ul>
-+ * <li>Allocating/releasing buffers for use with DMA
-+ * (this may be specific to a DMA controller, intervening busses, 
-+ * and a target's capabilities,
-+ * so the ICD cannot make assumptions or provide services here)
-+ * <li>Handling the details of moving multiple USB packets 
-+ * in cooperation with the Inventra USB core.
-+ * <li>Knowing the correlation between channels and the
-+ * Inventra core's local endpoint resources and data direction,
-+ * and maintaining a list of allocated/available channels.
-+ * <li>Updating channel status on interrupts,
-+ * whether shared with the Inventra core or separate.
-+ * <li>If the DMA interrupt is shared with the Inventra core,
-+ * handling it when called, and reporting whether it was the
-+ * source of interrupt.
-+ * </ul>
-+ */
++    MGC_SelectEnd(pBase, bEnd);
++    pEnd = &(pThis->aLocalEnd[bEnd]);
++      pEnd->bEnd=bEnd;
 +
-+/*************************** CONSTANTS ****************************/
++      pEnd->wMaxPacketSizeTx= 0;
++    pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
++    MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_BLK_VAL);
++    MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
++    pThis->bBulkRxEnd = bEnd;
++    /* move to next */
++    wFifoOffset += pEnd->wMaxPacketSizeRx;
++      pThis->wEndMask |= (1 << bEnd);
++    bEnd++;
 +
-+/**
-+ * DMA channel status.
-+ */
-+typedef enum 
-+{
-+    /** A channel's status is unknown */
-+    MGC_DMA_STATUS_UNKNOWN,
-+    /** A channel is available (not busy and no errors) */
-+    MGC_DMA_STATUS_FREE,
-+    /** A channel is busy (not finished attempting its transactions) */
-+    MGC_DMA_STATUS_BUSY,
-+    /** A channel aborted its transactions due to a local bus error */
-+    MGC_DMA_STATUS_BUS_ABORT,
-+    /** A channel aborted its transactions due to a core error */
-+    MGC_DMA_STATUS_CORE_ABORT
-+} MGC_DmaChannelStatus;
++    /* take care of the remaining eps */
++    for(; bEnd < MUSB_C_NUM_EPS; bEnd++) {
++              MGC_SelectEnd(pBase, bEnd);
++              pEnd = &(pThis->aLocalEnd[bEnd]);
++              pEnd->bEnd=bEnd;
 +
-+/***************************** TYPES ******************************/
++              MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ALL_VAL);
++              MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ALL_VAL);
++              pEnd->wMaxPacketSizeTx = pEnd->wMaxPacketSizeRx = 1 << (MGC_DFIFO_ALL_VAL+3);
++              pEnd->bIsSharedFifo = TRUE;
++              MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
++              MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
 +
-+/**
-+ * MGC_DmaChannel.
-+ * A DMA channel.
-+ * @field pPrivateData channel-private data; not to be interpreted by the ICD
-+ * @field wMaxLength the maximum number of bytes the channel can move
-+ * in one transaction (typically representing many USB maximum-sized packets)
-+ * @field dwActualLength how many bytes have been transferred
-+ * @field bStatus current channel status (updated e.g. on interrupt)
-+ * @field bDesiredMode TRUE if mode 1 is desired; FALSE if mode 0 is desired
-+ */
-+typedef struct
-+{
-+    void* pPrivateData;
-+    uint32_t dwMaxLength;
-+    uint32_t dwActualLength;
-+    MGC_DmaChannelStatus bStatus;
-+    uint8_t bDesiredMode;
-+} MGC_DmaChannel;
++              wFifoOffset += pEnd->wMaxPacketSizeRx;
++              pThis->wEndMask |= (1 << bEnd);
++    }
 +
-+/**
-+ * Start a DMA controller.
-+ * @param pPrivateData private data pointer from MGC_DmaController
-+ * @return TRUE on success
-+ * @return FALSE on failure (e.g. no DMAC appears present)
-+ */
-+typedef uint8_t (*MGC_pfDmaStartController)(void* pPrivateData);
++#ifdef MUSB_PARANOID
++      if ( wFifoOffset > 64 ) {
++              ERR("Allocated %d bytes, more than the allowed %d\n",
++               wFifoOffset, 64);
++      } else {
++              INFO("Allocated %d bytes, out of %d\n",
++                      wFifoOffset, 64);
++      }
++#endif
 +
-+/**
-+ * Stop a DMA controller.
-+ * @param pPrivateData the controller's private data pointer
-+ * @return TRUE on success
-+ * @return FALSE on failure; the ICD may try again
-+ */
-+typedef uint8_t (*MGC_pfDmaStopController)(void* pPrivateData);
++    DBG(2, "==>\n");
++}
++#endif
 +
++#else
 +/**
-+ * Allocate a DMA channel.
-+ * Allocate a DMA channel suitable for the given conditions.
-+ * @param pPrivateData the controller's private data pointer
-+ * @param bLocalEnd the local endpoint index (1-15)
-+ * @param bTransmit TRUE for transmit; FALSE for receive
-+ * @param bProtocol the USB protocol, as per USB 2.0 chapter 9
-+ * (0 => control, 1 => isochronous, 2 => bulk, 3 => interrupt)
-+ * @param wMaxPacketSize maximum packet size
-+ * @return a non-NULL pointer on success
-+ * @return NULL on failure (no channel available)
++ * Detect and configure the end points (no dynamic fifos).
++ * @param pThis the controller
 + */
-+typedef MGC_DmaChannel* (*MGC_pfDmaAllocateChannel)(
-+    void* pPrivateData, uint8_t bLocalEnd, 
-+    uint8_t bTransmit, uint8_t bProtocol, uint16_t wMaxPacketSize);
++void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
++    uint8_t bEnd=0, reg;
++    MGC_LinuxLocalEnd* pEnd;
++    void* pBase = pThis->pRegs;
++    /* how many of a given size/direction found: */
++    uint8_t b2kTxEndCount = 0;
++    uint8_t b2kRxEndCount = 0;
++    uint8_t b1kTxEndCount = 0;
++    uint8_t b1kRxEndCount = 0;
++    /* the smallest 2k or 1k ends in Tx or Rx direction: */
++    uint8_t b2kTxEnd = 0;
++    uint8_t b2kRxEnd = 0;
++    uint8_t b1kTxEnd = 0;
++    uint8_t b1kRxEnd = 0;
++    /* for tracking smallest: */
++    uint16_t w2kTxSize = 0;
++    uint16_t w1kTxSize = 0;
++    uint16_t w2kRxSize = 0;
++    uint16_t w1kRxSize = 0;
 +
-+/**
-+ * Release a DMA channel.
-+ * Release a previously-allocated DMA channel.
-+ * The ICD guarantess to no longer reference this channel.
-+ * @param pChannel pointer to a channel obtained by 
-+ * a successful call to pController->pfDmaAllocateChannel
-+ */
-+typedef void (*MGC_pfDmaReleaseChannel)(MGC_DmaChannel* pChannel);
++      DBG(2, ">==\n");
 +
-+/**
-+ * Allocate DMA buffer.
-+ * Allocate a buffer suitable for DMA operations with the given channel.
-+ * @param pChannel pointer to a channel obtained by 
-+ * a successful call to pController->pfDmaAllocateChannel
-+ * @param dwLength length, in bytes, desired for the buffer
-+ * @return a non-NULL pointer to a suitable region (in processor space)
-+ * on success
-+ * @return NULL on failure
-+ */
-+typedef uint8_t* (*MGC_pfDmaAllocateBuffer)(MGC_DmaChannel* pChannel,
-+                                           uint32_t dwLength);
++      for(bEnd = 1; bEnd < MUSB_C_NUM_EPS; bEnd++) {
++        MGC_SelectEnd(pBase, bEnd);
++              pEnd = &(pThis->aLocalEnd[bEnd]);
++              pEnd->bEnd=bEnd;
 +
-+/**
-+ * Release DMA buffer.
-+ * Release a DMA buffer previously acquiring by a successful call
-+ * to pController->pfDmaAllocateBuffer.
-+ * @param pChannel pointer to a channel obtained by 
-+ * a successful call to pController->pfDmaAllocateChannel
-+ * @param pBuffer the buffer pointer
-+ * @return TRUE on success
-+ * @return FALSE on failure (e.g. the controller owns the buffer at present)
-+ */
-+typedef uint8_t (*MGC_pfDmaReleaseBuffer)(MGC_DmaChannel* pChannel,
-+                                         uint8_t* pBuffer);
++              /* read from core */
++              reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_FIFOSIZE, bEnd);
++              if(!reg) {
++                /* 0's returned when no more endpoints */
++                break;
++              }
 +
-+/**
-+ * Program a DMA channel.
-+ * Program a DMA channel to move data at the core's request.
-+ * The local core endpoint and direction should already be known,
-+ * since they are specified in the pfDmaAllocateChannel call.
-+ * @param pChannel pointer to a channel obtained by 
-+ * a successful call to pController->pfDmaAllocateChannel
-+ * @param wPacketSize the packet size
-+ * @param bMode TRUE if mode 1; FALSE if mode 0
-+ * @param pBuffer base address of data (in processor space)
-+ * @param dwLength the number of bytes to transfer;
-+ * guaranteed by the ICD to be no larger than the channel's reported dwMaxLength
-+ * @return TRUE on success
-+ * @return FALSE on error
-+ */
-+typedef uint8_t (*MGC_pfDmaProgramChannel)(MGC_DmaChannel* pChannel, 
-+                                          uint16_t wPacketSize, uint8_t bMode,
-+                                          const uint8_t* pBuffer, 
-+                                          uint32_t dwLength);
++              pEnd->wMaxPacketSizeTx = 1 << (reg & 0x0f);
++              /* shared TX/RX FIFO? */
++              if((reg & 0xf0) == 0xf0) {
++                      pEnd->wMaxPacketSizeRx = 1 << (reg & 0x0f);
++                      pEnd->bIsSharedFifo = TRUE;
++              } else {
++                      pEnd->wMaxPacketSizeRx = 1 << ((reg & 0xf0) >> 4);
++                      pEnd->bIsSharedFifo = FALSE;
++              }
 +
-+/**
-+ * Get DMA channel status.
-+ * Get the current status of a DMA channel, if the hardware allows.
-+ * @param pChannel pointer to a channel obtained by 
-+ * a successful call to pController->DmaAllocateChannel
-+ * @return current status 
-+ * (MGC_DMA_STATUS_UNKNOWN if hardware does not have readable status)
-+ */
-+typedef MGC_DmaChannelStatus (*MGC_pfDmaGetChannelStatus)(
-+    MGC_DmaChannel* pChannel);
++              /* track certain sizes to try to reserve a bulk resource */
++              if(pEnd->wMaxPacketSizeTx >= 2048) {
++                      b2kTxEndCount++;
++                      if(!b2kTxEnd || (pEnd->wMaxPacketSizeTx < w2kTxSize)) {
++                              b2kTxEnd = bEnd;
++                              w2kTxSize = pEnd->wMaxPacketSizeTx;
++                      }
++              }
 +
-+/**
-+ * DMA ISR.
-+ * If present, this function is called by the ICD on every interrupt.
-+ * This is necessary because with the built-in DMA controller
-+ * (and probably some other configurations),
-+ * the DMA interrupt is shared with other core interrupts.
-+ * Therefore, this function should return quickly 
-+ * when there is no DMA interrupt.
-+ * When there is a DMA interrupt, this function should
-+ * perform any implementations-specific operations,
-+ * and update the status of all appropriate channels.
-+ * If the DMA controller has its own dedicated interrupt,
-+ * this function should do nothing.
-+ * This function is called BEFORE the ICD handles other interrupts.
-+ * @param pPrivateData the controller's private data pointer
-+ * @return TRUE if an interrupt was serviced
-+ * @return FALSE if no interrupt required servicing
-+ */
-+typedef uint8_t (*MGC_pfDmaControllerIsr)(void* pPrivateData);
++              if(pEnd->wMaxPacketSizeRx >= 2048) {
++                      b2kRxEndCount++;
++                      if(!b2kRxEnd || (pEnd->wMaxPacketSizeRx < w2kRxSize)) {
++                              b2kRxEnd = bEnd;
++                              w2kRxSize = pEnd->wMaxPacketSizeRx;
++                      }
++              }
 +
-+/**
-+ * MGC_DmaController.
-+ * A DMA Controller.
-+ * This is in a struct to allow the ICD to support
-+ * multiple cores of different types, 
-+ * since each may use a different type of DMA controller.
-+ * @field pPrivateData controller-private data;
-+ * not to be interpreted by the ICD
-+ * @field pfDmaStartController ICD calls this to start a DMA controller
-+ * @field pfDmaStopController ICD calls this to stop a DMA controller
-+ * @field pfDmaAllocateChannel ICD calls this to allocate a DMA channel
-+ * @field pfDmaReleaseChannel ICD calls this to release a DMA channel
-+ * @field pfDmaAllocateBuffer ICD calls this to allocate a DMA buffer
-+ * @field pfDmaReleaseBuffer ICD calls this to release a DMA buffer
-+ * @field pfDmaGetChannelStatus ICD calls this to get a DMA channel's status
-+ * @field pfDmaControllerIsr ICD calls this (if non-NULL) from its ISR
-+ */
-+typedef struct
-+{
-+    void* pPrivateData;
-+    MGC_pfDmaStartController pfDmaStartController;
-+    MGC_pfDmaStopController pfDmaStopController;
-+    MGC_pfDmaAllocateChannel pfDmaAllocateChannel;
-+    MGC_pfDmaReleaseChannel pfDmaReleaseChannel;
-+    MGC_pfDmaAllocateBuffer pfDmaAllocateBuffer;
-+    MGC_pfDmaReleaseBuffer pfDmaReleaseBuffer;
-+    MGC_pfDmaProgramChannel pfDmaProgramChannel;
-+    MGC_pfDmaGetChannelStatus pfDmaGetChannelStatus;
-+    MGC_pfDmaControllerIsr pfDmaControllerIsr;
-+} MGC_DmaController;
++              if(pEnd->wMaxPacketSizeTx >= 1024) {
++                      b1kTxEndCount++;
++                      if(!b1kTxEnd || (pEnd->wMaxPacketSizeTx < w1kTxSize)) {
++                              b1kTxEnd = bEnd;
++                              w1kTxSize = pEnd->wMaxPacketSizeTx;
++                      }
++              }
 +
-+/**
-+ * A DMA channel has new status.
-+ * This may be used to notify the ICD of channel status changes asynchronously.
-+ * This is useful if the DMA interrupt is different from the USB controller's
-+ * interrupt, so on some systems there may be no control over the order of
-+ * USB controller and DMA controller assertion.
-+ * @param pPrivateData the controller's private data pointer
-+ * @param bLocalEnd the local endpoint index (1-15)
-+ * @param bTransmit TRUE for transmit; FALSE for receive
-+ * @return TRUE if an IRP was completed as a result of this call;
-+ * FALSE otherwise
-+ */
-+typedef uint8_t (*MGC_pfDmaChannelStatusChanged)(
-+    void* pPrivateData, uint8_t bLocalEnd, 
-+    uint8_t bTransmit);
++              if(pEnd->wMaxPacketSizeRx >= 1024) {
++                      b1kRxEndCount++;
++                      if(!b1kRxEnd || (pEnd->wMaxPacketSizeRx < w1kTxSize)) {
++                              b1kRxEnd = bEnd;
++                              w1kRxSize = pEnd->wMaxPacketSizeRx;
++                      }
++              }
 +
-+/**
-+ * Instantiate a DMA controller.
-+ * Instantiate a software object representing a DMA controller.
-+ * @param pfDmaChannelStatusChanged channel status change notification function.
-+ * Normally, the ICD requests status in its interrupt handler.
-+ * For some DMA controllers, this may not be the correct time.
-+ * @param pDmaPrivate parameter for pfDmaChannelStatusChanged
-+ * @param pCoreBase the base address (in kernel space) of the core
-+ * It is assumed the DMA controller's registers' base address will be related
-+ * to this in some way.
-+ * @return non-NULL pointer on success
-+ * @return NULL on failure (out of memory or exhausted 
-+ * a fixed number of controllers)
-+ */
-+typedef MGC_DmaController* (*MGC_pfNewDmaController)(
-+    MGC_pfDmaChannelStatusChanged pfDmaChannelStatusChanged,
-+    void* pDmaPrivate,
-+    uint8_t* pCoreBase);
++              pThis->bEndCount++;
++              pThis->wEndMask |= (1 << bEnd);
++    } /* init queues etc. etc. etc. */
 +
-+/**
-+ * Destroy DMA controller.
-+ * Destroy a previously-instantiated DMA controller.
-+ */
-+typedef void (*MGC_pfDestroyDmaController)(
-+      MGC_DmaController* pController);
++    /* if possible, reserve the smallest 2k-capable Tx end for bulk */
++    if(b2kTxEnd && (b2kTxEndCount > 1)) {
++              pThis->bBulkTxEnd = b2kTxEnd;
++              INFO("Reserved end %d for bulk double-buffered Tx\n", b2kTxEnd);
++    }
++    /* ...or try 1k */
++    else if(b1kTxEnd && (b1kTxEndCount > 1)) {
++              pThis->bBulkTxEnd = b1kTxEnd;
++              INFO("Reserved end %d for bulk Tx\n", b1kTxEnd);
++    }
 +
-+/**
-+ * MGC_DmaControllerFactory.
-+ * A DMA controller factory.
-+ * To allow for multi-core implementations and different
-+ * types of cores and DMA controllers to co-exist,
-+ * it is necessary to create them from factories.
-+ * @field wCoreRegistersExtent the total size of the core's
-+ * register region with the DMA controller present,
-+ * for use in mapping the core into system memory.
-+ * For example, the MHDRC core takes 0x200 bytes of address space.
-+ * If your DMA controller starts at 0x200 and takes 0x100 bytes,
-+ * set this to 0x300.
-+ * @field pfNewDmaController create a DMA controller
-+ * @field pfDestroyDmaController destroy a DMA controller
-+ */
-+typedef struct
-+{
-+    uint16_t wCoreRegistersExtent;
-+    MGC_pfNewDmaController pfNewDmaController;
-+    MGC_pfDestroyDmaController pfDestroyDmaController;
-+} MGC_DmaControllerFactory;
++    /* if possible, reserve the smallest 2k-capable Rx end for bulk */
++    if(b2kRxEnd && (b2kRxEndCount > 1)) {
++              pThis->bBulkRxEnd = b2kRxEnd;
++              INFO("Reserved end %d for bulk double-buffered Rx\n", b2kRxEnd);
++    }
++    /* ...or try 1k */
++    else if(b1kRxEnd && (b1kRxEndCount > 1)) {
++              pThis->bBulkRxEnd = b1kRxEnd;
++              INFO("Reserved end %d for bulk Rx\n", b1kRxEnd);
++    }
 +
-+#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/g_ep0.c ../new/linux-2.6.20/drivers/usb/nomadik/g_ep0.c
---- linux-2.6.20/drivers/usb/nomadik/g_ep0.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/g_ep0.c    2008-08-08 19:15:20.000000000 +0530
-@@ -0,0 +1,858 @@
++    DBG(2, "<==\n");
++}
++#endif
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_hcd.c
+@@ -0,0 +1,869 @@
 +/*
-+ * linux/drivers/usb/nomadik/g_ep0.c
++ * linux/drivers/usb/nomadik/musb_hcd.c
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -191051,1139 +194534,863 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/g_ep0.c ../new/linux-2.6.20/driver
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/timer.h>
-+#include <linux/spinlock.h>
-+
-+#if defined(MUSB_V24) && !defined(MUSB_LINUX_MV21)
-+/* dealing with Linux headers */
-+struct usb_tt {
-+      struct usb_device       *hub;   /* upstream highspeed hub */
-+      int                     multi;  /* true means one TT per port */
-+}; 
-+#include "hcd.h"
-+#endif
-+
-+#include <linux/init.h>
-+#include <linux/usb_ch9.h>
-+#include "musbdefs.h"
-+#include "musb_gadgetdefs.h"
++#include <asm/arch/pexp.h>
++static void mgc_hcd_stop(struct usb_hcd *hcd);
++static int __devinit mgc_hcd_start(struct usb_hcd *hcd);
++static int mgc_hcd_submit_urb(struct usb_hcd *hcd,struct usb_host_endpoint *ep,
++      struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
++static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb);
++static int mgc_hcd_get_frame_number(struct usb_hcd *hcd);
++static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd);
++static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd,
++      struct usb_host_endpoint *ep);
++static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
 +
++static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++      u16 wIndex, char *pData, u16 wLength);
++static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData);
++int Urb_status=0;
++/* ------------------------------------------------------- */
++static int    mgc_bus_resume(struct usb_hcd *phcd)
++{
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
++      char* pBase = (char*)pThis->pRegs;
 +
-+/* ---------------------------------------------------------------------- */
++      nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
++      /* Reinitialize the interrupt*/
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, 0x20);
++      MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0xFFFF);
++      MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0xFFFE);
++      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xF7);
++      MGC_Write8(pBase, MGC_O_HDRC_INDEX ,0x00);
 +
-+/**
-+ * Identifies a transmit request.
-+ * @param pControlRequest the control request
-+ * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE, 
-+ *            USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME 
-+ */
-+uint8_t is_tx_request(const struct usb_ctrlrequest *pControlRequest) 
-+{
-+    return ( pControlRequest->bRequestType & USB_DIR_IN );
-+}
++      /* Configure the endpoints*/
++      MGC_HdrcConfigureEps(pThis);
++      MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);
++      mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
 +
-+/**
-+ * Identifies a zero data request.
-+ * @param pControlRequest the control request
-+ * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION, 
-+ *    USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
-+ * 
-+ */ 
-+uint8_t is_zerodata_request(const struct usb_ctrlrequest *pControlRequest) 
-+{
-+    return ( 0==pControlRequest->wLength ) && !is_tx_request(pControlRequest);
++      printk("Got Bus Resume:\n");
++      return 0;
 +}
-+
-+/**
-+ * Identifies a receive request.
-+ * @param pControlRequest the control request
-+ * @return true for USB_REQ_SET_DESCRIPTOR  
-+ */ 
-+uint8_t is_rx_request(const struct usb_ctrlrequest *pControlRequest) 
++static int    mgc_bus_suspend(struct usb_hcd *phcd)
 +{
-+    return pControlRequest->bRequest==USB_REQ_SET_DESCRIPTOR;
-+}
++      uint8_t  power;
++      uint8_t  devctrl;
++      uint8_t  topctrl;
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
++      char* pBase = (char*)pThis->pRegs;
 +
-+/* ---------------------------------------------------------------------- */
++      /* Delete Timer*/
++      del_timer(&notify_timer);
++      MUSB_A_IDLE_MODE(pThis);
 +
-+/**
-+ * Forward a request to the driver.
-+ *  
-+ * FROM: usb_gadget.h
-+ * Accordingly, the driver's setup() callback must always implement all
-+ * get_descriptor requests, returning at least a device descriptor and
-+ * a configuration descriptor.  Drivers must make sure the endpoint
-+ * descriptors match any hardware constraints. Some hardware also constrains
-+ * other descriptors. (The pxa250 allows only configurations 1, 2, or 3).
-+ *
-+ * The driver's setup() callback must also implement set_configuration,
-+ * and should also implement set_interface, get_configuration, and
-+ * get_interface.  Setting a configuration (or interface) is where
-+ * endpoints should be activated or (config 0) shut down.
-+ *
-+ * @param pControlRequest the usb control request to forward to the driver
-+ */
-+static int forward_to_driver(const struct usb_ctrlrequest *pControlRequest) 
-+{
-+    int handled=-EOPNOTSUPP;
-+    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
-+      
-+      
-+    DBG(2, "<== pThis->pGadgetDriver=%p, pControlRequest=%p\n", 
-+              pThis->pGadgetDriver, pControlRequest); 
-+    
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); 
-+#endif
-+      
-+    if ( pThis->pGadgetDriver ){
-+              handled=pThis->pGadgetDriver->setup(pThis->pGadget, 
-+                      pControlRequest);    
-+    }
-+    else{
-+              printk("Error case\n");
-+    }
-+      
-+    DBG(2, "==> handled=%d\n", handled);      
-+    return handled;
-+}
++      /*
++       * Device mode? disconnect the device and then
++       * proceed
++       */
++      if(MUSB_IS_DEV(pThis)){
++              udc_disconnect_isr();
++              power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++              MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_SOFTCONN);
++              devctrl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++              MUSB_B_IDLE_MODE(pThis);
++              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctrl & ~MGC_M_DEVCTL_SESSION);
++              dev_safe_remove =0;
++      }
++      /* Reset the controller*/
++      topctrl = MGC_Read8(pBase, MGC_O_HDRC_TOPCONTROL);
++      MGC_Write8(pBase, MGC_O_HDRC_TOPCONTROL, (topctrl |MGC_M_TOPCTRL_MODE_SRST));
++      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_ENSUSPEND);
 +
-+/* ---------------------------------------------------------------------- */
++      nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG,"OTG");
 +
-+/**
-+ * Service a receive request. Currently forward to the driver.
-+ * @param pControlRequest the usb control request to service.
-+ * @see is_rx_request
-+ */
-+static int service_rx_request(struct usb_ctrlrequest *pControlRequest) 
-+{
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); 
-+#endif
-+    return forward_to_driver(pControlRequest);
++      printk("Got Bus Suspend:\n");
++      return 0;
 +}
-+
-+/**
-+ * Service a transmit request.
-+ * @param pControlRequest the request to service
-+ * @see is_tx_request
-+ */
-+void service_tx_status_request(const struct usb_ctrlrequest *pControlRequest) 
++#ifdef        CONFIG_USB_SUSPEND
++static int    mgc_suspend (struct usb_hcd *phcd, pm_message_t message)
 +{
-+    uint8_t handled=1;
-+    uint8_t bResult[2], bEnd=0;
-+    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
-+    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK;
-+      
-+      /* ack the request */
-+      DBG(3, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
-+      spin_lock(&pThis->Lock);
-+      MGC_SelectEnd(pBase, 0);
-+      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY);
-+      spin_unlock(&pThis->Lock);
-+      
-+    switch (bRecip) {
-+              
-+      case USB_RECIP_DEVICE:          
-+              DBG(3, "USB_RECIP_DEVICE()\n");             
-+              bResult[0] = pThis->bIsSelfPowered ? 1 : 0;
-+              bResult[0] |= 2;
-+              bResult[1] = 0;     
-+              MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult);
-+              break;
-+              
-+      case USB_RECIP_ENDPOINT: 
-+              {
-+              uint16_t wTest;
-+              
-+              DBG(3, "USB_RECIP_ENDPOINT()\n");
-+              
-+              bEnd = (uint8_t)pControlRequest->wIndex;
-+              
-+              spin_lock(&pThis->Lock);
-+              MGC_SelectEnd(pBase, bEnd);
-+              wTest = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
-+              MGC_SelectEnd(pBase, 0);
-+              bResult[0] = (wTest & MGC_M_TXCSR_P_SENDSTALL) ? 1 : 0;
-+              bResult[1] = 0;
-+              MGC_HdrcLoadFifo(pBase, 0, 2, (uint8_t*)&bResult);
-+              spin_unlock(&pThis->Lock);
-+              } 
-+              break;
-+              
-+      default:
-+              handled=0;
-+              break;
-+    }
-+      
-+    /* send it out! (this will trigger the ep0 completition IRQ) 
-+       * serviced in interrupt_complete()  */
-+    if ( handled ) {
-+              pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT;
-+              
-+              spin_lock(&pThis->Lock);
-+              MGC_SelectEnd(pBase, bEnd);
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                      MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_P_DATAEND);
-+              spin_unlock(&pThis->Lock);
-+    }
++      uint8_t power;
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
++      char* pBase = (char*)pThis->pRegs;
++      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
++      printk("Got Suspend\n");
++      return 0;
 +}
-+
-+/**
-+ * Service a transmit a request. End0 buffer contains the current 
-+ * request (a standard control request). Assumes the fifo to be at least 
-+ * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION, 
-+ * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, 
-+ * USB_REQ_SYNC_FRAME.
-+ *
-+ * @param pControlRequest the request to service
-+ * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not 
-+ * supprorted), > 0 when the request is processed 
-+ * @see is_tx_request
-+ */
-+static int service_tx_request(const struct usb_ctrlrequest *pControlRequest) 
++static int    mgc_resume(struct usb_hcd *phcd)
 +{
-+    int handled=0; /* not handled */
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); 
-+#endif
-+      
-+    if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) {
-+              return forward_to_driver(pControlRequest);
-+    }
-+    
-+    switch (pControlRequest->bRequest) {
-+      case USB_REQ_GET_CONFIGURATION:
-+              DBG(3, "USB_REQ_GET_CONFIGURATION()\n");
-+              break;
-+              
-+      case USB_REQ_GET_INTERFACE:
-+              DBG(3, "USB_REQ_GET_INTERFACE()\n");
-+              break;
-+              
-+      case USB_REQ_GET_DESCRIPTOR:
-+              DBG(3, "USB_REQ_GET_DESCRIPTOR()\n");
-+              break;
-+              
-+      case USB_REQ_GET_STATUS: {
-+              DBG(3, "USB_REQ_GET_STATUS()\n");
-+              service_tx_status_request(pControlRequest);
-+              } 
-+              break;
-+              
-+      /* case USB_REQ_SYNC_FRAME:
-+              break; */
-+              
-+      default: 
-+              break;
-+    }
-+      
-+    if ( !handled ) {
-+              handled=forward_to_driver(pControlRequest);
-+    }
-+      
-+      /* now tx! */
-+    return handled;
++      uint8_t power;
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
++      char* pBase = (char*)pThis->pRegs;
++      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
++      mdelay(15);
++      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME);
++      printk("Got Resume\n");
++      return 0;
 +}
-+
-+/**
-+ * Service a zero data request. 
-+ * Called for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
-+ * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE.
-+ * 
-+ * @param pThis the controller instance
-+ * @param pControlRequest the control request to service.
-+ * @warning USB_REQ_SET_ADDRESS should be executed QUICKLY
-+ * @see is_zerodata_request
-+ */
-+static int service_zero_data_request(MGC_LinuxCd* pThis, 
-+                                                                       struct usb_ctrlrequest *pControlRequest) 
-+{
-+    int handled=1; /* handled, DO NOT not pass down */
-+    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    const uint8_t bRecip=pControlRequest->bRequestType & USB_RECIP_MASK;
-+      
-+    DBG(-1002, "<==\n");
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); 
-+#endif
-+      
-+    /* non standard requests are piped to the gadget */
-+    if ( USB_TYPE_STANDARD!=(pControlRequest->bRequestType&USB_TYPE_MASK )) {
-+              return forward_to_driver(pControlRequest);
-+    }
-+    
-+    /* zero data phase */     
-+    switch (pControlRequest->bRequest) {
-+              
-+      case USB_REQ_SET_INTERFACE:
-+              DBG(3, "USB_REQ_SET_INTERFACE()\n");
-+              handled=0; /* pass it to the gadget */
-+              break;       
-+              
-+      case USB_REQ_SET_CONFIGURATION:
-+              /* remember state & handle on the end status stage interrupt */
-+              DBG(3, "USB_REQ_SET_CONFIGURATION()\n");
-+              pThis->bDeviceState = (pControlRequest->wValue & 0xff)
-+                      ? MGC_STATE_CONFIGURED : MGC_STATE_ADDRESS;
-+              handled=0; /* pass it to the gadget */
-+              break;
-+              
-+      case USB_REQ_SET_ADDRESS:
-+              /* remember state & handle on the end status stage interrupt */
-+              DBG(3, "USB_REQ_SET_ADDRESS(0x%x)\n",(uint8_t)
-+                      (pControlRequest->wValue & 0x7f));
-+              
-+              pThis->bSetAddress = TRUE;
-+              pThis->bAddress = (uint8_t)(pControlRequest->wValue & 0x7f);
-+              pThis->bDeviceState = MGC_STATE_ADDRESS;
-+              break;
-+              
-+      case USB_REQ_CLEAR_FEATURE:
-+              DBG(3, "USB_REQ_CLEAR_FEATURE()\n");
-+              
-+              switch (bRecip) {
-+                      
-+              case USB_RECIP_DEVICE:
-+                      DBG(3, "USB_RECIP_DEVICE()\n");
-+                      break;
-+                      
-+              case USB_RECIP_INTERFACE:
-+                      DBG(3, "USB_RECIP_INTERFACE()\n");
-+                      break;
-+                      
-+              case USB_RECIP_ENDPOINT: {
-+                      const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ;
-+                      MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ];
-+                      
-+                      DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );                     
-+                      MGC_GadgetSetHalt( &pEnd->end_point, 0);
-+                      /* select ep0 again */
-+                      MGC_SelectEnd(pBase, 0);                        
-+                                                               } 
-+                      break;
-+                      
-+              default:
-+                      break;          
-+              }
-+              break; /* END: CLEAR_FEATURE */
-+              
-+              case USB_REQ_SET_FEATURE:
-+                      DBG(3, "USB_REQ_SET_FEATURE()\n");
-+                      
-+                      switch (bRecip) {
-+                              
-+                      case USB_RECIP_DEVICE:
-+                              DBG(3, "USB_RECIP_DEVICE()\n");
-+                              
-+                              switch (pControlRequest->wValue) {
-+                                      
-+                              case 1:
-+                                      DBG(3, "REMOTE_WAKEUP()\n");
-+                                      while (0) { } /* remote wakeup */
-+                                      break;
-+                                      
-+                              case 2:
-+                                      if (pControlRequest->wIndex & 0xff) {
-+                                              handled=-EINVAL;
-+                                      } else {
-+                                              uint16_t wTest;
-+                                              
-+                                              DBG(3, "ENTERING TESTMODE\n");
-+                                              pThis->bTestMode = TRUE;
-+                                              wTest = (uint8_t)pControlRequest->wIndex >> 8;
-+                                              switch(wTest) {
-+                                                      
-+                                              case 1:
-+                                                      DBG(3, "TEST_J\n");
-+                                                      /* TEST_J */
-+                                                      pThis->bTestModeValue = MGC_M_TEST_J;
-+                                                      break;
-+                                                      
-+                                              case 2:
-+                                                      /* TEST_K */
-+                                                      DBG(3, "TEST_K\n");
-+                                                      pThis->bTestModeValue = MGC_M_TEST_K;
-+                                                      break;
-+                                                      
-+                                              case 3:
-+                                                      /* TEST_SE0_NAK */
-+                                                      DBG(3, "TEST_SE0_NAK\n");
-+                                                      pThis->bTestModeValue = MGC_M_TEST_SE0_NAK;
-+                                                      break;
-+                                                      
-+                                              case 4:
-+                                                      /* TEST_PACKET */
-+                                                      DBG(3, "TEST_PACKET\n");
-+                                                      pThis->bTestModeValue = MGC_M_TEST_PACKET;
-+                                                      break;
-+                                                      
-+                                              default:
-+                                                      /* my gadget might know what to do with it */
-+                                                      break;
-+                                              }
-+                                      }
-+                                      break;
-+#ifdef MUSB_OTG
-+                              case 3:
-+                                      GADGET_SET_B_HNP_ENABLE(pThis->pGadget, 1);                     
-+                                      MGC_OtgMachineSetFeature(&(pThis->OtgMachine), 
-+                                              pControlRequest->wValue);
-+                                      break;
-+                                      
-+                              case 4:
-+                                      GADGET_SET_A_HNP_SUPPORT(pThis->pGadget, 1);                    
-+                                      MGC_OtgMachineSetFeature(&(pThis->OtgMachine), 
-+                                              pControlRequest->wValue);
-+                                      break;
-+                                      
-+                              case 5:
-+                                      GADGET_SET_A_ALT_HNP_SUPPORT(pThis->pGadget, 1);
-+                                      MGC_OtgMachineSetFeature(&(pThis->OtgMachine), 
-+                                              pControlRequest->wValue);
-+                                      break;
 +#endif
-+                              }
-+                              break;
-+                              
-+                              case USB_RECIP_INTERFACE:
-+                                      DBG(3, "USB_RECIP_INTERFACE()\n");
-+                                      break;
-+                                      
-+                              case USB_RECIP_ENDPOINT: {
-+                                      const uint8_t bEnd = (uint8_t)pControlRequest->wIndex & 0x7f ;
-+                                      MGC_GadgetLocalEnd* pEnd=&MGC_aGadgetLocalEnd[ bEnd ];
-+                                      
-+                                      DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );                        
-+                                      MGC_GadgetSetHalt(&pEnd->end_point, 1);
-+                                      
-+                                      /* select ep0 again */
-+                                      MGC_SelectEnd(pBase, 0);
-+                                                                               } 
-+                                      break;
-+                                      
-+                      }
-+                      break; /* END: SET_FEATURE */
-+                      
-+                      default:
-+                              handled=0;
-+                              break;
-+    }
-+      
-+    /* standard request not handed by this code go to the gadget */
-+    if ( !handled ) {
-+              handled=forward_to_driver(pControlRequest);
-+    }
-+      
-+    DBG(-1002, "==>\n");
-+    return handled;
-+}
++/* as platform_data */
++struct plat_musb_hcd {
++      unsigned long mapbase;
++      unsigned irq;
++      unsigned index;
++      char name[32];
++};
 +
-+/* ---------------------------------------------------------------------- */
++const struct hc_driver musb_ahb_hc_driver = {
++      .description =          MGC_HcdName,
++      .product_desc =         "MUSB HCD",
 +
-+/**
-+ * Complete a request on enpdpoint 0. This is called after a competition
-+ * IRQ on ep0 has occourred.
-+ * @warning Executed @ interrupt time; complete CANNOT sleep.
-+ */
-+void mgc_complete_ep0_request(void) 
-+{
-+    struct usb_request *pRequest;
-+    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
-+    
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_LOCKED(&MGC_aGadgetLocalEnd[0]); 
++      /* this will allocate a MGC_LinuxCd at the end of it */
++      .hcd_priv_size =        sizeof(MGC_LinuxCd),
++
++      /*
++       * generic hardware linkage
++       */
++#ifdef MUSB_POLL
++       .irq =                 NULL,
++#else
++       .irq =                 mgc_hcd_isr,
 +#endif
-+      
-+    spin_lock( &MGC_aGadgetLocalEnd[0].Lock );
-+    pRequest=MGC_CurrentRequest( &MGC_aGadgetLocalEnd[0] );
-+      
-+    DBG(3, "completing request pRequest=%p\n", pRequest);
-+      
-+    /* this is interrupt code, it cannot sleep! */
-+    if ( pRequest ) {
-+              list_del( &pRequest->list );    
-+              INIT_LIST_HEAD( &MGC_aGadgetLocalEnd[0].req_list );     
-+              
-+              spin_unlock( &MGC_aGadgetLocalEnd[0].Lock );
-+              if ( pRequest->complete ) {     
-+                      pRequest->complete(&MGC_aGadgetLocalEnd[0].end_point, 
-+                              pRequest);
-+              }
-+    } else {
-+              spin_unlock( &MGC_aGadgetLocalEnd[0].Lock );
-+    }
-+      
-+    pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;
-+}
 +
-+/**
-+ * handle the completition interrupt on endpoint 0. 
-+ */
-+static void handle_ep0_completition_irq(void) 
-+{
-+    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
-+    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+      
-+    DBG(3, "<==\n");
-+    DBG(4, "post event interrupts ep0stage=%s\n", 
-+              decode_ep0stage(pThis->bEnd0Stage));
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&MGC_aGadgetLocalEnd[0]); 
-+#endif
-+      
-+    switch (pThis->bEnd0Stage) {      
-+              
-+              /* end of sequence #2 (RX state) or #3 (no data) */
-+      case MGC_END0_STAGE_STATUSIN:       
-+              DBG(-1001, "MGC_END0_STAGE_STATUSIN request\n");
-+              
-+              /* update address (if needed) only @ the end of the 
-+               * status phase per standard. The guide is WRONG!
-+               */
-+              if(pThis->bSetAddress) {            
-+                      pThis->bSetAddress = FALSE;
-+                      MGC_Write8(pBase, MGC_O_HDRC_FADDR, pThis->bAddress);           
-+#ifdef MUSB_MONITOR_DATA
-+                      MGC_EnableDebug();
-+#endif                 
-+              }
-+              
-+              /* enter test mode if needed */
-+              if(pThis->bTestMode) {
-+                      DBG(-1001, "entering TESTMODE\n");
-+                      
-+                      if (MGC_M_TEST_PACKET == pThis->bTestModeValue) {
-+                              MGC_HdrcLoadFifo(pBase, 0, sizeof(MGC_aTestPacket), 
-+                                      MGC_aTestPacket);
-+                      }
-+                      
-+                      spin_lock(&pThis->Lock);
-+                      MGC_SelectEnd(pBase, 0); /* select ep0 */
-+                      MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 
-+                              pThis->bTestModeValue);
-+                      spin_unlock(&pThis->Lock);
-+              }           
-+              
-+              DBG(-1001, "completing posted request (if any)\n");         
-+              mgc_complete_ep0_request();
-+              break;
-+              
-+              /* sequence #1: write to host (TX state)  */
-+      case MGC_END0_STAGE_STATUSOUT:
-+              DBG(-1001, "completing posted request (if any)\n");         
-+              mgc_complete_ep0_request();
-+              break;
-+              
-+      case MGC_END0_STAGE_TX:
-+              DBG(-1001, "TX changeing ep status\n");
-+              if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) {
-+                      pThis->bEnd0Stage=MGC_END0_STAGE_STATUSOUT;
-+              }
-+              break;
++      /* USB version 2 & memeory usage */
++      .flags =                HCD_USB2 | HCD_MEMORY,
++
++      /*
++       * basic lifecycle operations
++       */
++      .start =                mgc_hcd_start,
++      .stop =                 mgc_hcd_stop,
++
++      /*
++       * managing i/o requests and associated device resources
++       */
++      .urb_enqueue =          mgc_hcd_submit_urb,
++      .urb_dequeue =          mgc_hcd_unlink_urb,
++
++      .endpoint_disable =     mgc_hcd_disable_endpoint,
++
++      /*
++       * scheduling support
++       */
++      .get_frame_number =     mgc_hcd_get_frame_number,
++
++      /*
++       * root hub support
++       */
++      .hub_status_data =      mgc_root_hub_status,
++      .hub_control =          mgc_root_hub_control,
++
++      .bus_suspend =          mgc_bus_suspend,
++      .bus_resume =           mgc_bus_resume,
++#ifdef        CONFIG_USB_SUSPEND
++      .suspend=                       mgc_suspend,
++      .resume=                        mgc_resume,
++#endif
 +
-+      case MGC_END0_STAGE_RX:
-+              DBG(-1001, "RX changeing ep status\n");
-+              if ( MGC_CurrentRequest(&MGC_aGadgetLocalEnd[0])->status!=-EINPROGRESS ) {
-+                      pThis->bEnd0Stage=MGC_END0_STAGE_STATUSIN;
-+              }
-+              break;
-+              
-+      default: /* IT WAS STALLED */
-+              DBG(-1002, "recovering from stall? ep0stage=%s\n", 
-+                      decode_ep0stage(pThis->bEnd0Stage));
-+              pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;                   
-+              break;
-+    }
-+              
-+    DBG(3, "==>\n");
-+}
++      .start_port_reset =     NULL,
++};
 +
++/* -------------------------------------------------------------------- */
 +
-+/* ---------------------------------------------------------------------- */
 +
-+/**
-+ * Handle ep0 in receive state. Called to start a receie and on each interrupt
-+ * when receiving data on ep0. 
++/*
++ * Scan the urb returning the urb the precede a give urb. When in the musb_hcd
++ * queue, urbs are linked to each other using the pUrb->hcdpriv field; the last
++ * urb has pUrb->hcpriv=NULL
++ * @param pThs the controller
++ * @param pUrb the urbn to search for
++ * @return NULL or pUrb1 such that (pUrb1->hcpriv==pUrb)
++ *
 + */
-+int ep0_rxstate(void) {
-+    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
-+    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]);
-+    struct usb_request *pRequest=MGC_CurrentRequest(pEnd);
-+      
-+      /* nothign for now */
-+    DBG(-1002, "<==\n");
-+      
-+    if ( pRequest->actual==0 ) {
-+              /* ack the request first */
-+              DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
-+              spin_lock(&pThis->Lock);
-+              MGC_SelectEnd(pBase, 0);
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                      MGC_M_CSR0_P_SVDRXPKTRDY);
-+              spin_unlock(&pThis->Lock);
-+    }
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_LOCKED(&pEnd->Lock); 
-+#endif
-+      
-+    DBG(-1002, "==>\n");      
-+      
-+    return 0;
++static struct urb* mgc_hcd_urb_find_prev(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) {
++      struct urb* temp=pQueue->urb_queue_head;
++
++      if ( temp==pUrb ) {
++              return pQueue->urb_queue_head; /* to make clear */
++      }
++
++      while ( temp!=NULL && temp->hcpriv!=pUrb) {
++              temp=(struct urb*)temp->hcpriv;
++      }
++
++      return temp;
 +}
 +
-+/**
-+ * Handle ep0 in transmit state. Called to start a receie and on each interrupt
-+ * when transmitting data on ep0. 
++/*
++ * push back an urb to the hcd queue.
++ * @param pThs the controller
++ * @param pUrb the urb push in queue
++ * @return <0 if error, 0 when the queue is idle, >0 otherwise
 + */
-+int ep0_txstate(void) 
-+{
-+    unsigned long flags;
-+    MGC_LinuxCd* pThis=MGC_GetDriverByName(NULL);
-+    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_GadgetLocalEnd* pEnd = &(MGC_aGadgetLocalEnd[0]);
-+    struct usb_request *pRequest=MGC_CurrentRequest(pEnd);
-+    uint16_t wCsrVal = MGC_M_CSR0_TXPKTRDY;
-+    uint8_t* pFifoSource; 
-+    uint8_t wFifoCount; 
-+      
-+    DBG(-1002, "<==\n"); 
-+      
++inline static int mgc_hcd_urb_pushback(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) {
 +#ifdef MUSB_PARANOID
-+    if ( !pThis || !pRequest )  {
-+        ERR("pThis=%p, pRequest=%p", pThis, pRequest); 
-+        return -EINVAL;
-+    }
-+#endif
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); 
-+      ASSERT_SPINLOCK_LOCKED(&pEnd->Lock); 
++      if (!pUrb) {
++              ERR("*** cannot push NULL urb\n");
++              return -ENODEV;
++      }
 +#endif
-+      
-+      spin_lock_irqsave(&pThis->Lock, flags);
-+      MGC_SelectEnd(pBase, 0);
-+      
-+    if ( pRequest->actual==0 ) {
-+              /* ack the request first */
-+              DBG(4, "acking request %s\n", decode_csr0(MGC_M_CSR0_P_SVDRXPKTRDY) );
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                      MGC_M_CSR0_P_SVDRXPKTRDY);
-+    }
-+      
-+    /* load the data */               
-+    pFifoSource = (uint8_t*)pRequest->buf+pRequest->actual;
-+    wFifoCount =min((int)MGC_END0_FIFOSIZE, (int)(pRequest->length-pRequest->actual));
-+    MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoSource);
-+    pRequest->actual+=wFifoCount; /* done */
-+      
-+    /* update the flags */
-+    if ( wFifoCount < MUSB_MAX_END0_PACKET ) {
-+              wCsrVal |= MGC_M_CSR0_P_DATAEND;
-+              pRequest->status=0; /* done */
-+    } 
-+    
-+    /* send it out! (this will trigger the ep0 completition IRQ) 
-+       * serviced in interrupt_complete()  
-+       */
-+    DBG(4, "wrote wFifoCount=%d bytes, wCsrVal=%s\n", wFifoCount, 
-+              decode_csr0(wCsrVal) );
-+    MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);
-+    spin_unlock_irqrestore(&pThis->Lock, flags);
-+      
-+    DBG(-1002, "==>\n"); 
-+    return 0;
-+}
 +
-+/* ---------------------------------------------------------------------- */
++      pQueue->urb_queue_count++;
++      pUrb->hcpriv=pQueue->urb_queue_head;
++      pQueue->urb_queue_head=pUrb;
++      if ( !pQueue->urb_queue_tail ) {
++              pQueue->urb_queue_tail=pUrb;
++      }
 +
-+/**
-+ * Handle ep0 interrupt of a device, lock & release pThis. This is the main 
-+ * entry point of the gadget Ep0 handling code.
-+ * @param pThis the controller
++      return 0;
++}
++
++/*
++ * Queue at an urb to the hcd queue.
++ * @return <0 if error, 0 when the queue is idle, >0 otherwise
 + */
-+uint8_t MGC_HdrcServiceFunctionEp0(MGC_LinuxCd* pThis)
-+{
-+    uint16_t wCsrVal; /* */
-+    uint16_t wCount; /* bytes available */
-+    const uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    
-+    DBG(2, "<==\n");
-+      
-+    spin_lock(&pThis->Lock);
-+    MGC_SelectEnd(pBase, 0); /* select ep0 */
-+    wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0);
-+    wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
-+      
-+    DEBUG_CODE(4, { uint8_t myaddr=MGC_Read8(pBase, MGC_O_HDRC_FADDR); \
-+        uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL); \
-+              printk(KERN_INFO "%s: wCrsVal=0x%x, wCount=%d, myaddr=%0x, mode=%s, ep0stage=%s\n", \
-+              __FUNCTION__, wCsrVal, wCount, myaddr, decode_devctl(devctl), \
-+              decode_ep0stage(pThis->bEnd0Stage) ); } );
-+      
-+    /* I sent a stall.. need to acknowledge it now.. */
-+    if(wCsrVal & MGC_M_CSR0_P_SENTSTALL) {    
-+              DBG(-1002, "acking stall while in ep0stage=%s\n",
-+                      decode_ep0stage(pThis->bEnd0Stage));
-+              
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                      wCsrVal & ~MGC_M_CSR0_P_SENTSTALL );    
-+              pThis->bEnd0Stage=MGC_END0_STAGE_SETUP; 
-+    }
-+      
-+    /* setup ended prematurely, abort it  */
-+    if (wCsrVal & MGC_M_CSR0_P_SETUPEND) {    
-+              DBG(-1002, "acking setupend while in ep0stage=%s\n",
-+                      decode_ep0stage(pThis->bEnd0Stage));
-+              
-+              /* clearing it */
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                      MGC_M_CSR0_P_SVDSETUPEND );
-+              pThis->bEnd0Stage=MGC_END0_STAGE_SETUP; 
-+    }
-+      
-+    spin_unlock(&pThis->Lock);    
-+      
-+    /* handle completition interrupt */
-+    if ( !wCsrVal && !wCount ) {
-+              handle_ep0_completition_irq();
-+              return TRUE;
-+    }
-+      
-+    switch( pThis->bEnd0Stage ) {
-+              /* done transmitting */
-+      case MGC_END0_STAGE_STATUSOUT:
-+      case MGC_END0_STAGE_STATUSIN:
-+              mgc_complete_ep0_request();
-+              break;
-+    }    
-+    
-+    switch( pThis->bEnd0Stage ) {     
-+              /* im alrewady writing to host, TX state, 
-+               * sequence #1 initiated during the setup 
-+               */
-+      case MGC_END0_STAGE_TX: 
-+              if (  wCsrVal & MGC_M_CSR0_TXPKTRDY  ) {
-+                      DBG(-1001, "MGC_END0_STAGE_TX\n");
-+                      ep0_txstate();
-+              } break;
-+              
-+              /* im alrewady receiving from host, RX state, 
-+               * sequence #2 initiated during the setup 
-+               */
-+      case MGC_END0_STAGE_RX: 
-+              if (  wCsrVal & MGC_M_CSR0_RXPKTRDY  ) {
-+                      DBG(-1001, "MGC_END0_STAGE_RX\n");
-+                      ep0_rxstate();      
-+              }
-+              break;
-+              
-+              /* received from host, RX State, header */
-+      case MGC_END0_STAGE_SETUP:      
-+              if ( wCsrVal & MGC_M_CSR0_RXPKTRDY ) { 
-+                      int count=0, handled=0;
-+                      
-+                      count=MGC_ReadUSBControlRequest(pThis, wCount);
-+                      if ( count<0 ) { 
-+                              /* ack the request */
-+                              ERR("error reading the control request: this is bad (tm)\n");
-+                      } else if ( 0==count ) { /* I got the full packet, GREAT! */
-+                              struct usb_ctrlrequest *pControlRequest=(struct usb_ctrlrequest*)
-+                                      pThis->pEnd0Buffer;
-+                              
-+                              DBG(-1002, "%s\n", decode_request(pControlRequest)); 
-+                              
-+                              /* sequence #3 */
-+                              if ( is_zerodata_request(pControlRequest) ) {
-+                                      uint16_t wCsrVal= MGC_M_CSR0_P_SVDRXPKTRDY
-+                                              | MGC_M_CSR0_P_DATAEND;
-+                                      
-+                                      pThis->bEnd0Stage = MGC_END0_STAGE_STATUSIN;
-+                                      handled=service_zero_data_request(pThis, 
-+                                              pControlRequest);
-+                                      if ( handled<0 && handled!=-EOPNOTSUPP ) {                      
-+                                              wCsrVal |= MGC_M_CSR0_P_SENDSTALL;    
-+                                      }
-+                                      
-+                                      /* ack the request */
-+                                      DBG(3, "handled=%d, wCsrVal=%s, ep0stage=%s\n", handled, 
-+                                              decode_csr0(wCsrVal), 
-+                                              decode_ep0stage(pThis->bEnd0Stage) );
-+                                      
-+                                      spin_lock(&pThis->Lock);
-+                                      MGC_SelectEnd(pBase, 0);
-+                                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);   
-+                                      spin_unlock(&pThis->Lock);                              
-+                              } else {
-+                                      /* sequence #1 */
-+                                      if ( is_tx_request(pControlRequest) ) {
-+                                              /* write to host, a request is posted on ep0 */                                             
-+                                              pThis->bEnd0Stage=MGC_END0_STAGE_TX;
-+                                              handled=service_tx_request(pControlRequest);
-+                                              /* sequence #2, a request is posted on ep0 */
-+                                      } else if ( is_rx_request(pControlRequest) ) {
-+                                              pThis->bEnd0Stage=MGC_END0_STAGE_RX;                                                
-+                                              handled=service_rx_request(pControlRequest);
-+                                      }
-+                                      
-+                                      if ( handled<0 ) {
-+                                              /* stall it!!! application stall */                                                     
-+                                              spin_lock(&pThis->Lock);
-+                                              MGC_SelectEnd(pBase, 0);
-+                                              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                                                      MGC_M_CSR0_P_SVDRXPKTRDY | MGC_M_CSR0_P_SENDSTALL);
-+                                              spin_unlock(&pThis->Lock);
-+                                      }                                                                       
-+                              }
-+                              
-+                      }                       
++inline static int mgc_hcd_queue_urb(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) {
++      int status=0;
++
++#ifdef MUSB_PARANOID
++      if (!pUrb) {
++              ERR("*** cannot queue NULL urb\n");
++              return -ENODEV;
++      }
++#endif
++
++      spin_lock(&pQueue->urb_queue_lock);
++      if ( !pQueue->urb_queue_head ) { /* idle */
++              pQueue->urb_queue_head=pUrb;
++              pQueue->urb_queue_tail=pUrb;
++              pQueue->urb_queue_count++;
++      } else { /* queue */
++              if ( pQueue->urb_queue_tail ) {
++                      ((struct urb*)pQueue->urb_queue_tail)->hcpriv=pUrb;
++                      pQueue->urb_queue_tail=pUrb;
++                      pQueue->urb_queue_count++;
++                      status=pQueue->urb_queue_count; /* queued */
 +              } else {
-+                      
++                      ERR("*** pThis->urb_queue_head=%p, pThis->urb_queue_tail=%p; this is BAD (TM)\n",
++                              pQueue->urb_queue_head, pQueue->urb_queue_tail);
++
++                      status=-ENODEV;
 +              }
-+              break;
-+              
-+              
-+              /* handle the application stall on Ep0 */
-+      default: 
-+              {
-+              uint16_t wCsrVal = MGC_M_CSR0_P_SENDSTALL;
++      }
++      spin_unlock(&pQueue->urb_queue_lock);
 +
-+              switch ( pThis->bEnd0Stage & ~MGC_END0_STAGE_STALL_BIT ) {
++      return status;
++}
 +
-+              case MGC_END0_STAGE_TX:
-+                      wCsrVal|=MGC_M_CSR0_TXPKTRDY;
-+                      break;
++/*
++ * top of the scheduler queue.
++ * @param pThis the controller
++ * @return next urb to be queued to hardware, NULL if idle
++ */
++inline static struct urb* mgc_hcd_urb_top(mgc_hcd_urb_queue *pQueue) {
++      return pQueue->urb_queue_head;
++}
 +
-+              case MGC_END0_STAGE_RX:
-+                      wCsrVal|=MGC_M_CSR0_RXPKTRDY;
-+                      break;
++/*
++ *
++ */
++inline static struct urb* mgc_hcd_urb_pop(mgc_hcd_urb_queue *pQueue) {
++      struct urb* pUrb=pQueue->urb_queue_head;
 +
++      if ( pUrb ) {
++              pQueue->urb_queue_count--;
++              pQueue->urb_queue_head=pUrb->hcpriv;
++              if ( !pQueue->urb_queue_head ) {
++                      pQueue->urb_queue_tail=NULL;
 +              }
-+              
-+              DBG(3, "Application stall from ep0stage=%s\n", 
-+                      decode_ep0stage(pThis->bEnd0Stage));
-+              spin_lock(&pThis->Lock);
-+              MGC_SelectEnd(pBase, 0);
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wCsrVal);   
-+              spin_unlock(&pThis->Lock);               
-+              
-+              pThis->bEnd0Stage = MGC_END0_STAGE_SETUP;       
-+              } 
-+              break;
-+    } 
-+      
-+    return 1;
++      } else {
++              pQueue->urb_queue_count=0; /* paranoid */
++              pQueue->urb_queue_head=NULL;
++              pQueue->urb_queue_tail=NULL;
++      }
++
++      return pUrb;
 +}
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/Kconfig ../new/linux-2.6.20/drivers/usb/nomadik/Kconfig
---- linux-2.6.20/drivers/usb/nomadik/Kconfig   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/Kconfig    2008-07-04 23:45:35.000000000 +0530
-@@ -0,0 +1,176 @@
-+#
-+# INVENTRA USB Host Controller Drivers
-+#
-+# $Revision: 1.13 $
-+#
-+config USB_INVENTRA_HCD
-+      depends on USB
-+      tristate 'Inventra HCD Controller Support'
-+      help
-+        Say Y here if you have the Inventra USB board on your system.
 +
-+        If you do not know what this is, please say N.
++/* ------------------------------------------------------------------- */
 +
-+        To compile this driver as a module, choose M here:  the 
-+        module will be called musb-hcd (host controller) or
-+        musb-gcd (gadget controller) or musb-icd (interface
-+        controller when OTG is enabled).
-+        
-+choice
-+prompt "Controller Mode"
-+depends on USB_INVENTRA_HCD 
-+default USB_INVENTRA_HCD_HOST
++static void mgc_hcd_stop(struct usb_hcd *hcd)
++{
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
 +
-+config USB_INVENTRA_HCD_HOST
-+      bool 'Host Mode'
++#ifdef MUSB_PARANOID
++      if ( !pThis ) {
++              ERR("pThis is null");
++              return;
++      }
++#endif
 +
-+config USB_INVENTRA_HCD_GADGET_API
-+      bool 'GADGET API'
-+      help
-+        Say Y here if you want support for GADGET API; the module will 
-+        be called musb-gcd.ko
-+        
-+        You will need to select the Inventra Controller in the Gadget 
-+        subsection.
++    mgc_hdrc_disable(pThis);
++}
 +
-+        If you do not know what this is, please say N.
++static int __devinit mgc_hcd_start(struct usb_hcd *hcd)
++{
++      int rc=0;
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
 +
-+config USB_INVENTRA_HCD_OTG
-+      bool 'On The Go'
-+      help
-+        Say Y here if you want support for USB On The Go. 
++      DBG(2, "<== Starting hcd=%p\n", hcd);
 +
-+        The module will be called musb-icd.ko
-+        
-+        If you do not know what this is, please say N.
++#ifdef MUSB_PARANOID
++      if ( !pThis ) {
++              ERR("pThis is null");
++              return -ENODEV;
++      }
++#endif
 +
-+#config USB_INVENTRA_HCD_GSTORAGE
-+#     bool 'Storage Demo'
-+#     help
-+#       Say Y here if you want the hcd driver compiled as
-+#       like a mass storage device.
-+#
-+#       If you do not know what this is, please say N.
++      hcd->state = HC_STATE_RUNNING;
++      pThis->pBus = &hcd->self;
++    pThis->pBus->bus_name = pThis->aName;
++      pThis->pBus->hcpriv = (void *)hcd;
 +
-+config USB_INVENTRA_HCD_OTG_GSTORAGE
-+      bool 'OTG Storage Demo'
-+      help
-+        Say Y here if you want the hcd driver compiled as
-+        a mass storage device with OTG support.
++      rc=mgc_init_root_hub(pThis);
++      if ( rc==0 ) {
++              DBG(3, "New bus @%p\n", pThis->pBus);
++      } else {
++              ERR("*** could not initialize the root hub\n");
++              return -ENODEV;                                                            /* return if not success !! */
++      }
 +
-+        If you do not know what this is, please say N.
++      DBG(2, "==> rc=0\n");
++      return 0;
++}
 +
++/* ------------------------------------------------------------------- */
 +
-+endchoice
++/**
++ *
++ */
++mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis) {
++      return &pThis->LocalQueue;
++}
 +
-+config USB_INVENTRA_STATIC_CONFIG
-+      depends on USB_INVENTRA_HCD
-+      bool 'Use static config (-DMUSB_STATIC_CONFIG)'
-+      default true
-+      help
-+        Use the static configuration file. File must be called
-+        hdrc_cnf.h and mut be generated from the board configuration
-+        file. Please check directory install/configs for examples.
++/* ------------------------------------------------------------------- */
 +
-+        If usure please say please say N and make sure your controller 
-+        is using the standard configuration HB+8E(8K)+8DMA
++/**
++ *
++ */
++void mgc_hcd_flush(MGC_LinuxCd* pThis) {
++      struct urb* pUrb;
++      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
 +
-+          NOTE: Make sure your board is using the corresponding core.
++      DBG(2, "<== flushing\n");
++      spin_lock(&pQueue->urb_queue_lock);
++      do      {
++              pUrb=mgc_hcd_urb_pop(pQueue);
++              if ( pUrb ) {
++                      DBG(3, "flushed=%p\n", pUrb);
++                      pUrb->status=-ENOENT;
++                      usb_kill_urb(pUrb);
++              } else {
 +
-+config USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
-+      depends on USB_INVENTRA_STATIC_CONFIG
-+      string 'Endpoint FIFO configuration file (Advanced)'
-+      default ''
-+      help
-+        Specify the file with the endpoint fifo configuration (Advanced). The
-+        file shoud define an struct MUSB_EpFifoDescriptor array called
-+        MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] containig the end point FIFO 
-+        configuration specs. Check musbdefs.h for more informations;
++              }
++      } while ( pUrb );
++      spin_unlock(&pQueue->urb_queue_lock);
++      DBG(2, "==>\n");
++}
 +
-+              struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS]={
++/**
++ *
++ */
++void mgc_hcd_complete_urb(MGC_LinuxCd* pThis, struct urb *pUrb)
++{
++      mgc_hcd_get_urb_queue(pThis)->urb_exec_count--;
 +
-+                      {}, /* EP0 use the default */
-+                      { MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
-+                      { MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 }
++      usb_hcd_giveback_urb(musbstruct_to_hcd(pThis), pUrb); /* this call complete */
 +
-+              };
++      /*printk("Yes completed:%d\n",usb_pipeendpoint(pUrb->pipe));*/
++}
 +
-+        gives the endpoint 0 its default value, and defines ep1/ep2 as bulk tx/rx
-+        512 bytes in size each with double buffering disabled. The FIFO memory 
-+        allocated with this confoguration is 64+512+512=1088 bytes      
++/**
++ * Schedule the urb to the hardware.
++ * @param pThis the controller
++ */
++int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis)
++{
 +
-+config USB_INVENTRA_DMA
-+      depends on USB_INVENTRA_HCD
-+      bool 'Use DMA when possible (-DMUSB_DMA)'
-+      default true
-+      help
-+        Enable DMA transfers when DMA is possible
 +
-+config USB_INVENTRA_MUSB_HAS_AHB_ID
-+      depends on USB_INVENTRA_HCD
-+      bool 'Enable AHB_ID (-DMUSB_AHB_ID)'
-+      default false
-+      help
-+        Disable auto core identification.
++      int rc=0, nEnd;
++      struct urb*pUrb;
++      MGC_LinuxLocalEnd *pEnd;
++      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
 +
-+          NOTE: Make sure your board is using the corresponding core.
-+        
-+config USB_INVENTRA_MUSB_HDR_CCNF_FILE
-+      depends on USB_INVENTRA_HCD
-+      string 'Custom config file (Advanced)'
-+      default ''
-+      help
-+        Specify a custom config file (Advanced)
++      do {
 +
-+config USB_INVENTRA_MUSB_BOARD_FILE
-+      depends on USB_INVENTRA_HCD
-+      string 'Custom board file (Advanced)'
-+      default ''
-+      help
-+        Specify a custom board file (Advanced)
-+        
-+config USB_INVENTRA_TPL
-+      depends on USB_INVENTRA_HCD_OTG
-+      tristate '    Use TPL (-DMUSB_TPL)'
-+      default false
-+      help
-+        Enable Target Peripheral List
++              DBG(2, "<== pQueue->urb_queue_count=%d, pQueue->urb_exec_count=%d\n",
++                              pQueue->urb_queue_count, pQueue->urb_exec_count);
 +
-+config USB_INVENTRA_PROC_TESTMUSB
-+      depends on USB_INVENTRA_HCD && PROC_FS && ( USB_INVENTRA_HOSTMODE || USB_INVENTRA_OTG )
-+      bool 'Enable /proc/testmusbhdrc*'
-+      default false
-+      help
-+        Add /proc/testmusbhdrc<num> to control the 
++              if ( !MUSB_IS_HST(pThis) ) {
++                      break; /* nothing to do */
++              }
 +
-+        NOTE: this is different from supporting /proc filesystem; 
++              spin_lock(&pQueue->urb_queue_lock);
++              pUrb=mgc_hcd_urb_pop(pQueue);
++              if ( !pUrb ) {
++                      DBG(3, "scheduler is idle\n");
++                      spin_unlock(&pQueue->urb_queue_lock);
++                      break;
++              }
 +
-+        If you do not know what this is, please say N.          
++              DBG(3, "pUrb=%p, (proto=%s)\n", pUrb, decode_urb_protocol(pUrb));
++              nEnd=mgc_hcd_find_end(pThis, pUrb);
++              if ( nEnd<0 ) {
++                      spin_unlock(&pQueue->urb_queue_lock);
++                      ERR("***> no resource for proto=%s, addr=%d, end=%d\n",
++                         decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe),
++                         usb_pipeendpoint(pUrb->pipe));
++                      if ( !pQueue->urb_exec_count ) {
++                              /* push it back and give it another chance */
++                              mgc_hcd_urb_pushback(pQueue, pUrb);
++                              ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n",
++                                      pUrb, nEnd, rc);
++                              break;
++                      } else {
++                              /* the urb will never be scheduled, kill it and move to next */
++                              usb_kill_urb(pUrb);
++                              ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n",
++                                      pUrb, nEnd);
++                              continue;
++                      }
++              }
 +
-+config        USB_INVENTRA_HCD_CUSTOM_OPTIONS
-+      depends on USB_INVENTRA_HCD
-+      string 'Custom compile options (Advanced)'
-+      default ''
-+      help
-+        Specify a custom compile options (Advanced)
-+        
-+config USB_INVENTRA_HCD_POLLING
-+      depends on USB_INVENTRA_HCD
-+      bool 'Use polling driver (debug only)'
-+      default false
-+      help
-+        Enable polling mode (events won't be triggered by IRQs); usefule
-+        for debugging.
++              pEnd=&pThis->aLocalEnd[nEnd];
++              if ( mgc_ep_is_idle(pEnd) ) {
++                      DBG(3, "(%d/%d) pUrb=%p, nEnd=%d, %s \n",
++                              pQueue->urb_queue_count, pQueue->urb_exec_count,
++                              pUrb, nEnd, mgc_ep_is_idle(pEnd)?"idle":"busy");
++                      spin_unlock(&pQueue->urb_queue_lock);
++                      rc=mgc_schedule_urb(pThis, pEnd, pUrb);
++                      if ( rc!=0 ) {
++                              if ( !pQueue->urb_exec_count ) {
++                                      /* the urb will never be scheduled, kill it */
++                                      usb_kill_urb(pUrb);
++                                      ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n",
++                                              pUrb, nEnd);
++                              } else {
++                                      /* push it back and give it another chance */
++                                      mgc_hcd_urb_pushback(pQueue, pUrb);
++                                      ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n",
++                                              pUrb, nEnd, rc);
++                              }
++                      } else {
++                              /* removed from the queue, scheduled to hardware */
++                              pQueue->urb_exec_count++;
++                              break;
++                      }
++              } else { /* too fast ? */
++                      mgc_hcd_urb_pushback(pQueue, pUrb);
++                      spin_unlock(&pQueue->urb_queue_lock);
++                      DBG(3, "???> cannot schedule pUrb=%p to nEnd=%d yet (busy with pEnd->pCurrentUrb=%p)\n",
++                              pUrb, nEnd, MGC_GetCurrentUrb(pEnd));
++                      break;
++              }
 +
-+        If you do not know what this is, please say N.          
++      } while ( 1 );
 +
-+config        USB_INVENTRA_HCD_LOGGING
-+      depends on USB_INVENTRA_HCD
-+      int  'Logging Level (0 - none / 3 - annoying)'
-+      default 0 
-+      help
-+        Set the logging level. 0 disable the debugging altogether (no 
-+        code will be added to the)
-+        
-+          If you do not know what this is, please say N.        
++      DBG(2, "==> rc=%d\n", rc);
++      return rc;
++}
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/logx ../new/linux-2.6.20/drivers/usb/nomadik/logx
---- linux-2.6.20/drivers/usb/nomadik/logx      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/logx       2008-07-04 23:45:36.000000000 +0530
-@@ -0,0 +1 @@
-+make: *** No rule to make target `vmlinux'.  Stop.
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/Makefile ../new/linux-2.6.20/drivers/usb/nomadik/Makefile
---- linux-2.6.20/drivers/usb/nomadik/Makefile  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/Makefile   2008-07-04 23:45:36.000000000 +0530
-@@ -0,0 +1,97 @@
-+MUSB_VERSION=2.2.2
-+HCD_TYPE=hcd
++/* ------------------------------------------------------------------ */
 +
++/**
++ * Find a local endpoint suitable for transmitting the given urb minimizing
++ * the reconfigurations. The best localendpoint is selceted using the following
++ * criterion:
++ * - ep0 is used for control Urbs
++ * - for bulk Urbs only (when available) choose the Tx or Rx reserved end
++ * - determine direction, size and traffic type
++ *
++ * @param pThis instance pointer
++ * @param pURB URB pointer
++ * @return suitable local endpoint
++ * @return -1 if nothing appropriate
++ */
++static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb)
++{
++      return mgc_linux_find_end(pThis, pUrb);
++}
 +
-+obj-$(CONFIG_USB_INVENTRA_HCD) += musb-hcd.o
++/**
++ * Submit an urb to our HCD driver. The urb will be queued and (sooner or later)
++ * scheduled to the hardware driver. The Urb had been queued to the ep from the
++ * kernel, DON'T modify with the urb_list otherwise BAD THINGS WILL
++ * HAPPEN (TM).
++ * @param hcd the HCD driver
++ * @param pURB URB pointer
++ */
++static int mgc_hcd_submit_urb(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
++      struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags)
++{
 +
++      int rc=0;
 +
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
 +
-+ifeq ($(CONFIG_PROC_FS),y)
-+      musb-$(HCD_TYPE)-objs += musb_procfs.o
-+endif
++      if(Urb_status==1)
++      {
++              pUrb->status=-ENODEV;
++              rc=-ENODEV;
++              return rc;
++      }
 +
++#ifdef MUSB_PARANOID
++              if ( !pThis ) {
++                      ERR("***==> pThis is null\n");
++                      return -ENODEV;
++              }
 +
-+ifneq ($(CONFIG_USB_INVENTRA_MUSB_BOARD_FILE),"")
-+        EXTRA_CFLAGS += -DMUSB_BOARD_FILE
-+endif
-+       
-+ifneq ($(CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE),"")
-+EXTRA_CFLAGS += -DMUSB_HDR_CCNF_FILE
-+endif
-+                
-+ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
-+ifneq ($(CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE),"")
-+EXTRA_CFLAGS += -DMUSB_EPFIFOCONFIG_FILE
-+endif
-+endif
++              if ( !pUrb ) {
++                      ERR("***==> pUrb is NULL\n");
++                      return -ENODEV;
++              }
 +
-+ifneq ($(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS),"")
-+EXTRA_CFLAGS += $(CONFIG_USB_INVENTRA_HCD_CUSTOM_OPTIONS)
-+endif
++              pUrb->hcpriv=NULL; /* paranoid!! */
++              pUrb->status=-EINPROGRESS; /* paranoid!! */
++#endif
 +
++              DBG(2, "<== submit pUrb=%p, pUrb->hcpriv=%p, (proto=%s), bRemoteAddress=%d, bRemoteEnd=%d\n",
++                              pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe),
++                              usb_pipeendpoint(pUrb->pipe));
 +
-+      EXTRA_CFLAGS += -DMUSB_C_DYNFIFO_DEF
-+      EXTRA_CFLAGS += -DMUSB_EPDISCRIPTORS_FILE
++              if ( pUrb->hcpriv ) {
++                      ERR("***==> on submission pUrb->hcpriv=%p; this is BAD (TM)\n", pUrb->hcpriv);
++                      return -ENODEV;
++              }
 +
-+ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
-+      EXTRA_CFLAGS += -DMUSB_AHB_ID
-+endif
++              {
++                      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
++                      int count=mgc_hcd_queue_urb(pQueue, pUrb);
++                      if ( count<0 ) {
++                              rc=-ENODEV;
++                      } else if ( count==0 ) {
++                              rc=mgc_hcd_schedule_urb(pThis);
++                              /*printk("Queued for scheduled:%d\n",usb_pipeendpoint(pUrb->pipe));*/
++                      } /* count>0 it's been queued */
++                      /*else
++                      {
++                              printk("Count> 0:%d\n",usb_pipeendpoint(pUrb->pipe));
++                      }*/
++              }
 +
-+ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
-+      EXTRA_CFLAGS += -DMUSB_DMA
-+      musb-$(HCD_TYPE)-objs += musbhsdma.o
-+endif
 +
-+EXTRA_CFLAGS += -DMUSB_VERSION='"$(MUSB_VERSION)"' -DHCD_NAME=$(HCD_NAME)
 +
-+ifeq ($(CONFIG_USB_INVENTRA_STATIC_CONFIG),y)
-+      EXTRA_CFLAGS += -DMUSB_STATIC_CONFIG
-+endif
++      DBG(2, "==> rc=%d\n", rc);
++      return rc;
++}
 +
-+ifeq ($(CONFIG_USB_INVENTRA_HCD_OTG),y)
-+  GADGET_API=y
-+  MUSB_HOSTMODE=y  
-+  EXTRA_CFLAGS += -DMUSB_OTG  
-+  musb-$(HCD_TYPE)-objs += otg.o
-+endif
++/**
++ * unlink an urb, hcd version. First check if the urb was queued to the
++ * hardware, if not search it in the hcd queue, if not... this is BAD
++ * (TM).
++ * @param hcd the HCD driver
++ * @param pURB URB pointer
++ */
++static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb)
++{
++      int rc=0;
++      MGC_LinuxLocalEnd* pEnd;
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
++      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
 +
-+ifeq ($(CONFIG_USB_INVENTRA_HCD_GADGET_API),y)
-+  GADGET_API=y
-+endif
++#ifdef MUSB_PARANOID
++      if ( !pThis ) {
++              ERR("pThis is null");
++              return -ENODEV;
++      }
++#endif
 +
-+#ifneq ($(GADGET_API),)
++    DBG(-1, "<== Unlinking pUrb=%p (%s), pUrb->hcpriv=%p\n", pUrb,
++              decode_urb_protocol(pUrb), pUrb->hcpriv);
++      spin_lock(&pQueue->urb_queue_lock);
++      pEnd=mgc_ep_find_end(pThis, pUrb);
++      if ( pEnd ) { /* was submitted */
++              spin_unlock(&pQueue->urb_queue_lock);
++              rc=mgc_unlink_urb(pThis, pUrb);
++      } else { /* remove the urb */
++              struct urb* prev;
++              prev=mgc_hcd_urb_find_prev(pQueue, pUrb);
++              if ( prev==NULL ) { /* not mine! */
++                      ERR("*** cannot find pUrb=%p: is not mine! this is bad (tm)\n",
++                              pUrb);
++              } else if ( prev==pUrb ) { /* list head */
++                      pQueue->urb_queue_head=prev->hcpriv;
++                      if ( pQueue->urb_queue_tail==prev ) {
++                              pQueue->urb_queue_tail=prev->hcpriv;
++                      }
++              } else {
++                      prev->hcpriv=pUrb->hcpriv;
++              }
++              spin_unlock(&pQueue->urb_queue_lock);
++      }
 +
-+#  GADGET_DIRS=y
-+#    EXTRA_CFLAGS += -DMUSB_GADGET 
-+#      musb-$(HCD_TYPE)-objs += musb_gadgetcommon.o g_ep0.o musb_gadget.o
-+#endif
++      DBG(2, "==> Unlinked urb=%p\n", pUrb);
++      return rc;
++}
 +
++/**
++ * return the frame number
++ * @param hcd the HCD driver
++ * @return the frame number
++ */
++static int mgc_hcd_get_frame_number(struct usb_hcd *hcd) {
++      return mgc_get_frame_number( hcd_to_musbstruct(hcd) );
++}
 +
-+ifeq ($(CONFIG_USB_INVENTRA_HCD_HOST),y)
-+      MUSB_HOSTMODE=y
-+endif
++/**
++ * Interrupt service routine, redirect it to the main routine/
++ * @param hcd the HCD driver
++ * @param r the pt registers
++ * @return
++ */
++static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd)
++{
++      return mgc_linux_isr( hcd_to_musbstruct(hcd) );
++}
 +
++/**
++ * @param hcd the HCD driver
++ * @param ep the endpoint to disable
++ */
++static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd,
++      struct usb_host_endpoint *ep)
++{
++   DBG(-1, "hw sync with ep=%d (%s) list_empty(&ep->urb_list)=%d\n",
++      0x7f&ep->desc.bEndpointAddress, (ep->desc.bEndpointAddress==0) ? "in/out"
++                      : (ep->desc.bEndpointAddress>=0x80)?"in":"out",
++                      list_empty(&ep->urb_list) );
 +
-+ifeq ($(MUSB_HOSTMODE),y)
-+  EXTRA_CFLAGS += -DMUSB_HOST 
-+  musb-$(HCD_TYPE)-objs += musb_virthub.o musb_host.o musb-hcd.o musb_plat_uds.o musb_bus_direct.o  musb_epfifocfg.o musb_ioctl.o nomadik_udc.o otg_pwm.o otg_func.o
++   DBG(2, "<== disable endpoint %d (%s)\n", 0x7f&ep->desc.bEndpointAddress,
++              (ep->desc.bEndpointAddress==0) ? "in/out"
++                      : (ep->desc.bEndpointAddress>=0x80)?"in":"out");
 +
-+endif
++   DBG(2, "==>disabled endpoint %d\n", 0x7f&ep->desc.bEndpointAddress);
++}
 +
-+ifndef DEBUG
-+  DEBUG=0
-+endif
++/* --------------------------------------------------------------- */
++/* Virtual hub */
++/* --------------------------------------------------------------- */
 +
-+MUSB_DEBUG=$(CONFIG_USB_INVENTRA_HCD_LOGGING)
-+ifeq ("$(strip $(MUSB_DEBUG))","")
-+      MUSB_DEBUG:=$(DEBUG)
-+endif
++/**
++ * Report the virtual hub status.
++ *
++ * @param hcd the hcd
++ * @param pData the buffer to store the status in
++ */
++static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData)
++{
++      MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd);
++      MGC_VirtualHub* pHub = &(pThis->RootHub);
++      int len = 0;
 +
++      spin_lock(&pHub->Lock);
++      len = mgc_rh_port_status(pHub, pData);
++    pHub->bIsChanged = FALSE;
++      spin_unlock(&pHub->Lock);
++      DBG(5, "len=%d, status=%02x\n", len, pData[0]);
++      return len;
++}
 +
-+ifneq ($(MUSB_DEBUG),0)
-+      EXTRA_CFLAGS += -g
-+      musb-$(HCD_TYPE)-objs += musb_debug.o
-+endif
++/** MGC_VirtualhubControl Instead of MGC_VirtualHubSubmitUrb
++ * @param hcd the HCD driver
++ */
++static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++      u16 wIndex, char *pData, u16 wLength)
++{
++      MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd);
++      MGC_VirtualHub* pHub = &(pThis->RootHub);
++    uint8_t bPort = (uint8_t)(wIndex & 0xff) - 1;
++    uint16_t wSize = 0xffff;
++      int retval = 0;
++      int     ports = (pHub->bPortCount + 1);
 +
-+EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG) 
++      DBG("<==\n");
++      DBG("Setup_Data: bmReqtype-bmRequest=%04x | wValue=%x | wIndex=%x | wLength=%04x \n", \
++              typeReq, wValue, wIndex, wLength);
++      DBG("Setup_Data: wValue=%04x | wIndex=%04x | wLength=%04x | \n", \
++               wValue, wIndex, wLength);
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c
---- linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c  2008-08-08 19:15:21.000000000 +0530
-@@ -0,0 +1,371 @@
++      switch (typeReq) {
++              case ClearHubFeature:
++                      switch (wValue) {
++                              case C_HUB_LOCAL_POWER:
++                              case C_HUB_OVER_CURRENT:
++                                      wSize = 0;
++                                      break;
++                              default:
++                                      goto error;
++                      }
++                      break;
++              case ClearPortFeature:
++                      if (!wIndex || wIndex > ports)
++                              goto error;
++                      wIndex--;
++                      switch (wValue) {
++                              case USB_PORT_FEAT_ENABLE:
++                                      DBG("enable port %d\n", bPort);
++                                      pHub->pPortServices->pfSetPortEnable(
++                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_C_ENABLE:
++                                      DBG("ack enable port %d\n", bPort);
++                                      pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE;
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_SUSPEND:
++                                      DBG("suspend port %d\n", bPort);
++                                      pHub->pPortServices->pfSetPortSuspend(
++                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_C_SUSPEND:
++                                      DBG("ack suspend port %d\n", bPort);
++                                      pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND;
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_POWER:
++                                      DBG("feat feat power port %d\n", bPort);
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_C_CONNECTION:
++                                      DBG("ack connection port %d\n", bPort);
++                                      pHub->aPortStatusChange[bPort].wChange &= ~1;
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_C_OVER_CURRENT:
++                                      DBG("ack over current port %d\n", bPort);
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_C_RESET:
++                                      DBG("ack reset port %d\n", bPort);
++                                      pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET;
++                                      wSize = 0;
++                                      break;
++                              default:
++                                      goto error;
++                      }
++                      break;
++              case GetHubDescriptor:
++                      DBG("GET_CLASS_DESCRIPTOR()\n");
++                      pData[0] = 9;
++                      pData[1] = 0x29;
++                      pData[2] = pHub->bPortCount;
++                      /* min characteristics */
++                      pData[3] = 1;  /* invidual port power switching */
++                      pData[4] = 0;
++                      /* PowerOn2PowerGood */
++                      pData[5] = 50;
++                      /* no current */
++                      pData[6] = 0;
++                      /* removable ports */
++                      pData[7] = 0;
++                      /* reserved */
++                      pData[8] = 0xff;
++                      wSize = pData[0];
++                      break;
++              case GetHubStatus:
++                      /* hub status */
++                      memset(pData, 0, 4);
++                      wSize = 4;
++                      DBG("hub statusreport=%02x%02x%02x%02x\n",
++                              pData[0], pData[1], pData[2], pData[3]);
++                      break;
++              case GetPortStatus:
++                      if (!wIndex || wIndex > ports)
++                              goto error;
++                      /* port status/change report */
++                      memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2);
++                      memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange), 2);
++                      /* reset change (TODO: lock) */
++                      pHub->aPortStatusChange[wIndex-1].wChange = 0;
++                      wSize = 4;
++                      DBG("port status report=%02x%02x%02x%02x\n",
++                              pData[0], pData[1], pData[2], pData[3]);
++                      break;
++
++              case SetHubFeature:
++                      switch (wValue) {
++                              case C_HUB_OVER_CURRENT:
++                              case C_HUB_LOCAL_POWER:
++                                      break;
++                              default:
++                                      goto error;
++                      }
++                      break;
++              case SetPortFeature:
++                      if (!wIndex || wIndex > ports)
++                              goto error;
++                      switch (wValue) {
++                              case USB_PORT_FEAT_SUSPEND:
++                                      DBG("suspend port %d\n", bPort);
++                                      pHub->pPortServices->pfSetPortSuspend(
++                                              pHub->pPortServices->pPrivateData, bPort, TRUE);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND;
++                                      pHub->bIsChanged = TRUE;
++                                      wSize = 0;
++                                      break;
++                              case USB_PORT_FEAT_POWER:
++                                      DBG("power port %d\n", bPort);
++
++                                        #if 1
++                                              {
++                                                      int err;
++                                                      err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_0,STMPE2401_PRIMARY_FUNCTION);
++                                                      if (err != STMPE2401_OK)
++                                                    DBG("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_0);
++                                                      err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_0,STMPE2401_GPIO_OUT );
++                                                      if (err != STMPE2401_OK)
++                                                      DBG("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_0);
++                                                     err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_0, 0);
++                                                    if (err != STMPE2401_OK)
++                                                    DBG("Couldn't set STMPE GPIO12\n");
++
++                                              }
++                                      #endif
++                                      pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData,
++                                              bPort,TRUE);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER;
++                                      wSize = 0;
++
++                                      break;
++                              case USB_PORT_FEAT_RESET:
++                                      DBG("USB_Class set feature USB_PORT_FEAT_RESET Port_no:%d \n",
++                                              bPort);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET;
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
++                                      pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET;
++                                      pHub->bIsChanged = TRUE;
++
++                                      pHub->pPortServices->pfSetPortReset(
++                                              pHub->pPortServices->pPrivateData, bPort, TRUE);
++                                      wSize = 0;
++                                      break;
++                              default:
++                                      goto error;
++                      }
++                      break;
++
++              default:
++error:
++                      /* "protocol stall" on error */
++                      retval = -EPIPE;
++      }
++
++      DBG("==> retval=%d\n", retval);
++      return retval;
++}
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_host.c
+@@ -0,0 +1,2791 @@
 +/*
-+ * linux/drivers/usb/nomadik/musb_bus_direct.c
++ * linux/drivers/usb/nomadik/musb_host.c
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -192199,2885 +195406,2785 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_bus_direct.c ../new/linux-2.6
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/usb.h>
++
++#include <asm/uaccess.h>
++
++#ifdef CONFIG_USB_DEBUG
++    #define DEBUG
++#else
++    #undef DEBUG
++#endif
++
++#include <linux/usb.h>
 +
 +#include "musbdefs.h"
-+#include <asm/io.h>
++#include "musb_host.h"
++#include "../core/hub.h"
 +
-+#ifdef MUSB_BOARD_FILE
-+#include CONFIG_USB_INVENTRA_MUSB_BOARD_FILE
-+#else
-+#include "board.h"
++#ifdef MUSB_USE_HCD_DRIVER
++#define HAS_USB_TT_MULTI
++#include "../core/hcd.h"
 +#endif
 +
-+#ifndef MUSB_BOARD_DEFAULT_SIZE
-+#define MUSB_DEFAULT_ADDRESS_SPACE_SIZE 0x00001000
++/** how much to "scale" response timeouts */
++#define MUSB_MAX_RETRIES         8
++
++/*************************** Forwards ***************************/
++
++/* HCD helpers */
++static uint8_t find_first1(unsigned int nValue);
++static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
++static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
++static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis);
++int *Urb_test;
++extern int Urb_status;
++/**************************************************************************
++ *
++ **************************************************************************/
++
++#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY 0
 +#endif
 +
-+#ifdef MUSB_V26
-+#include <linux/device.h>
++#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN 0
 +#endif
 +
-+/****************************** sysfs stuff *****************************/
++#ifndef DEBUG
++#endif
 +
-+#define kobj_to_direct_driver(obj) container_of(obj, struct device_driver, kobj)
-+#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
++int mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY;
 +
-+/**************************** instance vars *****************************/
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE {  }
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE {  }
++#define MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP {  }
 +
-+#ifndef MUSB_USE_HCD_DRIVER
-+static int MGC_InstancesCount=0;
-+static MGC_LinuxCd** MGC_DriverInstances;
++/**************************************************************************
++ * Glue for virtual root hub
++**************************************************************************/
++
++#ifdef MUSB_CONFIG_PROC_FS
++/**
++ * Decode an host endpoint protocol.
++ * @param pUrn the uRb protocol shoudl be decoded
++ * @return a const char* to the name of the protocol.
++ */
++char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
++    char* pProto = "Err ";
++
++      switch(pThis->aLocalEnd[bEnd].bTrafficType) {
++              case PIPE_ISOCHRONOUS: pProto = "Isoc"; break;
++              case PIPE_INTERRUPT: pProto = "Intr"; break;
++              case PIPE_CONTROL: pProto = "Ctrl"; break;
++              case PIPE_BULK: pProto = "Bulk"; break;
++      }
++
++      return pProto;
++}
 +#endif
 +
-+void *g_pDevice;
-+/********************* under 26 thigs changes a bit *************************/
++/**
++ * Decode an urb protocol.
++ * @param pUrn the uRb protocol shoudl be decoded
++ * @return a const char* to the name of the protocol.
++ */
++char* decode_urb_protocol(struct urb* pUrb) {
++      static char buffer[8];
 +
-+#ifdef MUSB_V26
-+#if 1
-+struct device MGC_ControllerDevice =
-+{
++      if ( !pUrb ) {
++              strcpy(&buffer[0], "NULL");
++              return buffer;
++      }
 +
-+};
++      buffer[0]=usb_pipein(pUrb->pipe)?'I':'O';
++      if ( usb_pipeint(pUrb->pipe) ) {
++              strcpy(&buffer[1], " int");
++      } else if ( usb_pipeisoc(pUrb->pipe) ) {
++              strcpy(&buffer[1], " isoc");
++      } else if ( usb_pipebulk(pUrb->pipe) ) {
++              strcpy(&buffer[1], " bulk");
++      } else if ( usb_pipecontrol(pUrb->pipe) ) {
++              strcpy(&buffer[0], " ctl");
++      }
 +
-+struct device_driver MGC_ControllerDriver=
-+{
-+      .name = "musb-hcd",
-+};
-+#endif
++      return buffer;
++}
 +
-+#ifndef MUSB_USE_HCD_DRIVER
++/* Root speed need to be translated (addapted)
++ */
++static uint8_t MGC_TranslateVirtualHubSpeed(uint8_t source) {
++    uint8_t speed=2;
 +
-+static inline ssize_t
-+store_new_id(struct device_driver *driver, const char *buf, size_t count);
++    switch ( source ) {
++      case 3: speed=0; break;
++      case 2: speed=1; break;
++    }
 +
++    return speed;
++}
++
++/**
++ * Timer completion callback to turn off reset and get connection speed
++ */
++static void MGC_HdrcResetOff(unsigned long param)
++{
++    uint8_t power;
++    MGC_LinuxCd* pThis = (MGC_LinuxCd*)param;
++    void* pBase = pThis->pRegs;
++    unsigned long flags;
 +
-+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
++    DBG(2, "<== Stopping root port reset...\n");
 +
-+static ssize_t driver_count=0;
++    SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++    pThis->bIgnoreDisconnect = FALSE;
++    power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++    MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
 +
-+/* probably we don't need to be a system device in this case */
-+struct device MGC_ControllerDevice =
-+{
++    /* check for high-speed and set in root device if so */
++    power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++    if(power & MGC_M_POWER_HSMODE) {
++              DBG(3, "high-speed device connected\n");
++              pThis->bRootSpeed = 1;
++    }
 +
-+};
++#ifdef MUSB_VIRTHUB
++    MGC_VirtualHubPortResetDone(&(pThis->RootHub), 0,
++    MGC_TranslateVirtualHubSpeed(pThis->bRootSpeed));
++#endif
 +
-+struct device_driver MGC_ControllerDriver=
-+{
-+      .name = "musb-hcd",
-+};
++      DBG(2, "==>\n");
++    SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++}
 +
-+/**
-+ * store_new_id
-+ *
-+ * Adds a new dynamic device ID to this driver,
-+ * and causes the driver to probe for all devices again.
-+ */
-+static inline ssize_t
-+store_new_id(struct device_driver *driver, const char *buf, size_t count)
++/* see virthub.h */
++void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
++    uint8_t bPower)
 +{
-+      return driver_count++;
++    DBG(2, "<==\n");
++    if(bPower) {
++        DBG(3, "Root port power on\n");
++              MGC_HdrcStart((MGC_LinuxCd*)pPrivateData);
++    } else {
++        DBG(3, "Root port power off\n");
++              MGC_HdrcStop((MGC_LinuxCd*)pPrivateData);
++    }
++    DBG(2, "==>\n");
 +}
 +
-+
-+static ssize_t
-+direct_driver_attr_store(struct kobject * kobj, struct attribute *attr,
-+                    const char *buf, size_t count)
++/* see virthub.h */
++void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
++    uint8_t bEnable)
 +{
-+      struct device_driver *driver = kobj_to_direct_driver(kobj);
-+      struct driver_attribute *dattr = attr_to_driver_attribute(attr);
-+      ssize_t ret = 0;
++    DBG(2, "<==\n");
++    if (bEnable) {
++              DBG(3, "Root port power enabled\n");
++    } else {
++      DBG(3, "Root port power disabled\n");
++    }
 +
-+      if (get_driver(driver)) {
-+              if (dattr->store)
-+                      ret = dattr->store(driver, buf, count);
-+              put_driver(driver);
-+      }
-+      return ret;
++    DBG(2, "==>\n");
 +}
 +
-+static ssize_t
-+direct_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
++/* see virthub.h */
++void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
++      uint8_t bSuspend)
 +{
-+      struct device_driver *driver = kobj_to_direct_driver(kobj);
-+      struct driver_attribute *dattr = attr_to_driver_attribute(attr);
-+      ssize_t ret = 0;
++    uint8_t power;
++    MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
++    void* pBase = pThis->pRegs;
 +
-+      if ( get_driver(driver) ) {
-+              if (dattr->show)
-+                      ret = dattr->show(driver, buf);
-+              put_driver(driver);
-+      }
-+      return ret;
-+}
++    DBG(2, "<==\n");
 +
-+static struct sysfs_ops direct_driver_sysfs_ops = {
-+      .show = direct_driver_attr_show,
-+      .store = direct_driver_attr_store,
-+};
-+static struct kobj_type direct_driver_kobj_type = {
-+      .sysfs_ops = &direct_driver_sysfs_ops,
-+};
++    power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++    if(bSuspend) {
++        DBG(3, "Root port power suspended\n");
++              MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
++    } else if(power & MGC_M_POWER_SUSPENDM) {
++        DBG(3, "Root port power resumed\n");
++              power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME);
++              MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
++              WAIT_MS(20);
++              MGC_Write8(pBase, MGC_O_HDRC_POWER, power);
++    }
 +
-+static int
-+direct_create_newid_file(struct device_driver *drv)
-+{
-+      int error = 0;
-+      if (drv->probe != NULL)
-+              error = sysfs_create_file(&drv->kobj,
-+                      &driver_attr_new_id.attr);
-+      return error;
++      DBG(2, "==>\n");
 +}
 +
-+static int
-+direct_populate_driver_dir(struct device_driver *drv)
++/* see virthub.h */
++void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
++      uint8_t bReset)
 +{
-+      return direct_create_newid_file(drv);
-+}
++    uint8_t power;
++    MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
++    void* pBase = pThis->pRegs;
 +
-+/* ------------------------ let the ball rolling -------------------------*/
++    DBG(2, "<==\n");
 +
-+/* customize for different behavior */
-+static int direct_hotplug (struct device *dev, char **envp, int num_envp,
-+    char *buffer, int buffer_size)
-+{
-+      return -ENODEV;
++    power = MGC_Read8(pBase, MGC_O_HDRC_POWER) & 0xf0;
++    if (bReset) {
++              pThis->bIgnoreDisconnect = TRUE;
++              MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESET);
++              MGC_LinuxSetTimer(pThis, MGC_HdrcResetOff, (unsigned long)pThis, 60);
++    } else if(power & MGC_M_POWER_RESET) {
++        DBG(3, "root port reset stopped\n");
++              MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
++    }
++
++      DBG(2, "==>\n");
 +}
 +
-+static int direct_device_suspend(struct device * dev, u32 state)
-+{
-+      return 0;
++/**************************************************************************
++ *
++ **************************************************************************/
++
++ /**
++ * return the current urb for a given endpoint. Caller is responsible for
++ * locking
++ * @param pEnd the end point (pEnd!=NULL)
++ * @return the urb or NULL when the end point is idle
++ */
++struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd) {
++#ifdef MUSB_USE_HCD_DRIVER
++      return pEnd->pCurrentUrb;
++#else
++    DBG(8 ,"GetCurrentUrb urb_list_ptr:0x%p \n",&(pEnd->urb_list));
++    DBG(8 ,"GetCurrentUrb urb_list->next:0x%p \n",pEnd->urb_list.next);
++    DBG(8 ,"GetCurrentUrb urb_list->prev:0x%p \n",pEnd->urb_list.prev);
++    return list_empty(&(pEnd->urb_list)) ? NULL
++              : list_entry(pEnd->urb_list.next, struct urb, urb_list);
++#endif
 +}
 +
-+/* customize for different behavior */
-+static int direct_device_resume(struct device * dev)
++/**
++ * Test whether a local endpoint is idle.
++ * @param pEnd the endpoint
++ * @return !=0 when idle, 0 otherwise
++ */
++int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd)
 +{
-+      return 0;
++#ifdef MUSB_USE_HCD_DRIVER
++      return (pEnd->pCurrentUrb)==NULL;
++#else
++      return list_empty(&pEnd->urb_list);
++#endif
 +}
 +
-+static int direct_bus_match(struct device * dev, struct device_driver * drv) {
-+      return (&MGC_ControllerDriver==drv)?1:0;
++
++void mgc_ep_idle(MGC_LinuxLocalEnd* pEnd) {
++#ifdef MUSB_USE_HCD_DRIVER
++      pEnd->pCurrentUrb=NULL;
++#else
++      INIT_LIST_HEAD(&(pEnd->urb_list));
++#endif
 +}
 +
-+struct bus_type direct_bus_type = {
-+      .name           = "system",
-+      .match          = direct_bus_match,
-+      .hotplug        = direct_hotplug,
-+      .suspend        = direct_device_suspend,
-+      .resume         = direct_device_resume,
-+};
 +
 +/**
-+ * direct_register_driver - register a new driver
-+ * @drv: the driver structure to register
-+ * 
-+ * Adds the driver structure to the list of registered drivers
-+ * Returns the number of devices which were claimed by the driver
-+ * during registration.  The driver remains registered even if the
-+ * return value is zero.
++ * Dequeue an urb from an endpoint.
++ * @param pEnd the endpoint
++ * @param pUrb the urb to be removed
 + */
-+static int
-+direct_register_driver(struct device_driver *drv, struct bus_type *btype)
++static int mgc_ep_dequeue_urb(MGC_LinuxLocalEnd* pEnd, struct urb *pUrb,MGC_LinuxCd* pThis)
 +{
-+    int count = 0;
-+      
-+    /* initialize common driver fields */
-+    drv->bus = (btype)?btype:&direct_bus_type;
-+    drv->kobj.ktype = &direct_driver_kobj_type;
++      int rc=0;
 +
-+    /* register with core */
-+    count = driver_register( drv );
-+    if (count >= 0) {
-+          direct_populate_driver_dir( drv );
-+    }
++#ifdef MUSB_USE_HCD_DRIVER
++      if ( pEnd->pCurrentUrb==pUrb ) {
++              pUrb->hcpriv=NULL;
++              pEnd->pCurrentUrb=NULL;
++      } else {
++              rc=-EINVAL;
++              ERR("*** Trying to dequeue pUrb=%p from ep%d while pEnd->pCurrentUrb=%p\n",
++                      pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
++      }
++#else
++      pUrb->hcpriv=NULL;
++      list_del_init(&pUrb->urb_list);
++#endif
 +
-+    return count ? count : 1;
++      /* clear endpoint status (preserving the softstate for find_end() ) */
++      mgc_ep_linux_clear(pEnd,pThis);
++
++      DBG(1, "==> dequeued pUrb=%p from pEnd->bEnd=%d rc=%d\n",
++              pUrb, pEnd->bEnd, rc);
++      return rc=0;
 +}
 +
 +/**
-+ * unregister_driver - unregister a driver
-+ * @drv: the driver structure to unregister
-+ * 
-+ * Deletes the driver structure from the list of registered drivers,
-+ * gives it a chance to clean up by calling its remove() function for
-+ * each device it was responsible for, and marks those devices as
-+ * driverless.
++ * @return 0 success, != when the ep is busy with another request
 + */
-+
-+static void
-+direct_unregister_driver(struct device_driver *drv)
++static int mgc_ep_enqueue_urb(MGC_LinuxLocalEnd* pEnd, struct urb* pUrb)
 +{
-+    driver_unregister( drv );
-+}
++      int rc=0;
 +
-+#endif
++#ifdef MUSB_USE_HCD_DRIVER
++      if ( pEnd->pCurrentUrb ) {
++              ERR("*** urb=%p, ep=%d wile busy with urb=%p, this is BAD (tm)\n",
++                      pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
++              rc=-EBUSY;
++      } else {
++              pEnd->pCurrentUrb=pUrb;
++      }
++#else
++      list_add_tail(&(pUrb->urb_list), &(pEnd->urb_list));
 +#endif
 +
-+/* ------------------------------------------------------------------- */
-+/* ------------------------------------------------------------------- */
-+/* ------------------------------------------------------------------- */
++      return rc;
++}
 +
-+#ifdef MUSB_CUSTOM_DIRECT_BUS_FILE
-+#include MUSB_CUSTOM_DIRECT_BUS_FILE
-+#else
 +/**
-+ * Discover and initialize the drivers on the direct bus.
++ * find the end an urb is posted to
++ * @param pUrb
++ * @return the pEnd or NULL when not found.
 + */
-+int
-+direct_bus_init(void) {
-+      
-+    int rc= -1;
-+    char name[32];
-+    void* pDevice = NULL;
-+      
-+#ifdef MUSB_USE_HCD_DRIVER
-+      MGC_LinuxCd* pThis;
-+      
-+      /* already initialized */
-+      if ( MGC_nIndex ) { 
-+              return 0;
-+      }       
-+      snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);         
-+      
-+      pDevice = &MGC_ControllerDevice;  
-+      g_pDevice=pDevice; 
-+      kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
-+
-+      rc = kobject_register(&((struct device*)pDevice)->kobj);
++MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb)
++{
++      int bEnd=0;
 +
-+      if(rc < 0){
-+              ERR("failed to register:%d\n", rc);
-+              return rc;
++      for (bEnd=0; bEnd<MUSB_C_NUM_EPS-1; bEnd++) {
++              if ( MGC_GetCurrentUrb(&pThis->aLocalEnd[bEnd])==pUrb ) {
++                      return &pThis->aLocalEnd[bEnd];
++              }
 +      }
-+      
-+      INIT_LIST_HEAD( (struct list_head*)&((struct device*)pDevice)->klist_children );
-+      
-+      ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
-+      
-+      sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);  
-+      
-+      pThis = MGC_LinuxInitController(pDevice, MUSB_CONTROLLER_HDRC, INT_USBOTG, 
-+              ioremap(NOMADIK_USB_BASE, 0x100000), 0x00100000, name);
-+      
-+      if(pThis) {
-+              DBG(3, "MGC_LinuxInitController success MGC_struct:0x%p \n", pThis);
-+              rc = 0;
-+              MGC_VirtualHubStart( &(pThis->RootHub) );
++
++      return NULL;
++}
++
++/**************************************************************************
++ *
++ **************************************************************************/
++
++void mgc_complete_urb(MGC_LinuxCd *pThis, struct urb *pUrb) {
++      /* give it back */
++      usb_put_urb(pUrb);
++      if (pUrb->status) {
++              DBG(1, "completing urb=%p,status=%d\n", pUrb, pUrb->status);
 +      }
-+      return(rc);
-+      
++
++#ifdef MUSB_USE_HCD_DRIVER
++      mgc_hcd_complete_urb(pThis, pUrb);
 +#else
-+      const int nCount = sizeof(MUSB_aLinuxController) 
-+              / sizeof(MUSB_LinuxController);
-+    int nIndex;
-+      
-+      INFO("Probing direct bus [direct=%d]\n", nCount); 
-+      
-+      if ( !nCount ) {
-+              return 0;
-+    }
-+      
-+    KMALLOC(MGC_DriverInstances, nCount*sizeof(MGC_LinuxCd*), GFP_ATOMIC);
-+    if ( !MGC_DriverInstances ) {
-+        return -ENOMEM;
-+    }
-+      
-+#ifdef MUSB_V26
-+    pDevice = &MGC_ControllerDevice;    
-+      kobject_set_name(&((struct device*)pDevice)->kobj, "musbdev");
-+      rc = kobject_register(&((struct device*)pDevice)->kobj);
-+      if(rc < 0){
-+              ERR("failed to register:%d\n", rc);
-+              return rc;
++      if ( pUrb->complete ) {
++              COMPLETE_URB(pUrb, NULL);
 +      }
-+      
-+      INIT_LIST_HEAD( &((struct device*)pDevice)->children );
-+      
-+      ((struct device *)pDevice)->driver = &MGC_ControllerDriver;
-+      sprintf (&((struct device *)pDevice)->bus_id[0], "usb%d", rc);  
-+    bus_register( &direct_bus_type ); 
-+    direct_register_driver(&MGC_ControllerDriver, NULL);
-+#endif
-+      
-+    /* NON PCI machines */
-+    for (nIndex = 0; !rc && nIndex < nCount; nIndex++) {
-+              MUSB_LinuxController* pStaticController=&(MUSB_aLinuxController[nIndex]);
-+              
-+        snprintf(name, 32, "musbhdrc%d", MGC_nIndex++);
-+              MGC_DriverInstances[nIndex]=MGC_LinuxInitController(pDevice, 
-+                      pStaticController->wType, pStaticController->dwIrq, 
-+                      pStaticController->pBase, 
-+                      (pStaticController->dwSize)? pStaticController->dwSize
-+                      : MUSB_DEFAULT_ADDRESS_SPACE_SIZE, name);
-+              
-+              if( MGC_DriverInstances[nIndex] ) {
-+#ifdef MUSB_VIRTHUB           
-+                      MGC_VirtualHubStart( &(MGC_DriverInstances[nIndex]->RootHub) );
-+#endif
-+                      MGC_InstancesCount++;
-+              } else {
-+                      ERR("controller %d failed to initialize\n", nIndex);
-+                      direct_bus_shutdown();
-+                      rc=-1;
-+              }
-+    }
-+    return MGC_InstancesCount;
 +#endif
-+      
++
++      if (pUrb->status) {
++              DBG(1, "done completing pUrb=%p\n", pUrb);
++      }
 +}
 +
 +/**
++ * complete an urb. Since urb completion generally post new urbs via
++ * submit urn, this  make sure the ep won't kickstart it during the
++ * completion.
 + *
++ * @param pEnd the end point urb is posted to
++ * @param pUrb the urb to complete !=NULL
++ * @return 0 success
 + */
-+void direct_bus_shutdown(void) 
++static inline int mgc_linux_complete_urb(MGC_LinuxCd *pThis,
++      MGC_LinuxLocalEnd* pEnd, struct urb *pUrb)
 +{
-+#ifdef MUSB_USE_HCD_DRIVER
-+      kobject_unregister(&((struct device*)g_pDevice)->kobj); /* shoudl check the hcd drivers */
-+      
-+      
-+#else
-+    int nIndex=0;
-+      
-+      /* free the instances */
-+    for (nIndex = 0; nIndex < MGC_InstancesCount; nIndex++) {
-+              MGC_LinuxCdFree( MGC_DriverInstances[nIndex] );
-+    }
-+      
-+      KFREE(MGC_DriverInstances);
-+#ifdef MUSB_V26
-+      direct_unregister_driver(&MGC_ControllerDriver);
-+#endif        
-+#endif
 +
-+}
-+#endif
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_cross.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_cross.h
---- linux-2.6.20/drivers/usb/nomadik/musb_cross.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_cross.h       2008-08-08 19:15:22.000000000 +0530
-@@ -0,0 +1,131 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_cross.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 
-+ */
++      int periodic=mgc_urb_is_periodic(pUrb);
++      int status=periodic; /* 0 needs start next */
++      int error=(pUrb->status==-ENOENT) || (pUrb->status==-ECONNRESET) ||
++              (pUrb->status==-ESHUTDOWN) || (pUrb->status==-ETIMEDOUT)
++              || (pUrb->status==-EBUSY);
 +
-+#ifndef __MUSB_CROSS_H
-+#define __MUSB_CROSS_H
++      DBG(2, "<== completing URB %p, on pEnd->bEnd=%d status=%d, proto=%s\n",
++              pUrb, pEnd->bEnd, pUrb->status, decode_urb_protocol(pUrb));
 +
-+#include <linux/version.h>
++    if ( error && periodic ) {
++              pEnd->bIsClaimed=FALSE;
++      }
 +
-+/****************************** KERNEL VERSION MACROS ************************/
++      /* prevents locking&kickstarting */
++      pEnd->bBusyCompleting=1;
 +
-+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) 
-+#undef MUSB_V26
++      mgc_complete_urb(pThis, pUrb);
 +
-+#ifndef MUSB_V24 
-+#define MUSB_V24
-+#endif 
++#ifdef MUSB_V24
++      /* Under 2.4 interrupt IN URBs must be re-submitted from the driver
++       * unless they are unlinked; 2.6 urbs do that from the completition
++       * routine. ENODEV means we raced disconnect() */
++    if ( !error && periodic ) {
++              DBG(1, "periodic pUrb=%p, proto=%s, (status=%d)\n", pUrb,
++                      decode_urb_protovol(pUrb), pUrb->status);
++              status=mgc_schedule_urb(pThis, pEnd, pUrb);
++              if ( (status!= 0) && (status != -ENODEV) ) {
++                      DBG(3, "error resubmitting intr URB %p (status=%d)\n",
++                              pUrb, status);
++              }
 +
++      }
++#else
++      status=0; /* kickstart next */
 +#endif
 +
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#undef MUSB_V24
-+#ifndef MUSB_V26 
-+#define MUSB_V26
-+#endif
-+#endif
++      /* allows locking&kickstarting again */
++      pEnd->bBusyCompleting=0;
 +
-+#ifdef MUSB_V26
++      DBG(2, "==> status=%d, periodic=%d\n", status, periodic);
++      return status;
++}
 +
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
-+#ifndef MUSB_V26_POST10
-+#define MUSB_V26_POST10
-+#endif
-+#endif
++/**
++ * Start transmit. Caller is responsible for locking the ep.
++ * On EP0 only PING is disabled.
++ *
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ */
++void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++    uint16_t wCsr;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++    DBG(2, "<== bEnd=%d ==>\n", bEnd);
++    /* NOTE: no locks here; caller should lock */
++    MGC_SelectEnd(pBase, bEnd);
++    if(bEnd) {
++        wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++              wCsr |= MGC_M_TXCSR_TXPKTRDY;
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
++    } else {
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      MGC_M_CSR0_H_NO_PING | MGC_M_CSR0_H_SETUPPKT | MGC_M_CSR0_TXPKTRDY);
++    }
++}
 +
++/**************************************************************************
++ *
++ **************************************************************************/
 +
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
-+#ifndef MUSB_USE_HCD_DRIVER
-+#define MUSB_USE_HCD_DRIVER
-+#endif
++ /**
++  * return the buffer associated to an urb (map it too)
++  */
++static inline uint8_t* get_urb_buffer(struct urb* pUrb) {
++       uint8_t *pBuffer=NULL;
++
++#ifdef MUSB_PARANOID
++      if ( !pUrb ) {
++              return NULL;
++      }
 +#endif
 +
++       pBuffer=pUrb->transfer_buffer;
++#ifndef MUSB_LINUX_MV21
++      if ( !pBuffer ) {
++              pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
++      }
 +#endif
 +
++      return pBuffer;
++}
 +
-+/*********************************** WEIRDNESS ******************************/
++/**
++ * Xmit a packet. pEnd->dwOffset is updated as well
++ * @param pThis
++ * @param bEnd the EP urb is queued to
++ */
++static uint8_t mgc_linux_packet_tx(MGC_LinuxCd* pThis, uint8_t bEnd) {
++      uint32_t wLength=0;
++    uint8_t bDone = FALSE;
++      uint8_t *pBase = (uint8_t*)pThis->pRegs;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++      struct urb* pUrb=MGC_GetCurrentUrb(pEnd);
++      uint8_t *pBuffer=get_urb_buffer(pUrb);
++    int nPipe = pUrb ? pUrb->pipe : 0;
 +
-+#ifdef MUSB_V26_POST10
-+#define MUSB_MEMFLAG_TYPE     unsigned int
++      DBG(2, "<== bEnd=%d\n", bEnd);
++
++      /* abort the transfer */
++    if ( !pBuffer ) {
++              ERR("***> no buffer was given, BAD things are happening (TM)!\n");
++              return TRUE;
++    }
++
++      /* see if more transactions are needed */
++#ifdef MUSB_DMA
++      if(pEnd->pDmaChannel) {
++              if (MGC_DMA_STATUS_FREE ==
++                      pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel)
++              ) {
++                      pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
++              }
++      } else {
++              pEnd->dwOffset += pEnd->dwRequestSize;
++      }
 +#else
-+#define MUSB_MEMFLAG_TYPE     int
++      pEnd->dwOffset += pEnd->dwRequestSize;
 +#endif
 +
-+/****************************** SYSTEM PROPERTIES ***************************/
++      if (usb_pipeisoc(nPipe)) {
++              /* isoch case */
++              if(++pEnd->dwIsoPacket >= pUrb->number_of_packets) {
++                      bDone = TRUE;
++              } else {
++                      pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
++                      wLength = pUrb->iso_frame_desc[pEnd->dwIsoPacket].length;
++              }
++      } else {
++              pBuffer += pEnd->dwOffset;
++              wLength = min((uint32_t)(pEnd->wPacketSize),
++                        (uint32_t)(pUrb->transfer_buffer_length - pEnd->dwOffset));
++              if(pEnd->dwOffset >= pUrb->transfer_buffer_length) {
++                      /* sent everything; see if we need to send a null */
++                      if(!((pEnd->dwRequestSize == pEnd->wPacketSize) &&
++                       (pUrb->transfer_flags & USB_ZERO_PACKET)))
++                      {
++                              bDone = TRUE;
++                      }
++              }
++      }
 +
-+#if defined(MUSB_V26) || defined(MUSB_V24)
-+#define MUSB_HAS_BUSNAME
-+#endif
++      if (bDone) {
++              pUrb->status=0;
++      } else if ( wLength ) { /* @assert bDone && !wLength */
++              MGC_HdrcLoadFifo(pBase, bEnd, wLength, pBuffer);
++              pEnd->dwRequestSize = wLength;
++      }
 +
-+#ifndef MUSB_LINUX_MV21
-+#define HAS_USB_TT_MULTI
++#ifdef MUSB_CONFIG_PROC_FS
++      pEnd->dwTotalTxBytes += pEnd->dwRequestSize;
++      pEnd->dwTotalTxPackets++;
 +#endif
 +
-+#ifdef CONFIG_PREEMPT
-+/* warning??? */
-+#endif
++      DBG(2, "==> bDone=%d\n", bDone);
++      return bDone;
++}
 +
-+/* gstorage is liked to the driver: the init code lives there */
-+#ifdef MUSB_GSTORAGE 
-+#define MUSB_SKIP_INIT
-+#endif
 +
-+/* When compiled in the kernel, the init function is needed only when gadget
-+ * gadget API is not compiled (usb_register_driver takes care of the init)
++/**
++ * Receive a packet (or part of it).
++ * @requires pThis->Lock locked
++ * @param pThis
++ * @param bEnd
++ * @param bIsochError
++ * @return TRUE if URB is complete
 + */
-+#if defined(MUSB_BUILTIN) && !defined(MUSB_GADGET)
-+#ifndef MUSB_SKIP_INIT
-+#define MUSB_SKIP_INIT
-+#endif
-+#endif
++static uint8_t mgc_linux_packet_rx(MGC_LinuxCd* pThis, uint8_t bEnd,
++      uint16_t wRxCount, uint8_t bIsochError)
++{
++    uint16_t wLength, wCsr;
++    uint8_t bDone = FALSE;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++    struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
++    uint8_t* pBuffer=get_urb_buffer(pUrb);
++    int nPipe = pUrb ? pUrb->pipe : 0;
 +
-+/* -------------------------------- OTG ----------------------------- */
++      DBG(2, "<== end %d RxCount=%04x\n", bEnd, wRxCount);
 +
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-+#define MUSB_HAS_OTG
-+#define HAS_HNP_SUPPORT
-+#endif 
++#ifdef MUSB_PARANOID
++    if ( !pUrb || ((pUrb->transfer_buffer_length - pEnd->dwOffset)<0) )  {
++              ERR("***> Rx error: pUrb=%p, pUrb->transfer_buffer_length=%d pEnd->dwOffset=%d\n", \
++                      pUrb, pUrb->transfer_buffer_length, pEnd->dwOffset );
++              return TRUE;
++    }
++#endif
 +
-+/* -------------------------------- DMA ----------------------------- */
++    DBG(3, "bEnd=%d, pUrb->transfer_flags=0x%x pUrb->transfer_buffer=%p\n", \
++              bEnd, pUrb->transfer_flags, pUrb->transfer_buffer);
++      DBG(3, "pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, wRxCount=%d\n",
++              pUrb->transfer_buffer_length, pEnd->dwOffset, wRxCount);
 +
-+#define       DMA_ADDR_INVALID        (~(dma_addr_t)0)
++      /* abort the transfer */
++    if ( !pBuffer ) {
++              ERR("***> pBuffer=NULL, BAD things are happening (TM)!\n");
++              return TRUE;
++    }
 +
-+/* MVL21 doesn't support DMA */
-+#if defined(MUSB_LINUX_MV21) 
-+#ifdef MUSB_DMA
-+#error "DMA Mode not supported in MontaVista 2.1"
-+#endif
++    /* unload FIFO */
++    if( usb_pipeisoc(nPipe) ) {
++              /* isoch case */
++              pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
++              wLength = min((unsigned int)wRxCount,
++                                pUrb->iso_frame_desc[pEnd->dwIsoPacket].length);
++              pUrb->actual_length += wLength;
 +
-+/* DMA supported from 2.4 'till 2.6.10 */
-+#elif defined(MUSB_V24) || (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
-+#ifndef MUSB_HAS_DMA_URBS
-+#define MUSB_HAS_DMA_URBS
-+#endif
++              /* update actual & status */
++              pUrb->iso_frame_desc[pEnd->dwIsoPacket].actual_length = wLength;
++              if(bIsochError) {
++                      pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_CRC;
++                      pUrb->error_count++;
++              } else {
++                      pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_NOERROR;
++              }
 +
-+/* DMA not supported on versions >= 2.6.10 */
-+#elif ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) ) 
++              /* see if we are done */
++              bDone = (++pEnd->dwIsoPacket >= pUrb->number_of_packets);
 +
-+#ifdef MUSB_DMA
-+#error "DMA Mode MIGHT not be supported in kernels > 2.6.10"
-+#endif
++              DBG(3, "pEnd->dwIsoPacket=%d, pUrb->number_of_packets=%d, wLength=%d\n",
++                      pEnd->dwIsoPacket, pUrb->number_of_packets, wLength);
++              DEBUG_CODE(3, if ( bDone ) { \
++                              INFO("completing %d-packet isoch URB; len=%x, errors=%d\n", \
++                              pUrb->number_of_packets, pUrb->actual_length, pUrb->error_count); \
++                      } );
++    } else {
++              DBG(3, "(bEnd=%d), wRxCount=%d, pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, pEnd->wPacketSize=%d\n",
++                 bEnd, wRxCount, pUrb->transfer_buffer_length, pEnd->dwOffset, pEnd->wPacketSize);
 +
-+#endif
++              /* non-isoch */
++              pBuffer += pEnd->dwOffset;
++              wLength = min((unsigned int)wRxCount,
++                                pUrb->transfer_buffer_length - pEnd->dwOffset);
++              pUrb->actual_length += wLength;
++              pEnd->dwOffset += wLength;
 +
-+/* -------------------------------- GADGETS ----------------------------- */
-+#endif
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_debug.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_debug.c
---- linux-2.6.20/drivers/usb/nomadik/musb_debug.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_debug.c       2008-07-28 15:20:53.000000000 +0530
-@@ -0,0 +1,190 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_debug.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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/list.h>
-+#include <linux/completion.h>
-+#include <linux/interrupt.h>
++              /* see if we are done */
++              bDone = (pEnd->dwOffset >= pUrb->transfer_buffer_length)
++                      || (wRxCount < pEnd->wPacketSize);
 +
-+#include <linux/usb.h>
++              DEBUG_CODE(3, if ( bDone ) { \
++                      INFO("will complete URB; pUrb=%p (%s) len=%x, errors=%d\n", \
++                      pUrb, decode_urb_protocol(pUrb), pUrb->actual_length, \
++                      pUrb->error_count); \
++              } );
++    }
 +
-+#include "debug.h"
-+#include "musbdefs.h"
++      if ( wLength ) {
++              MGC_HdrcUnloadFifo(pBase, bEnd, wLength, pBuffer);
++      }
 +
-+#define IPRINTF(_f, _m)       printk(KERN_INFO "%s"_f, indent, _m)
-+#define isspace(c)    (c==' ' || c=='\t')
-+#define LABEL KERN_INFO "dump: "
++#ifdef MUSB_CONFIG_PROC_FS
++    pEnd->dwTotalRxBytes += wLength;
++    pEnd->dwTotalRxPackets++;
++#endif
 +
-+/******************************************************************/
++    if( wRxCount <= wLength ) { /* test for short packet */
++              wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++                                 wCsr & ~MGC_M_RXCSR_RXPKTRDY);
++    }
++      if ( bEnd && bDone ) {
++              pUrb->status=0;
++      }
 +
-+int MGC_DebugLevel=MUSB_DEBUG;
-+int MGC_DebugDisable=0;
++      DBG(2, "==> bDone=%d\n", bDone);
++    return bDone;
++}
 +
-+/******************************************************************/ 
++/* *************************************************************************
++ *
++ **************************************************************************/
 +
-+/* Decode CSR0 value to a string. Not reentrant
++/**
++ * Find first (lowest-order) 1 bit
++ * @param nValue value in which to search
++ * @return bit position (0 could mean no bit; caller should check)
 + */
-+char *decode_csr0(uint16_t csr0) {
-+    static char buf[64];
-+    sprintf(buf, "(%s%s%s%s)", 
-+          csr0&MGC_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"",
-+          csr0&MGC_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"",
-+          csr0&MGC_M_CSR0_P_SENDSTALL ? "[stalled]":"",
-+          csr0&MGC_M_CSR0_P_DATAEND ? "[dataend]":""); 
-+    return buf;  
-+}
++static uint8_t find_first1(unsigned int nValue)
++{
++    uint8_t bResult;
++    unsigned int nWork = nValue;
 +
-+/* Decode a value to binary.
-+ */
-+char *decode_bits(uint16_t value) {
-+    int i=0;
-+    static char buf[64];
-+    
-+    for (; i<16;i++) {
-+      buf[15-i]=(value&(1<<i))?'1':'0';    
++    for(bResult = 0; bResult < 32; bResult++) {
++              if(nWork & 1) {
++                      return bResult;
++              }
++              nWork >>= 1;
 +    }
-+    
-+    return buf;
++
++    return bResult;
 +}
 +
-+/* Decode TXCSR register.
++/**
++ * @param nPipe
 + */
-+char *decode_txcsr(uint16_t txcsr) {
-+    static char buf[256];
-+    sprintf(buf, "%s (%s%s%s%s)", 
-+          decode_bits(txcsr),
-+          txcsr&MGC_M_TXCSR_TXPKTRDY ? "[TXPKTRDY]":"",
-+          txcsr&MGC_M_TXCSR_AUTOSET ? "[MGC_M_TXCSR_AUTOSET]":"",
-+          txcsr&MGC_M_TXCSR_DMAENAB ? "[MGC_M_TXCSR_DMAENAB]":"",
-+          txcsr&MGC_M_TXCSR_DMAMODE ? "[MGC_M_TXCSR_DMAMODE]":""); 
-+    return buf;  
++static inline char *pipe_type(const unsigned int nPipe) {
++      if ( usb_pipeisoc(nPipe) ) {
++              return "isoc";
++      } else if ( usb_pipebulk(nPipe) ) {
++              return "bulk";
++      } else if ( usb_pipeint(nPipe) ) {
++              return "int";
++      } else {
++              return "cntl";
++      }
 +}
 +
-+/*
++/** Calculate the interval (or NAK limit for bulk) for isoc and
++ * inter requests.
++ * @param pUrb the urb interval should be determined for
++ * @return the interval
 + */
-+char *decode_devctl(uint16_t devctl) {
-+    return (devctl&MGC_M_DEVCTL_HM)?"host":"function";
-+}
++static uint8_t hdrc_interval(struct urb* pUrb) {
++    const unsigned int nPipe = pUrb->pipe;
++    uint8_t bInterval = (uint8_t)pUrb->interval;
 +
++    if( usb_pipeint(nPipe) ) {
++              /* correct interval for high-speed */
++              if((USB_SPEED_HIGH == ((uint8_t)pUrb->dev->speed)) && (pUrb->interval > 255)) {
++                      bInterval = find_first1(pUrb->interval);
++              }
++    } else {
++              /* normalize value */
++              if(pUrb->interval > 16) {
++                      bInterval = find_first1(pUrb->interval);
++              }
 +
-+/*
-+ */
-+char *decode_ep0stage(uint8_t stage) {
-+    static char buff[64];
-+    uint8_t stallbit=stage&MGC_END0_STAGE_STALL_BIT;
-+    
-+    stage=stage&~stage&MGC_END0_STAGE_STALL_BIT;
-+    sprintf(buff, "%s%s", (stallbit)? "stall-" : "",
-+      (stage==MGC_END0_STAGE_SETUP)
-+      ? "setup" :
-+      (stage==MGC_END0_STAGE_TX)
-+      ? "tx" :
-+      (stage==MGC_END0_STAGE_RX)
-+      ? "rx" :
-+      (stage==MGC_END0_STAGE_STATUSIN)
-+      ? "statusin" : 
-+      (stage==MGC_END0_STAGE_STATUSOUT)
-+      ? "statusout" : "error");
-+    return buff;
-+}
++              if(usb_pipeisoc(nPipe) && (bInterval < 1)) {
++                      bInterval = 1;
++              }
++
++              if( usb_pipebulk(nPipe) && (bInterval < 2)) {
++                      /* this is the NACK time */
++                      bInterval = 0;/*16;*/
++              }
++    }
 +
++      DBG(2, "pipe_type=%s bInterval=%d\n", pipe_type(nPipe), bInterval);
 +
-+/*
++      return bInterval;
++}
++
++/**
++ * @param pUrb
 + */
-+void dump_urb (void *pUrb)
-+{
-+      struct urb* purb=(struct urb*)pUrb;
++static inline uint8_t hdrc_type(struct urb* pUrb) {
++    uint8_t bStdType = 0;
++    const unsigned int nPipe = pUrb->pipe;
 +
-+      printk (LABEL "urb                   :%p\n", purb);
-+      printk (LABEL "urb_list                          :%s\n", dump_node(&purb->urb_list));
-+#ifdef V24    
-+      printk (LABEL "next                  :%p\n", purb->next);
-+#endif        
-+      printk (LABEL "dev                   :%p\n", purb->dev);
-+      printk (LABEL "pipe                  :%08X\n", purb->pipe);
-+      printk (LABEL "status                :%d\n", purb->status);
-+      printk (LABEL "transfer_flags        :%08X\n", purb->transfer_flags);
-+      printk (LABEL "transfer_buffer       :%p\n", purb->transfer_buffer);
-+      printk (LABEL "transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-+      printk (LABEL "actual_length         :%d\n", purb->actual_length);
-+      printk (LABEL "setup_packet          :%p\n", purb->setup_packet);
-+      printk (LABEL "start_frame           :%d\n", purb->start_frame);
-+      printk (LABEL "number_of_packets     :%d\n", purb->number_of_packets);
-+      printk (LABEL "interval              :%d\n", purb->interval);
-+      printk (LABEL "error_count           :%d\n", purb->error_count);
-+      printk (LABEL "context               :%p\n", purb->context);
-+      printk (LABEL "complete              :%p\n", purb->complete);
++    if(usb_pipeisoc(nPipe)) {
++        bStdType = 1;
++    } else if(usb_pipeint(nPipe)) {
++        bStdType = 3;
++    } else if( usb_pipebulk(nPipe) ) {
++        bStdType = 2;
++      }
++
++      return bStdType;
 +}
 +
 +/**
-+ * Dump core registers whose reads are non-destructive.
-+ * @param pThis
-+ * @param bEnd 
++ * program hdrc_registers for the device address of a given urb.
++ * @param pTjos
++ * @param pUrb
++ * @param bEnd
++ * @param bXmt
 + */
-+void MGC_HdrcDumpRegs(uint8_t* pBase, int multipoint, uint8_t bEnd)
++static void hdrc_set_address(MGC_LinuxCd* pThis, struct urb* pUrb, uint8_t bEnd,
++      unsigned int bXmt)
 +{
-+    MGC_SelectEnd(pBase, bEnd);    
-+      
-+    if(!bEnd) {
-+              printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n",
-+             MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_TYPE0, 0),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0));
-+    } else {
-+              printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n",
-+             bEnd,
-+             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
-+             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd));
-+              printk(KERN_INFO "    RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n",
-+             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd),
-+             MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd),
-+             MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd),
-+             MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd));
-+    }
-+    
-+    if( multipoint) {
-+              printk(KERN_INFO "    TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n",
-+                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR)),
-+                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR)),
-+                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT)));
-+              printk(KERN_INFO "    RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n",
-+                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR)),
-+                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR)),
-+                      MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT)));
++#ifdef MUSB_LINUX_MV21
++    struct usb_device* pParent;
++#endif
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    uint8_t bAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
++    uint8_t bHubAddr = 0, bHubPort = 0, bIsMulti = FALSE;
++
++
++      /* NOTE: there is always a parent due to the virtual root hub */
++    bHubAddr = (uint8_t)pUrb->dev->parent->devnum;
++      /* but not if parent is our virtual root hub */
++    if(bHubAddr == pThis->RootHub.bAddress) {
++              bHubAddr = 0;
 +    }
-+}
 +
++#ifdef MUSB_LINUX_MV21
++    /* parent hub address */
++      pParent = pUrb->dev->parent;
 +
-+/* list related */
++    /* this distribution doesn't support directly, so try to find ourselves */
++    if((USB_SPEED_HIGH!=((uint8_t)pUrb->dev->speed)) &&
++       (pParent->devnum != pThis->RootHub.bAddress))
++    {
++              int nChild;
++              struct usb_device* pDevice;
 +
-+/*
-+ * NOT REENTRANT!
-+ */
-+char *dump_node(struct list_head *node) {
-+    static char buf[64];
-+    sprintf(buf, "[n=%p,p=%p]", node->next, node->prev);                          
-+    return buf;
-+}
++        /* walk up to first high-speed hub and remember our subtree's child */
++              pDevice = pUrb->dev;
++              while(pParent && (USB_SPEED_HIGH != pParent->speed) &&
++                        (pParent->devnum != pThis->RootHub.bAddress))
++              {
++                      pDevice = pParent;
++                      pParent = pParent->parent;
++              }
 +
++              if(pParent && (pParent->devnum != pThis->RootHub.bAddress)) {
++                      /* correlate to port and check for multi-TT */
++                      for(nChild = 0; nChild < pParent->maxchild; nChild++) {
++                              if(pParent->children[nChild] == pDevice) {
++                                      bHubPort = nChild + 1;
++                                      bIsMulti = (2 == pParent->descriptor.bDeviceProtocol);
++                                      break;
++                              }
++                      }
++              }
++    }
++#else
++    /* if tt pointer, use its info */
++    if(pUrb->dev->tt) {
++              bHubPort = (uint8_t)pUrb->dev->ttport;
++#ifdef HAS_USB_TT_MULTI
++              bIsMulti = (uint8_t)pUrb->dev->tt->multi;
++#endif
++    }
++#endif
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbdefs.h ../new/linux-2.6.20/drivers/usb/nomadik/musbdefs.h
---- linux-2.6.20/drivers/usb/nomadik/musbdefs.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musbdefs.h 2008-08-08 19:15:30.000000000 +0530
-@@ -0,0 +1,828 @@
-+/*
-+ * linux/drivers/usb/nomadik/musbdefs.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 
-+ */
++      if ( bIsMulti ) {
++              bHubAddr |=0x80;
++      }
 +
-+#ifndef __MUSB_MUSBDEFS_H__
-+#define __MUSB_MUSBDEFS_H__
++      /* tx address */
++      if(pThis->bIsMultipoint) {
++              /* target addr & hub addr/port */
++              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR),
++                         bAddress);
++              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR),
++                         bHubAddr);
++              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT),
++                         bHubPort);
 +
-+#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <linux/smp_lock.h>
-+#include <linux/errno.h>
++              /* also, try Rx (this is a bug ion the core: I always need to to do
++               * both (at least for ep0), needs to be changed when the core is
++               * fixed */
++              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR),
++                         bAddress);
++              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR),
++                         bHubAddr);
++              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT),
++                         bHubPort);
++      } else {
++              /* non-multipoint core */
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+#include <linux/fs.h>
-+#endif
++              MGC_Write8(pBase, 0x80 + 8*bEnd, bAddress);
++              MGC_Write8(pBase, 0x84 + 8*bEnd, bAddress);
 +
-+/* useful for compiling across linux version & debug definitions */
-+#include "musb_cross.h"
-+#include "debug.h"
++      }
 +
-+/* Board-specific definitions (hard-wired controller locations/IRQs) */
-+#include "plat_cnf.h"
-+#include "plat_arc.h"
-+#include "musbhdrc.h"
++      DBG(2, "end %d, device %d, parent %d, port %d, multi-tt: %d, speed:%d\n", \
++              bEnd, pUrb->dev->devnum, bHubAddr, bHubPort, bIsMulti, pUrb->dev->speed );
++}
++
++/**
++ * @param pThis
++ * @param pUrb
++ * @param bEnd
++ * @param bXmt
++ */
++static void hdrc_set_protocol(MGC_LinuxCd* pThis, struct urb* pUrb,
++      uint8_t bEnd, unsigned int bXmt)
++{
++    uint8_t reg;
++    uint8_t bStdType = hdrc_type(pUrb);
++    unsigned int nPipe = pUrb->pipe;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++      reg = (bStdType << 4 ) |
++              (((uint8_t)usb_pipeendpoint(nPipe)) & 0xf);
++              switch( ((uint8_t)pUrb->dev->speed) ) {
++                case USB_SPEED_LOW:
++                      reg |= 0xc0;
++                      break;
++                case USB_SPEED_FULL:
++                      reg |= 0x80;
++                      break;
++                default:
++                      reg |= 0x40;
++              }
++
++      if ( bXmt ) {
++              if(bEnd) {
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd, reg);
++              } else if(pThis->bIsMultipoint) {
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
++              }
++      } else {
++              if(bEnd) {
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXTYPE, bEnd, reg);
++              } else if(pThis->bIsMultipoint) {
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
++              }
++      }
++}
 +
-+/****************************** VERIFY THE DEFINES **************************
-+ * determine how to compile the driver; MUSB_GADGET->as gadget driver, 
-+ * MUSB_HOST as host mode, MUSB_OTG -> otg mode (host and gadget) 
-+ *
-+ * OTG => GADGET 
-+ */
++static void mgc_hdrc_flush_fifo(MGC_LinuxCd* pThis, uint8_t bEnd, int rx)
++{
++      if ( rx ) {
++              /* twice in case of double packet buffering */
++              MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd,
++                      MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++              MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd,
++              MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++      }
++}
 +
-+#ifdef MUSB_GSTORAGE
++static void mgc_hdrc_flush_end(MGC_LinuxCd* pThis, uint8_t bEnd) {
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
 +
-+/* for now */
-+#ifndef MUSB_OTG
-+#define MUSB_OTG
-+#endif
++      if(bEnd) {
++              /* general endpoint */
++              /* if not ready, flush and restore data toggle */
++              if(!pEnd->bIsReady && pThis->bIsMultipoint) {
++                      pEnd->bIsReady = TRUE;
 +
-+#endif
++                      /* twice in case of double packet buffering */
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++                                         MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG);
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++                                         MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG);
++              }
++      } else {
++              /* endpoint 0: just flush */
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd,
++                         MGC_M_CSR0_FLUSHFIFO);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd,
++                         MGC_M_CSR0_FLUSHFIFO);
++      }
++}
 +
-+#ifdef MUSB_OTG
-+#endif
-+#ifndef MUSB_HOST
-+#define MUSB_HOST
++/**
++ * Program an HDRC endpoint as per the given URB
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ * @param pURB URB pointer
++ * @param nOut zero for Rx; non-zero for Tx
++ * @param pBuffer buffer pointer
++ * @param dwLength how many bytes to transmit or expect to receive
++ */
++static void mgc_hdrc_program_end(MGC_LinuxCd* pThis, uint8_t bEnd,
++      struct urb* pUrb, unsigned int nOut, unsigned int bXmt,
++      uint8_t* pBuffer, uint32_t dwLength)
++{
++    uint16_t wIntrTxE;
++    uint8_t bDone = FALSE;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    unsigned int nPipe = pUrb->pipe;
++    uint16_t wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut);
++    uint8_t bIsBulk = usb_pipebulk(nPipe);
++    uint8_t bInterval=hdrc_interval(pUrb);
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++    uint8_t bStdType = hdrc_type(pUrb);
++      uint8_t bDmaOk=FALSE;
++#ifdef MUSB_DMA
++      MGC_DmaChannel* pDmaChannel;
++      MGC_DmaController* pDmaController;
 +#endif
++      unsigned long flags;
 +
-+#ifdef CONFIG_PROC_FS
-+#ifndef MUSB_CONFIG_PROC_FS
-+#define MUSB_CONFIG_PROC_FS
-+#endif
-+#endif
++    DBG(2, "<==(bEnd=%d, pUrb=%p) bRemoteAddress=%d\n", bEnd, pUrb, (uint8_t)usb_pipedevice(nPipe));
++    DBG(3, "end %d, device %d, speed:%d\n", bEnd, pUrb->dev->devnum,
++              pUrb->dev->speed );
 +
-+#ifdef MUSB_PROC_TESTMUSB
++    /* prepare endpoint registers according to flags */
++      SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++    MGC_SelectEnd(pBase, bEnd);
 +
-+#ifndef CONFIG_PROC_FS
-+#error "TestMusb needs CONFIG_PROC_FS"
-+#endif
++      if ( bStdType==0 ) {
++              bXmt=TRUE;
++      }
 +
-+#ifndef MUSB_HOST
-+#error "TestMusb needs HOST MODE"
-+#endif
++      hdrc_set_protocol(pThis, pUrb, bEnd, bXmt);
++      hdrc_set_address(pThis, pUrb, bEnd, bXmt);
 +
-+#endif
 +
-+#ifdef MUSB_HOST
-+#define MUSB_VIRTHUB
-+#endif
++#ifdef MUSB_DMA
++              pDmaController = pThis->pDmaController;
++              pDmaChannel = pEnd->pDmaChannel;
 +
-+/************************* DEFINES DEPENDENT INCLUDES ************************/
++              if( !WANTS_DMA(pUrb) && pDmaChannel) {
++                      /* release previously-allocated channel */
++                      pDmaController->pfDmaReleaseChannel(pDmaChannel);
++                      pEnd->pDmaChannel = NULL;
++              } else if( WANTS_DMA(pUrb) ) {
 +
-+/* virtual hub */
-+#include "musb_virthub.h" 
++                      /* candidate for DMA */
++                      if(pDmaController && !pDmaChannel) {
++                              pDmaChannel = pEnd->pDmaChannel = pDmaController->pfDmaAllocateChannel(
++                              pDmaController->pPrivateData, bEnd, nOut ? TRUE : FALSE,
++                                      bStdType, wPacketSize);
 +
-+/****************************** USB CONSTANTS ********************************/
++                      }
 +
-+#ifndef USB_DT_DEVICE_QUALIFIER
-+#define USB_DT_DEVICE_QUALIFIER 6
++                      if(pDmaChannel) {
++                              pDmaChannel->dwActualLength = 0L;
++                              pEnd->dwRequestSize = min(dwLength, pDmaChannel->dwMaxLength);
++                              bDmaOk = pDmaController->pfDmaProgramChannel(pDmaChannel,
++                                      wPacketSize, pDmaChannel->bDesiredMode, DMA_BUFFER(pUrb),
++                                      pEnd->dwRequestSize);
++                              if(!bDmaOk) {
++                                      pDmaController->pfDmaReleaseChannel(pDmaChannel);
++                                      pEnd->pDmaChannel = NULL;
++                              }
++                      }
++              }
 +#endif
 +
-+#ifndef USB_DT_DEVICE_QUALIFIER_SIZE
-+#define USB_DT_DEVICE_QUALIFIER_SIZE 10
-+#endif
++    if ( bXmt ) { /* transmit */
++              uint16_t wLoadCount=0;
++              uint16_t wCsr= MGC_M_TXCSR_MODE;
 +
-+#ifndef USB_DT_OTHER_SPEED
-+#define USB_DT_OTHER_SPEED 7
-+#endif
++              if ( !bDmaOk ) {
++                      if( bIsBulk && pThis->bBulkSplit ) {
++                              wLoadCount = min((uint32_t)pEnd->wMaxPacketSizeTx, dwLength);
++                      } else {
++                              wLoadCount = min((uint32_t)wPacketSize, dwLength);
++                      }
++              }
 +
-+#ifndef USB_MAXCHILDREN
-+#define USB_MAXCHILDREN         (16)
-+#endif
++              /* disable interrupt in case we flush */
++              wIntrTxE = MGC_Read16(pBase, MGC_O_HDRC_INTRTXE);
++              MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE & ~(1 << bEnd));
 +
-+/****************************** DEBUG CONSTANTS ********************************/
++              /* data toggle, make sure nothing is there! */
++              mgc_hdrc_flush_end(pThis, bEnd);
 +
-+#define MGC_PAD_FRONT   0xa5deadfe
-+#define MGC_PAD_BACK    0xabadcafe
-+#define MGC_TEST_PACKET_SIZE 53
++              if( bEnd) {
++                      wCsr |= MGC_M_TXCSR_H_WR_DATATOGGLE;
++                      if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 1)) {
++                              wCsr |= MGC_M_TXCSR_H_DATATOGGLE;
++                      } else {
++                              wCsr &= ~MGC_M_TXCSR_H_DATATOGGLE;
++                      }
 +
-+/****************************** CONSTANTS ********************************/
++                      /* protocol/endpoint/interval/NAKlimit */
++                      if(bIsBulk && pThis->bBulkSplit) {
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd,
++                                      wPacketSize |
++                                      ((pEnd->wMaxPacketSizeTx / wPacketSize) - 1) << 11);
++                      } else {
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, wPacketSize);
++                      }
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, bInterval);
 +
-+#if MUSB_DEBUG > 0
-+#define STATIC
-+#define MUSB_PARANOID
-+#else
-+#define STATIC static
++#ifdef MUSB_DMA
++                      if (bDmaOk) {
++                              wCsr |= (MGC_M_TXCSR_AUTOSET | MGC_M_TXCSR_DMAENAB |
++                              (pDmaChannel->bDesiredMode ? MGC_M_TXCSR_DMAMODE : 0));
++                      }
 +#endif
 +
-+#ifndef TRUE
-+#define TRUE 1
-+#endif
-+#ifndef FALSE
-+#define FALSE 0
-+#endif
++                      mgc_linux_packet_tx(pThis, bEnd);
++              } else {
++                      /* protocol/endpoint/interval/NAKlimit */
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, bInterval);
++                      if ( wLoadCount ) {
++                              pEnd->dwRequestSize = wLoadCount;
++                              MGC_HdrcLoadFifo(pThis->pRegs, bEnd, wLoadCount, pBuffer);
++                      }
++              }
 +
-+#ifndef MUSB_C_NUM_EPS
-+#define MUSB_C_NUM_EPS ((uint8_t)16)
-+#endif
++              /* re-enable interrupt and write CSR to transmit */
++              MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE);
 +
-+#ifndef MUSB_MAX_END0_PACKET
-+#define MUSB_MAX_END0_PACKET ((uint16_t)MGC_END0_FIFOSIZE)
-+#endif
++              if (bEnd) {
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
++              }
++    } else { /* receive */
 +
-+#define MGC_END0_START  0x0
-+#define MGC_END0_OUT    0x2
-+#define MGC_END0_IN     0x4
-+#define MGC_END0_STATUS 0x8
++              /* if was programmed for Tx, be sure it is ready for re-use */
++              uint16_t wCsr=MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++        if ( pEnd->bIsSharedFifo && wCsr & MGC_M_TXCSR_MODE) {
++                      pEnd->bIsReady = FALSE;
 +
-+#define MGC_END0_STAGE_SETUP          0x0
-+#define MGC_END0_STAGE_TX             0x2
-+#define MGC_END0_STAGE_RX             0x4
-+#define MGC_END0_STAGE_STATUSIN               0x8
-+#define MGC_END0_STAGE_STATUSOUT        0xf
-+#define MGC_END0_STAGE_STALL_BIT      0x10
++                      DBG(1, "reprogramming ep%d for rx\n", bEnd);
 +
-+/* obsolete */
-+#define MGC_END0_STAGE_DATAIN         MGC_END0_STAGE_TX
-+#define MGC_END0_STAGE_DATAOUT                MGC_END0_STAGE_RX
++                      if ( wCsr & MGC_M_TXCSR_FIFONOTEMPTY ) {
++                              /* this shouldn't happen */
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++                                         MGC_M_TXCSR_FRCDATATOG);
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++                                         MGC_M_TXCSR_FRCDATATOG);
 +
-+/* EASY GUESS */
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-+#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus, _port)
-+#else
-+/* 2.4, mvl21, bc5 */
-+#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus)
-+#endif
++                              ERR("*** switching end %d to Rx but Tx FIFO not empty\n", bEnd);
++                              MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP;
++                      }
 +
++                      /* clear mode (and everything else) to enable Rx */
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 0);
++              }
 +
-+/* 2.4/2.6 compatibility */
-+#ifdef MUSB_V26 
++              /* grab Rx residual if any */
++              wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
++              if (wCsr & MGC_M_RXCSR_RXPKTRDY) {
++                      uint16_t wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
++                      bDone = mgc_linux_packet_rx(pThis, bEnd, wRxCount, FALSE);
++                      DBG(1, "residual found bDone=%d\n", bDone);
++              }
 +
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
-+#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) ((_dev)->bus->op->disable(_dev, _pipe_ep))
-+#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
-+#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) ( 0 )
-+#else
-+#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
-+#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
-+#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
++              /* protocol/endpoint/interval/NAKlimit */
++              if(bEnd) {
++#if 0
++                      /* doesn't work reliably */
++                      if(bIsBulk && pThis->bBulkCombine) {
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize |
++                                      ((min(pEnd->wMaxPacketSizeRx, dwLength) / wPacketSize) - 1) << 11);
++                      } else {
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize);
++                      }
 +#endif
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize);
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, bInterval);
++              }
 +
-+/*#define COMPLETE_URB(_pUrb, _p)        _pUrb->complete(_pUrb, _p)*/
-+#define COMPLETE_URB(_pUrb, _p)        (_pUrb->complete=_p)            
-+#define WAIT_MS(_ms)                  mdelay(_ms)
++              /* first time or re-program and shared FIFO, flush & clear toggle */
++              if(!pEnd->bIsReady && pEnd->bIsSharedFifo) {
++                      DBG(4, "shared fifo\n");
 +
-+#define USB_ISO_ASAP            0x0002
-+#define USB_ASYNC_UNLINK        0x0008
++                      /* twice in case of double packet buffering */
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++                                 MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++                                 MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
++                      pEnd->bIsReady = TRUE;
++              }
 +
-+#define USB_ST_NOERROR          (0)
-+#define USB_ST_CRC              (-EILSEQ)
-+#define USB_ST_BITSTUFF         (-EPROTO)
-+#define USB_ST_NORESPONSE       (-ETIMEDOUT)    /* device not responding/handshaking */
-+#define USB_ST_DATAOVERRUN      (-EOVERFLOW)
-+#define USB_ST_DATAUNDERRUN     (-EREMOTEIO)
-+#define USB_ST_BUFFEROVERRUN    (-ECOMM)
-+#define USB_ST_BUFFERUNDERRUN   (-ENOSR)
-+#define USB_ST_INTERNALERROR    (-EPROTO)       /* unknown error */
-+#define USB_ST_SHORT_PACKET     (-EREMOTEIO)
-+#define USB_ST_PARTIAL_ERROR    (-EXDEV)        /* ISO transfer only partially completed */
-+#define USB_ST_URB_KILLED       (-ENOENT)       /* URB canceled by user */
-+#define USB_ST_URB_PENDING      (-EINPROGRESS)
-+#define USB_ST_REMOVED          (-ENODEV)       /* device not existing or removed */
-+#define USB_ST_TIMEOUT          (-ETIMEDOUT)    /* communication timed out, also in urb->status**/
-+#define USB_ST_NOTSUPPORTED     (-ENOSYS)
-+#define USB_ST_BANDWIDTH_ERROR  (-ENOSPC)       /* too much bandwidth used */
-+#define USB_ST_URB_INVALID_ERROR  (-EINVAL)     /* invalid value/transfer type */
-+#define USB_ST_URB_REQUEST_ERROR  (-ENXIO)      /* invalid endpoint */
-+#define USB_ST_STALL            (-EPIPE)        /* pipe stalled, also in urb->status*/
-+                                                                                
-+#define USB_ZERO_PACKET         0x0040        /* Finish bulk OUTs always with zero length packet */
++              /* program data toggle if possibly switching use */
++              if(!pEnd->bIsReady && pThis->bIsMultipoint) {
++                      DBG(4, "multipoint\n");
 +
-+#endif
++                      wCsr = MGC_M_RXCSR_H_WR_DATATOGGLE;
++                      if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 0)) {
++                              wCsr |= MGC_M_RXCSR_H_DATATOGGLE;
++                      }
 +
-+#ifdef MUSB_V24
-+#define usb_disabled()                        0
-+#define COMPLETE_URB(_pUrb, _p)               _pUrb->complete(_pUrb)
-+#define WAIT_MS(_ms)                  wait_ms(_ms)
-+#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
-+#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr);
++              }
 +
-+#ifdef MUSB_LINUX_MV21
-+#define usb_get_urb(_pUrb) _pUrb
-+#define usb_put_urb(_pUrb)
-+#undef MUSB_HAS_BUSNAME
++              /* kick things off */
++              if( bEnd && !bDone) {
++                      wCsr = MGC_M_RXCSR_H_REQPKT;
++                      if(usb_pipeint(nPipe)) {
++                              wCsr |= MGC_M_RXCSR_DISNYET;
++                      }
++#ifdef MUSB_DMA
++                      if(bDmaOk) {
++                              wCsr &= ~MGC_M_RXCSR_H_REQPKT;
++                              wCsr |= MGC_M_RXCSR_H_AUTOREQ;
++                              wCsr |= (MGC_M_RXCSR_AUTOCLEAR | MGC_M_RXCSR_DMAENAB |
++                                      (pDmaChannel->bDesiredMode ? MGC_M_RXCSR_DMAMODE : 0));
++                      }
 +#endif
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr);
++              }
++    }
++      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++    DBG(2, "==>\n");
++}
 +
-+#endif
++/* *************************************************************************
++ *
++ **************************************************************************/
 +
-+typedef enum
++static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis)
 +{
-+  MGC_STATE_DEFAULT,
-+  MGC_STATE_ADDRESS,
-+  MGC_STATE_CONFIGURED
-+} MGC_DeviceState;
-+
-+/* failure codes */
-+#define MUSB_ERR_WAITING      1
-+#define MUSB_ERR_VBUS         -1
-+#define MUSB_ERR_BABBLE               -2
-+#define MUSB_ERR_CORRUPTED    -3
-+#define MUSB_ERR_IRQ          -4
-+#define MUSB_ERR_SHUTDOWN     -5
-+#define MUSB_ERR_RESTART      -6
-+
-+/****************************** FUNCTIONS ********************************/
-+
-+#define KMALLOC(a,b,c)        { lock_kernel(); a=kmalloc(b,c); unlock_kernel(); }
-+#define KFREE(p)      { lock_kernel(); kfree(p); unlock_kernel(); }
-+
-+/*************************** REGISTER ACCESS ********************************/
++      uint16_t wVal=0;
++      unsigned long flags;
++      uint8_t* pBase = (uint8_t*)pThis->pRegs;
 +
-+/* indexed vs. flat register model */
-+#ifdef MUSB_FLAT_REG
-+#define MGC_SelectEnd(_pBase, _bEnd)
-+#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
-+    MGC_Read8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
-+#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
-+    MGC_Read16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
-+#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
-+    MGC_Write8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
-+#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
-+    MGC_Write16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
-+#else
-+#define MGC_SelectEnd(_pBase, _bEnd) \
-+    MGC_Write8(_pBase, MGC_O_HDRC_INDEX, _bEnd)
-+#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
-+    MGC_Read8(_pBase, (_bOffset + 0x10))
-+#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
-+    MGC_Read16(_pBase, (_bOffset + 0x10))
-+#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
-+    MGC_Write8(_pBase, (_bOffset + 0x10), _bData)
-+#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
-+    MGC_Write16(_pBase, (_bOffset + 0x10), _bData)
-+#endif
++    pEnd->dwOffset = 0;
++    pEnd->dwRequestSize = 0;
++    pEnd->dwIsoPacket = 0;
++    pEnd->dwWaitFrame = 0;
++    pEnd->bRetries = 0;
 +
++      /* do the proper sequence to abort the transfer */
++      SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
 +
-+/************************** ULPI Registers ********************************/
++      MGC_SelectEnd(pBase, pEnd->bEnd);
 +
-+/* Added in HDRC 1.9(?) & MHDRC 1.4 */
-+/* ULPI pass-through */
-+#define MGC_O_HDRC_ULPI_VBUSCTL       0x70
-+#define MGC_O_HDRC_ULPI_REGDATA 0x74
-+#define MGC_O_HDRC_ULPI_REGADDR 0x75
-+#define MGC_O_HDRC_ULPI_REGCTL        0x76
++      if((pEnd->bRemoteEnd & 0x0F) == 0)
++      {
++              wVal |= MGC_M_CSR0_FLUSHFIFO;
++              wVal &= ~MGC_M_CSR0_H_REQPKT;
++              wVal &= ~MGC_M_CSR0_TXPKTRDY;
 +
-+/* extended config & PHY control */
-+#define MGC_O_HDRC_ENDCOUNT   0x78
-+#define MGC_O_HDRC_DMARAMCFG  0x79
-+#define MGC_O_HDRC_PHYWAIT    0x7A
-+#define MGC_O_HDRC_PHYVPLEN   0x7B    /* units of 546.1 us */
-+#define MGC_O_HDRC_HSEOF1     0x7C    /* units of 133.3 ns */
-+#define MGC_O_HDRC_FSEOF1     0x7D    /* units of 533.3 ns */
-+#define MGC_O_HDRC_LSEOF1     0x7E    /* units of 1.067 us */
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wVal);
++      }
++      else
++      {
++              if(pEnd->bIsTx)
++              {
++                      wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
++                      wVal |= MGC_M_TXCSR_FLUSHFIFO;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal);
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal);
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, pEnd->bEnd, 0);
++              }
++              else
++              {
++                      wVal &= ~MGC_M_RXCSR_H_REQPKT;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, pEnd->bEnd, wVal);
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, pEnd->bEnd, 0);
++              }
++      }
 +
-+/* Added in HDRC 1.9(?) & MHDRC 1.4 */
-+/* ULPI */
-+#define MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND    0x02
-+#define MGC_M_ULPI_VBUSCTL_USEEXTVBUS     0x01
-+#define MGC_M_ULPI_REGCTL_INT_ENABLE      0x08
-+#define MGC_M_ULPI_REGCTL_READNOTWRITE            0x04
-+#define MGC_M_ULPI_REGCTL_COMPLETE        0x02
-+#define MGC_M_ULPI_REGCTL_REG             0x01
-+/* extended config & PHY control */
-+#define MGC_M_ENDCOUNT_TXENDS 0x0f
-+#define MGC_S_ENDCOUNT_TXENDS 0
-+#define MGC_M_ENDCOUNT_RXENDS 0xf0
-+#define MGC_S_ENDCOUNT_RXENDS 4
-+#define MGC_M_DMARAMCFG_RAMBITS       0x0f        /* RAMBITS-1 */
-+#define MGC_S_DMARAMCFG_RAMBITS       0
-+#define MGC_M_DMARAMCFG_DMACHS        0xf0
-+#define MGC_S_DMARAMCFG_DMACHS        4
-+#define MGC_M_PHYWAIT_WAITID  0x0f        /* units of 4.369 ms */
-+#define MGC_S_PHYWAIT_WAITID  0
-+#define MGC_M_PHYWAIT_WAITCON 0xf0        /* units of 533.3 ns */
-+#define MGC_S_PHYWAIT_WAITCON 4
++      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
 +
-+/****************************** FUNCTIONS ********************************/
++#ifdef MUSB_USE_HCD_DRIVER
++      pEnd->pCurrentUrb=NULL;
++#endif
++}
 +
-+#define MUSB_HST_MODE(_pthis) { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
-+      (_pthis)->bIsA=1; (_pthis)->bFailCode=0; }
-+#define MUSB_DEV_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
-+      (_pthis)->bIsA=0; (_pthis)->bFailCode=0; }
-+#define MUSB_B_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-+      (_pthis)->bIsA=0; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
-+#define MUSB_A_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-+      (_pthis)->bIsA=1; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
-+#define MUSB_ERR_MODE(_pthis, _cause) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-+      (_pthis)->bFailCode=_cause; }
++/**
++ * Start the current URB on an endpoint; wants ep to be
++ * locked and pThis to be locked as well; end must be claimed
++ * from the caller.
++ *
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ * @pre the endpoint is locked from the caller
++ * @pre pThis is NOT locked
++ */
++static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++    uint16_t wFrame;
++    uint32_t dwLength;
++    void* pBuffer;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++    struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
++    unsigned int nPipe, nOut, bXmt;
++    uint16_t wPacketSize;
++    uint8_t bRemoteAddress, bRemoteEnd;
 +
-+#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
-+#define MUSB_IS_HST(_x) ( !MUSB_IS_ERR(_x) && (_x)->bIsHost && !(_x)->bIsDevice )
-+#define MUSB_IS_DEV(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && (_x)->bIsDevice )
-+#define MUSB_IS_B_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && !(_x)->bIsA )
-+#define MUSB_IS_A_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && (_x)->bIsA )
++      /* I should not have called!!! */
++      if ( !pUrb ) {
++              ERR("***> bEnd=%d is idle!\n", bEnd);
++              return;
++      }
 +
-+#define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST":( MUSB_IS_DEV(_x)?"FUNCTION":(MUSB_IS_B_IDLE(_x)?"B_IDLE":(MUSB_IS_A_IDLE(_x)?"A_IDLE":"ERROR"))) )
++      if ( pUrb->hcpriv ) {
++              ERR("==> pUrb=%p, pUrb->hcpriv=%p, pEnd=%p, bEnd=%d (%s) was kickstarted already! this is not good (TM)\n",
++                      pUrb, pUrb->hcpriv, pEnd, bEnd, decode_urb_protocol(pUrb));
++      }
 +
-+#define HDRC_IS_HST(_x) (  MGC_Read8((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM )
-+#define HDRC_IS_DEV(_x) (  !HDRC_IS_HST(_x) )
++    nPipe = pUrb->pipe;
++    nOut = usb_pipeout(nPipe);
++      bXmt = nOut ? TRUE : FALSE;
++    wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut);
++    bRemoteAddress = (uint8_t)usb_pipedevice(nPipe);
++    bRemoteEnd = (uint8_t)usb_pipeendpoint(nPipe);
 +
++      DBG(2, "<== pUrb=%p, bEnd=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, nOut=%d\n",
++              pUrb, bEnd, wPacketSize, bRemoteAddress, bRemoteEnd, nOut);
 +
-+/******************************** DMA TYPES **********************************/
++    /* if no root device, assume this must be it */
++    if(!pThis->pRootDevice) {
++              pThis->pRootDevice = pUrb->dev;
++              switch(pThis->bRootSpeed) {
++                case 1:
++                      pThis->pRootDevice->speed = USB_SPEED_HIGH;
++                      break;
++                case 2:
++                      pThis->pRootDevice->speed = USB_SPEED_FULL;
++                      break;
++                case 3:
++                      pThis->pRootDevice->speed = USB_SPEED_LOW;
++                      break;
++              }
++    }
 +
-+#ifdef MUSB_DMA
-+#include "dma.h"
++    /* indicate in progress */
++    pUrb->actual_length = 0;
++    pUrb->error_count = 0;
++      pUrb->hcpriv = pEnd;
++      /* remember software state - find_end() will use this - */
++    pEnd->bRemoteAddress = bRemoteAddress;
++    pEnd->bRemoteEnd = bRemoteEnd;
++    pEnd->bTrafficType = (uint8_t)usb_pipetype(nPipe);
++    pEnd->bIsTx=bXmt;
 +
-+#ifndef MGC_HSDMA_CHANNELS
-+#define MGC_HSDMA_CHANNELS 8
-+#endif
++    /* init urb */
++    pEnd->dwOffset = 0;
++    pEnd->dwRequestSize = 0;
++    pEnd->dwIsoPacket = 0;
++    pEnd->dwWaitFrame = 0;
++    pEnd->bRetries = 0;
++    pEnd->wPacketSize = wPacketSize;
 +
-+#ifdef MUSB_HAS_DMA_URBS
-+#define WANTS_DMA(_pUrb) ((_pUrb)->transfer_dma && (_pUrb->flags & URB_NO_TRANSFER_DMA_MAP))
-+#define DMA_BUFFER(_pUrb) ((_pUrb)->transfer_dma)
-+#else
-+#define WANTS_DMA(_pUrb) (0)
-+#define DMA_BUFFER(pUrb) ((void*)0x000666) 
++#ifdef MUSB_USE_HCD_DRIVER
++      pEnd->pCurrentUrb=pUrb;
 +#endif
 +
-+extern MGC_DmaControllerFactory MGC_HdrcDmaControllerFactory;
-+#endif
++    /* pEnd->bIsClaimed=(usb_pipeisoc(nPipe) || usb_pipeint(nPipe)) ?TRUE:FALSE;
++     * end must be claimed from my caller
++     */
++    if( usb_pipecontrol(nPipe) ) {
++              /* control transfers always start with an OUT */
++              bXmt=TRUE;
++              pEnd->bIsTx=TRUE;
++              pThis->bEnd0Stage = MGC_END0_START;
++    }
 +
++    /* gather right source of data */
++    if( usb_pipeisoc(nPipe) ) {
++              pBuffer = pUrb->transfer_buffer + pUrb->iso_frame_desc[0].offset;
++              dwLength = pUrb->iso_frame_desc[0].length;
++    } else if(usb_pipecontrol(nPipe)) {
++              pBuffer = pUrb->setup_packet;
++              dwLength = 8;
++    } else {
++              /* - */
++              pBuffer = pUrb->transfer_buffer;
++              dwLength = pUrb->transfer_buffer_length;
++    }
 +
-+/************************** Ep Configuration ********************************/
++#ifndef MUSB_LINUX_MV21
++    if ( !pBuffer ) {
++      pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
++    }
++#endif
 +
-+/** The End point descriptor */
-+struct MUSB_EpFifoDescriptor {
-+    uint8_t bType;    /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */
-+    uint8_t bDir;     /* 0 for autoconfig, INOUT, IN, OUT */
-+    uint16_t wSize;   /* 0 for autoconfig, or the size */
-+    uint8_t bDbe;     /* Double buffering: 0 disabled, 1 enabled */
-+};
++      /* abort the transfer */
++    if ( !pBuffer ) {
++              ERR("Rx requested but no buffer was given, BAD things are happening (TM)! aborting\n");
++              return;
++    }
 +
-+#define MUSB_EPD_AUTOCONFIG   0
++    DBG(3, "(%p): dir=%s, type=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, pBuffer=%p\n", \
++              pUrb, (nOut)?"out":"in", usb_pipetype(nPipe), wPacketSize, bRemoteAddress,
++              bRemoteEnd, pBuffer);
 +
-+#define MUSB_EPD_T_CNTRL      1
-+#define MUSB_EPD_T_ISOC               2
-+#define MUSB_EPD_T_BULK               3
-+#define MUSB_EPD_T_INTR               4
++    /* Configure endpoint */
++    mgc_hdrc_program_end(pThis, bEnd, pUrb, nOut, bXmt, pBuffer, dwLength);
 +
-+#define MUSB_EPD_D_INOUT      0
-+#define MUSB_EPD_D_TX         1
-+#define MUSB_EPD_D_RX         2
++    /* if transmit, start it if it is time */
++    if ( !bXmt ) {
++              DBG(2, "==>\n");
++              return;
++      }
 +
-+/******************************** TYPES *************************************/
++      /* determine if the time is right for a periodic transfer */
++      if( usb_pipeisoc(nPipe) || usb_pipeint(nPipe) ) {
++              DBG(3, "check whether there's still time for periodic Tx\n");
++              pEnd->dwIsoPacket = 0;
++              wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME);
 +
-+struct urb;
-+struct usb_device;
-+struct usb_gadget;
-+struct usb_hcd;
++              if((pUrb->transfer_flags & USB_ISO_ASAP) ||
++                 (wFrame >= pUrb->start_frame))
++              {
++                      pEnd->dwWaitFrame = 0;
++                      MGC_HdrcStartTx(pThis, bEnd);
++              } else {
++                      pEnd->dwWaitFrame = pUrb->start_frame;
++                      /* enable SOF interrupt so we can count down */
++                      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xff);
++              }
++      } else {
++              MGC_HdrcStartTx(pThis, bEnd);
++      }
 +
-+/**
-+ * The device request.
-+ */
-+typedef struct __attribute__((packed)) {
-+    uint8_t bmRequestType;
-+    uint8_t bRequest;
-+    uint16_t wValue;
-+    uint16_t wIndex;
-+    uint16_t wLength;
-+} MUSB_DeviceRequest;
++      DBG(2, "==>\n");
++}
 +
 +/**
-+ * MGC_LinuxLocalEnd.
-+ * Local endpoint resource.
-+ * @field Lock spinlock
-+ * @field pUrb current URB
-+ * @field urb_list list
-+ * @field dwOffset current buffer offset
-+ * @field dwRequestSize how many bytes were last requested to move
-+ * @field wMaxPacketSizeTx local Tx FIFO size
-+ * @field wMaxPacketSizeRx local Rx FIFO size
-+ * @field wPacketSize programmed packet size
-+ * @field bIsSharedFifo TRUE if FIFO is shared between Tx and Rx
-+ * @field bAddress programmed bus address
-+ * @field bEnd programmed remote endpoint address
-+ * @field bTrafficType programmed traffic type
-+ * @field bIsClaimed TRUE if claimed
-+ * @field bIsTx TRUE if current direction is Tx
-+ * @field bIsReady TRUE if ready (available for new URB)
++ * Start the next URB on an endpoint. Wants the _endpoint_ to be locked.
++ * It might call MGC_LinuxStartUrb pThis needs to be locked as well..
++ * THIS UNLOCK THE END POINT.
++ *
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
 + */
-+typedef struct
++static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd)
 +{
-+#if MUSB_DEBUG > 0
-+    uint32_t dwPadFront;
-+#endif
-+    spinlock_t Lock;
-+    uint8_t bEnd; /* ep number */
-+    
-+#ifdef MUSB_USE_HCD_DRIVER
-+      struct urb* pCurrentUrb; 
-+#else
-+    struct list_head urb_list;
-+#endif
-+
-+      uint8_t bBusyCompleting; /* TRUE on Tx when the current urb is completing */
-+
-+    unsigned int dwOffset;            /* offset int the current request */
-+    unsigned int dwRequestSize; /* request size */
-+    unsigned int dwIsoPacket;
-+    unsigned int dwWaitFrame;
-+    uint8_t bRetries; 
-+
-+#ifdef MUSB_DMA
-+    MGC_DmaChannel* pDmaChannel;
-+#endif
++#ifndef MUSB_USE_HCD_DRIVER
++    struct urb* pUrb;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+    unsigned long dwTotalTxBytes;
-+    unsigned long dwTotalRxBytes;
-+    unsigned long dwTotalTxPackets;
-+    unsigned long dwTotalRxPackets;
-+    unsigned long dwErrorTxPackets;
-+    unsigned long dwErrorRxPackets;
-+    unsigned long dwMissedTxPackets;
-+    unsigned long dwMissedRxPackets;
-+#endif
++    DBG(1, "<== bEnd=%d\n", bEnd);
++      pUrb=MGC_GetCurrentUrb(pEnd);
++      if ( !pUrb ) {
++              DBG(2, "==> bEnd=%d idle\n", bEnd);
++              return;
++      }
 +
-+    uint16_t wMaxPacketSizeTx;
-+    uint16_t wMaxPacketSizeRx;
-+    uint16_t wPacketSize;
-+    uint8_t bDisableDma; /* not used now! */
-+    uint8_t bIsSharedFifo;
-+      
-+      /* softstate, used from find_end() to determine a good match */
-+    uint8_t bRemoteAddress;
-+    uint8_t bRemoteEnd;       
-+    uint8_t bTrafficType;
-+    uint8_t bIsClaimed; /* only for isoc and int traffic */    
-+    uint8_t bIsTx;
-+    uint8_t bIsReady; 
-+      uint8_t bStalled; /* the ep has been halted */  
++      /* introduce a delay between urbs, to accomodate slow devices. The counter
++       * is increased on every NAK/TIMEOUT and decreased on successful transfers
++       * (eps != 0 )
++       */
++      if ( mgc_slow_device_kludge_delay ) {
++              DBG(1, "Delay mgc_slow_device_kludge_delay=%d\n",
++                      mgc_slow_device_kludge_delay);
++              udelay( mgc_slow_device_kludge_delay*20 );
++      }
 +
-+#if MUSB_DEBUG > 0
-+    uint32_t dwPadBack;
++    /* check for linked URB and jump start the next one */
++      mgc_linux_kickstart_urb(pThis, bEnd);
++#else
++    DBG(1, "<== bEnd=%d\n", bEnd);
++      if ( MUSB_IS_HST(pThis) ) {
++              mgc_hcd_schedule_urb(pThis);
++      }
 +#endif
-+} MGC_LinuxLocalEnd;
-+
-+/** A listener for disconnection */
-+typedef void (*MGC_pfDisconnectListener)(void*);
-+/** A handler for the default endpoint interrupt */
-+typedef void (*MGC_pfDefaultEndHandler)(void*);
++      DBG(1, "==>\n");
++}
 +
-+#ifdef MUSB_USE_HCD_DRIVER
-+typedef struct {
-+    spinlock_t urb_queue_lock;
-+      int urb_queue_count;
-+      int urb_exec_count;     
-+    void *urb_queue_head;
-+    void *urb_queue_tail;     
-+} mgc_hcd_urb_queue;
-+#endif
++/* *************************************************************************
++ *
++ **************************************************************************/
 +
 +/**
-+ * MGC_LinuxCd.
-+ * Driver instance data.
-+ * @field Lock spinlock
-+ * @field Timer interval timer for various things
-+ * @field pBus pointer to Linux USBD bus
-+ * @field RootHub virtual root hub
-+ * @field PortServices services provided to virtual root hub
-+ * @field pRootDevice root device pointer, to track connection speed
-+ * @field nIrq IRQ number (needed by free_irq)
-+ * @field bIsMultipoint TRUE if multi-point core
-+ * @field bIsHost TRUE if host
-+ * @field bIsDevice TRUE if peripheral
-+ * @field pRegs pointer to mapped registers
++ * Try to stop traffic on the given local endpoint. Don;t worry about the
++ * urbs, they will be flushed from the system (later on).
++ *
++ * @param pThis the controller
++ * @param bEnd the endpoint number.
 + */
-+typedef struct
++void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd)
 +{
-+#if MUSB_DEBUG > 0
-+    uint32_t dwPadFront;
-+#endif
-+    spinlock_t Lock;
-+    struct timer_list Timer;
-+    struct usb_bus *pBus;
-+    char aName[32];
-+    MGC_VirtualHub RootHub;
-+    MGC_PortServices PortServices;
-+    struct usb_device* pRootDevice;
++      uint16_t wCsr;
++      uint8_t* pBase = (uint8_t*)pThis->pRegs;
++      const uint8_t reg=(bEnd)?MGC_O_HDRC_RXCSR:MGC_O_HDRC_CSR0;
 +
-+#ifdef MUSB_DMA
-+    MGC_DmaController* pDmaController;
-+#endif
++    DBG(2, "<== ep%d\n", bEnd);
++      wCsr = MGC_ReadCsr16(pBase, reg, bEnd);
++      wCsr &= (bEnd)?~MGC_M_RXCSR_H_REQPKT:~MGC_M_CSR0_H_REQPKT;
++      MGC_WriteCsr16(pBase, reg, bEnd, wCsr);
++    DBG(2, "==>\n");
++}
 +
-+    int nIrq;
-+      int nIrqType;
-+      
-+    int nBabbleCount;
-+    void* pRegs;
++/* *************************************************************************
++ *
++ **************************************************************************/
 +
-+    MGC_LinuxLocalEnd aLocalEnd[MUSB_C_NUM_EPS];
-+      
-+#ifdef MUSB_USE_HCD_DRIVER
-+      mgc_hcd_urb_queue LocalQueue;
-+      wait_queue_head_t waitqh;
-+#endif
-+      
-+    uint16_t wEndMask;
-+    uint8_t bEndCount;
-+    uint8_t bRootSpeed;
-+    uint8_t bIsMultipoint;
-+    uint8_t bIsHost;
-+    uint8_t bIsDevice;
-+    uint8_t bIsA;
-+    uint8_t bIgnoreDisconnect; /* during bus resets I got fake disconnects */
-+      uint8_t bVbusErrors; /* bus errors found */
-+    
-+    int bFailCode; /* one of MUSB_ERR_* failure code */
-+    
-+    uint8_t bBulkTxEnd;
-+    uint8_t bBulkRxEnd;
-+    uint8_t bBulkSplit;
-+    uint8_t bBulkCombine;
++/**
++ * Service the default endpoint (ep0) as host.
++ * @param pThis this
++ * @param wCount current byte count in FIFO
++ * @param pUrb URB pointer for EP0
++ * @return TRUE if more packets are required for this transaction
++ */
++static uint8_t mgc_hdrc_service_host_default(MGC_LinuxCd* pThis,
++      uint16_t wCount, struct urb* pUrb)
++{
++    uint8_t bMore = FALSE;
++    uint8_t* pFifoDest = NULL;
++    uint16_t wFifoCount = 0;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]);
++    MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;
 +
-+    uint8_t bEnd0Stage; /* end0 stage while in host or device mode */
++    DBG(2, "<== (wCount=%04x, pUrb=%lx, bStage=%02x)\n",
++      wCount, (unsigned long)pUrb, pThis->bEnd0Stage);
 +
-+#ifdef MUSB_GADGET
-+    uint8_t bDeviceState;
-+    uint8_t bIsSelfPowered;
-+    uint8_t bSetAddress;
-+    uint8_t bAddress;
-+    uint8_t bTestMode;
-+    uint8_t bTestModeValue;
++    if(MGC_END0_IN == pThis->bEnd0Stage) {
++        /* we are receiving from peripheral */
++        pFifoDest = pUrb->transfer_buffer + pUrb->actual_length;
++              wFifoCount = min(wCount, ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length)));
 +
-+    struct usb_gadget* pGadget; /* the gadget */
-+    struct usb_gadget_driver* pGadgetDriver; /* it's driver */
++      DBG(3, "Receiving %d bytes in &%p[%d] (pUrb->actual_length=%u)\n",
++              wFifoCount, pUrb->transfer_buffer, (unsigned int)pUrb->actual_length,
++                      pUrb->actual_length );
 +
-+    /* Endpoint 0 buffer and its buffer code; can be customized for 
-+     * devices that are not usign the default USB headers. Default
-+     * values are:
-+       *
-+     * . pfFillBuffer is MGC_HdrcReadUSBControlRequest() 
-+     * . pEnd0Buffer is an instance of MGC_End0Buffer
-+     **/
-+    int (*pfReadHeader)(void*, uint16_t); /* NULL==MGC_HdrcReadUSBControlRequest*/
-+   void* pEnd0Buffer; /* this is the buffer, default implementation uses MGC_End0Buffer */        
++              MGC_HdrcUnloadFifo(pBase, 0, wFifoCount, pFifoDest);
 +
-+    /* compatibility, need to be osoleted used from gstorage */
-+    uint16_t wEnd0Offset;     
++#ifdef MUSB_CONFIG_PROC_FS
++              pEnd->dwTotalRxBytes += wFifoCount;
++              pEnd->dwTotalRxPackets++;
 +#endif
 +
-+#ifdef MUSB_OTG
-+    MGC_OtgMachine OtgMachine;
-+    MGC_OtgServices OtgServices;
-+    uint8_t bDelayPortPowerOff;
-+    uint8_t bOtgError;
-+#endif
++              pUrb->actual_length += wFifoCount;
++              if((pUrb->actual_length < pUrb->transfer_buffer_length) &&
++                 (wCount == pEnd->wPacketSize))
++              {
++                      bMore = TRUE;
++              }
++    } else {
++        /* we are sending to peripheral */
++        if((MGC_END0_START == pThis->bEnd0Stage) &&
++                      (pRequest->bmRequestType & USB_DIR_IN))
++              {
++                      DBG(3, "just did setup, switching to IN\n");
 +
-+#if MUSB_DEBUG > 0
-+    uint32_t dwPadBack;
-+#endif
++                      /* this means we just did setup; switch to IN */
++                      pThis->bEnd0Stage = MGC_END0_IN;
++                      bMore = TRUE;
 +
 +#ifdef MUSB_CONFIG_PROC_FS
-+    struct proc_dir_entry* pProcEntry;
-+
-+    /* A couple of hooks to enable HSET */
-+    MGC_pfDisconnectListener pfDisconnectListener;
-+    void* pDisconnectListenerParam;
-+    MGC_pfDefaultEndHandler pfDefaultEndHandler;
-+    void* pDefaultEndHandlerParam;    
++          pEnd->dwTotalTxBytes += 8;
++          pEnd->dwTotalTxPackets++;
 +#endif
++              } else if(pRequest->wLength && (MGC_END0_START == pThis->bEnd0Stage)) {
++                      pThis->bEnd0Stage = MGC_END0_OUT;
++                      pFifoDest = (uint8_t*)(pUrb->transfer_buffer + pUrb->actual_length);
++                      wFifoCount = min(pEnd->wPacketSize,
++                      ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length)));
++                      DBG(3, "Sending %d bytes to %p\n", wFifoCount, pFifoDest);
++                      MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoDest);
 +
-+} MGC_LinuxCd;
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+void mgc_hcd_complete_urb(MGC_LinuxCd *pThis, struct urb* pUrb);
-+mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis);
++#ifdef MUSB_CONFIG_PROC_FS
++                      pEnd->dwTotalTxBytes += wFifoCount;
++                      pEnd->dwTotalTxPackets++;
 +#endif
++                      pEnd->dwRequestSize = wFifoCount;
++                      pUrb->actual_length += wFifoCount;
++                      if(wFifoCount) {
++                              bMore = TRUE;
++                      }
++              }
++    }
++
++    return bMore;
++}
 +
++/* *************************************************************************
++ * Default end (end 0)
++ **************************************************************************/
 +
-+/***************************** Glue it together *****************************/
++/**
++ * Handle default endpoint interrupt as host. Only called in IRQ time
++ * from the LinuxIsr() interrupt service routine.
++ * @param pThis this
++ */
++void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis)
++{
++    struct urb* pUrb;
++    unsigned long flags;
++    uint16_t wCsrVal, wCount;
++    int status = USB_ST_NOERROR;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]);
++    uint8_t bVal, bOutVal = 0, bComplete = FALSE, bError = FALSE;
++      struct usb_descriptor_header *header;
++      MUSB_DeviceRequest* pRequest;
 +
++    DBG(2, "<==\n");
 +
-+extern unsigned int MGC_nIndex;
++    spin_lock(&pEnd->Lock);
++    pUrb = MGC_GetCurrentUrb(pEnd);
 +
-+extern int MGC_DriverInit(void);
-+extern void MGC_DriverCleanup(void);
++      /* check URB */
++#ifdef MUSB_PARANOID
++    if( pUrb && (pUrb->hcpriv!=pEnd)) {
++        ERR("==> corrupt URB %p!!! from now on \"bad things will happen\"\n",
++                      pUrb);
++              spin_unlock(&pEnd->Lock);
++              return;
++    }
++#endif
 +
-+extern void MGC_HdrcStart(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcStop(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcServiceUsb(MGC_LinuxCd* pThis, uint8_t reg);
-+extern void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd, 
-+      uint16_t wCount, const uint8_t* pSource);
-+extern void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd, 
-+      uint16_t wCount, uint8_t* pDest);
++    SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++    MGC_SelectEnd(pBase, 0);
++    wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0);
++    wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
++    bVal = (uint8_t)wCsrVal;
 +
-+extern MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType, 
-+      int nIrq, void* pRegs, u64 len, const char* pName);
-+extern void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long), 
-+      unsigned long pParam, unsigned long millisecs);
++    DBG(2, "<== CSR0=%04x, wCount=%04x\n", wCsrVal, wCount);
 +
-+extern void MGC_LinuxCdFree(MGC_LinuxCd* pThis);
++    /* if we just did status stage, we are done */
++    if(MGC_END0_STATUS == pThis->bEnd0Stage) {
++              bComplete = TRUE;
++    }
 +
-+extern struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd);
++    /* prepare status */
++    if((MGC_END0_START == pThis->bEnd0Stage) && !wCount &&
++       (wCsrVal & MGC_M_CSR0_RXPKTRDY))
++    {
++              DBG(2, "missed data\n");
 +
-+extern int queue_length(struct list_head *lh);
++        /* just started and got Rx with no data, so probably missed data */
++        status = USB_ST_SHORT_PACKET;
++              bError = TRUE;
 +
-+/* Conditionally-compiled to update OTG state machine when necessary */
-+extern void MGC_OtgUpdate(MGC_LinuxCd* pThis, uint8_t bVbusError, 
-+      uint8_t bConnect);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++    }
 +
-+extern        void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis); 
-+extern MGC_LinuxCd *hcd_to_musbstruct(void *ptr);
-+extern struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis); 
++    if(bVal & MGC_M_CSR0_H_RXSTALL) {
++              DBG(2, "STALLING ENDPOINT 0\n");
++        status = USB_ST_STALL;
++              bError = TRUE;
++    } else if(bVal & MGC_M_CSR0_H_ERROR) {
++              DBG(3, "ep0 no response (error)\n");
++              DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); );
 +
-+/*-------------------------- available buses ---------------------*/
++        status = USB_ST_NORESPONSE;
++              bError = TRUE;
++    } else if(bVal & MGC_M_CSR0_H_NAKTIMEOUT) {
++              DBG(2, "ep0 NAK timeout pEnd->bRetries=%d\n", pEnd->bRetries);
 +
-+extern int direct_bus_init(void);
-+extern void direct_bus_shutdown(void);
++        if( ++pEnd->bRetries < MUSB_MAX_RETRIES) {
++                      /* cover it up if retries not exhausted */
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
++              } else {
++                      DBG(3, "no response (NAK timeout)\n");
++                      DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); );
++                      pEnd->bRetries=0;
++                      status = USB_ST_NORESPONSE;
++                      bError = TRUE;
++              }
++    }
 +
-+/*-------------------------- ProcFS definitions ---------------------*/
++    if(USB_ST_NORESPONSE == status) {
++              DBG(2, "ep0 aborting\n");
 +
-+struct MGC_TestProcData;
-+struct proc_dir_entry;
++              /* use the proper sequence to abort the transfer */
++              if(bVal & MGC_M_CSR0_H_REQPKT) {
++                      bVal &= ~MGC_M_CSR0_H_REQPKT;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++                      bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++              } else {
++                      bVal |= MGC_M_CSR0_FLUSHFIFO;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++                      bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
++              }
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+extern char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
-+extern char* decode_dev_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
-+#endif
++              MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, 0);
++    }
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+extern void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
-+      MGC_pfDisconnectListener pfListener, void* pParam);
-+extern void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
-+      MGC_pfDefaultEndHandler pfHandler, void* pParam);       
-+extern struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, 
-+      MGC_LinuxCd* data);
-+extern void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data);
-+#else
-+#define PROC_FS_DISABLED(_x) {  DBG(3, "#PROC_FS DISABLED"); _x }
++    if(bError) {
++              DBG(3, "ep0 handling error\n");
 +
-+static inline void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
-+      MGC_pfDisconnectListener pfListener, void* pParam) PROC_FS_DISABLED(;) 
-+static inline  void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
-+      MGC_pfDefaultEndHandler pfHandler, void* pParam) PROC_FS_DISABLED(;)    
-+static inline struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, 
-+      MGC_LinuxCd* data) PROC_FS_DISABLED(;)
-+static inline void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data)
-+      PROC_FS_DISABLED(;)
++        /* clear it */
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
++
++#ifdef MUSB_CONFIG_PROC_FS
++        switch(pThis->bEnd0Stage) {
++                      case MGC_END0_START:
++                      case MGC_END0_OUT:
++                              pEnd->dwErrorTxPackets++;
++                              break;
++                      case MGC_END0_IN:
++                              pEnd->dwErrorRxPackets++;
++                              break;
++              }
 +#endif
 +
-+/*-------------------------- TestProcFS definitions ---------------------*/
++    }
 +
-+#ifdef MUSB_PROC_TESTMUSB
-+extern struct proc_dir_entry* MGC_LinuxCreateTestProcFs(char *name, MGC_LinuxCd* data);
-+extern void MGC_LinuxDeleteTestProcFs(char *name, MGC_LinuxCd* data);
-+#endif
++    if(!pUrb) {
++              /* stop endpoint since we have no place for its data, this
++               * SHOULD NEVER HAPPEN! */
++              DBG(1, "no URB for end 0\n");
 +
-+/*------------------------------ IOCTLS/PROCFS -----------------------*/
++        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
 +
-+extern void MGC_Zap(MGC_LinuxCd* pThis); /* zap the driver */
-+extern void MGC_Session(MGC_LinuxCd* pThis); /* start a session */
-+extern void MGC_SetDebugLevel(int level); /* set the debug level */
-+extern int dump_header_stats(MGC_LinuxCd* pThis, char *buffer); /* compile options etc */
-+#ifdef MUSB_HOST
-+int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
-+#endif
++              /* start next URB that might be queued for it */
++              spin_unlock(&pEnd->Lock);
++              DBG(2, "==>\n");
++              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++              return;
++    }
 +
++    if(!bComplete && !bError) {
 +
++        /* call common logic and prepare response */
++        if( mgc_hdrc_service_host_default(pThis, wCount, pUrb) ) {
++                      /* more packets required */
++                      bOutVal = (MGC_END0_IN == pThis->bEnd0Stage) ?
++                      MGC_M_CSR0_H_REQPKT : MGC_M_CSR0_TXPKTRDY;
++                 DBG(3, "Need more bytes bOutVal=%04x\n", bOutVal);
++              } else {
++                      /* data transfer complete; perform status phase */
++                      bOutVal = MGC_M_CSR0_H_STATUSPKT |
++                        (usb_pipeout(pUrb->pipe) ? MGC_M_CSR0_H_REQPKT :
++                         MGC_M_CSR0_TXPKTRDY);
 +
-+/*-------------------------- DEBUG Definitions ---------------------*/
++                      /* flag status stage */
++                      pThis->bEnd0Stage = MGC_END0_STATUS;
++                      DBG(3, "Data transfer complete, status phase bOutVal=%04x\n", \
++                              bOutVal);
++              }
++    }
 +
++    /* write CSR0 if needed */
++    if(bOutVal) {
++        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bOutVal);
++    }
 +
-+#ifdef MUSB_PARANOID
-+#define MGC_HDRC_DUMPREGS(_t, _s) MGC_HdrcDumpRegs((_t)->pRegs, MUSB_IS_HST(_t) && _t->bIsMultipoint, _s)
-+#define MGC_ISCORRUPT(_x)     mgc_is_corrupt((_x), __FUNCTION__,__LINE__)
++    /* call completion handler if done */
++    if(bComplete || bError) {
++      DBG(3, "completing cntrl URB %p, status=%d, len=%x\n", \
++                      pUrb, status, pUrb->actual_length);
 +
-+/**
-+ * Test whether the struct is corrupted.
-+ * @param pThis
-+ */
-+static inline uint8_t mgc_is_corrupt(MGC_LinuxCd* pThis, const char *function, int line) {
-+#ifdef MUSB_HOST      
-+      uint8_t bEnd;
-+      MGC_LinuxLocalEnd* pEnd;
-+#endif
-+      
-+      if(MGC_PAD_FRONT != pThis->dwPadFront) {
-+              printk(KERN_INFO"musb %s:%d: pThis front pad corrupted (%x)\n", 
-+                      function, line, pThis->dwPadFront);
-+              return TRUE;
-+      }
-+      
-+      if(MGC_PAD_BACK != pThis->dwPadBack) {
-+              printk(KERN_INFO"musb %s:%d: pThis back pad corrupted (%x)\n", 
-+                      function, line, pThis->dwPadBack);
-+              return TRUE;
-+      }
++              /* Hub Class not supported */
++              if((pUrb->dev == pThis->pRootDevice))
++              {
++                      pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;
 +
-+#ifdef MUSB_HOST      
-+      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+              pEnd = &(pThis->aLocalEnd[bEnd]);
-+              
-+              if(MGC_PAD_FRONT != pEnd->dwPadFront) {
-+                      printk(KERN_INFO"musb %s:%d: end %d front pad corrupted (%x)\n", 
-+                              function, line, bEnd, pEnd->dwPadFront);
-+                      return TRUE;
++                      if((USB_REQ_GET_DESCRIPTOR == pRequest->bRequest) &&
++                              (USB_DIR_IN == pRequest->bmRequestType) &&
++                              (USB_DT_DEVICE == pUrb->setup_packet[3]) &&
++                              (pUrb->setup_packet[6] >= USB_DT_DEVICE_SIZE))
++                      {
++
++                              header = (struct usb_descriptor_header*)pUrb->transfer_buffer;
++                              if((header->bDescriptorType == USB_DT_DEVICE) &&
++                                      (*((char*)pUrb->transfer_buffer + 4) == USB_CLASS_HUB))
++                              {
++                                      printk("Hub Class NOT support \n");
++                                      /* Will pass error to upper stack */
++                                      status = -ENODEV;
++                              }
++                      }
 +              }
-+        
-+              if(MGC_PAD_BACK != pEnd->dwPadBack) {
-+                      printk(KERN_INFO"musb %s:%d: end %d back pad corrupted (%x)\n", 
-+                              function, line, bEnd, pEnd->dwPadBack);
-+                      return TRUE;
++              if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
++                      spin_unlock(&pEnd->Lock);
++                      pUrb->status = status;
++                      if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 )  {
++                              mgc_linux_start_next_urb(pThis, 0);
++                      }
++              } else {
++                      ERR("*** pUrb=%p is not queued to bEnd=%d\n", pUrb,
++                              pEnd->bEnd);
 +              }
++    } else {
++              spin_unlock(&pEnd->Lock);
 +      }
-+#endif
 +
-+#ifdef MUSB_GADGET    
-+      /* do something about it */
-+#endif
-+
-+      return FALSE;
++      DBG(2, "==>\n");
++      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
 +}
 +
-+#else
-+#define MGG_IsCorrupt(_x)     (_x)
-+#define MGC_HDRC_DUMPREGS(_t, _s) 
-+#endif
++/**************************************************************************
++ * EP1-n Tx and Rx data
++ **************************************************************************/
 +
-+/* -------------------------- Host Definitions ------------------------ */
++static void complete_ep_urb(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd,
++      struct urb* pUrb, int toggle)
++{
 +
-+#ifdef MUSB_HOST
-+extern void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis);
-+#endif
++      if (pUrb->status==USB_ST_STALL) {
++              toggle=0;
++      }
 +
-+/* -------------------------- Gadget Definitions --------------------- */
++      /* save data toggle */
 +
-+struct usb_ep;
++      usb_settoggle(pUrb->dev, pEnd->bEnd, (pEnd->bIsTx)?1:0, toggle);
++      /* we re-use bulk, so re-programming required */
++      pEnd->bIsReady = FALSE;
 +
-+extern const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE];
++      if (pUrb->status) {
++              DBG(1, "completing Tx URB=%p, status=%d, len=%x\n", \
++                      pUrb, pUrb->status, pUrb->actual_length);
++      }
 +
-+#if defined(MUSB_GADGET) || defined(MUSB_V26)
-+void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma);
-+void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma);
-+#endif
++      if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
++              spin_unlock(&pEnd->Lock);
++              if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 )  {
++                      mgc_linux_start_next_urb(pThis, pEnd->bEnd);
++              }
++      } else {
++              ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb,
++                      pEnd->bEnd);
++      }
++}
 +
-+#ifdef MUSB_GADGET
-+extern void* MGC_MallocEp0Buffer(const MGC_LinuxCd* pThis);
-+#endif
++/**
++ * Service a Tx-Available interrupt for the given endpoint.
 +
-+/* Gadget functions */
-+#ifdef MUSB_GADGET
-+struct usb_gadget;
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
++ */
++void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++      int skip=0;
++    struct urb* pUrb;
++    unsigned long flags;
++    uint16_t wTxCsrVal, wVal=0;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    uint32_t dev_status = 0;
 +
-+extern MGC_LinuxCd* MGC_GetDriverByName(const char *name);
-+extern int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd);
-+extern void mgc_init_gadget_endpoints(MGC_LinuxCd *pThis, struct usb_gadget *gadget); 
-+extern void MGC_GadgetReset(MGC_LinuxCd* pThis);
-+extern void MGC_GadgetResume(MGC_LinuxCd* pThis);
-+extern void MGC_GadgetSuspend(MGC_LinuxCd* pThis);
-+extern void MGC_GadgetDisconnect(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis);
-+extern void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
-+extern void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
++    DBG(1, "<==\n");
 +
-+extern void dump_ep_status(MGC_LinuxCd* pThis);
-+extern void dump_ep_queue(int index, int verbose);
++    spin_lock(&pEnd->Lock);
++    pUrb = MGC_GetCurrentUrb(pEnd);
++      if ( !pUrb ) {
++              MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE;
++              spin_unlock(&pEnd->Lock);
++              DBG(2, "==> tx ep empty\n");
++              return;
++      }
 +
-+/*
-+ * Gadget disabled
-+ */
-+#else
-+#define GADGET_DISABLED(_x) {  DBG(0, "#GADGET DISABLED"); _x }
++      if ( !pUrb->hcpriv ) {
++              DBG(2, "==> kickstarting it\n");
++              mgc_linux_kickstart_urb(pThis, bEnd);
++              spin_unlock(&pEnd->Lock);
++              return;
++      }
 +
-+static inline MGC_LinuxCd* MGC_GetDriverByName(const char *name) 
-+      GADGET_DISABLED( return NULL; )
-+static inline int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd)        
-+      GADGET_DISABLED( return -1; )
-+static inline void MGC_InitGadgetEndPoints(MGC_LinuxCd *pThis) 
-+      GADGET_DISABLED(;)
-+static inline void MGC_GadgetReset(MGC_LinuxCd* pThis) 
-+      GADGET_DISABLED(;)
-+static inline void MGC_GadgetResume(MGC_LinuxCd* pThis) 
-+      GADGET_DISABLED(;)
-+static inline void MGC_GadgetSuspend(MGC_LinuxCd* pThis) 
-+      GADGET_DISABLED(;)
-+static inline void MGC_GadgetDisconnect(MGC_LinuxCd* pThis) 
-+      GADGET_DISABLED(;)
-+static inline void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis)
-+      GADGET_DISABLED(;)
-+static inline void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) 
-+      GADGET_DISABLED(;)
-+static inline void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
-+      GADGET_DISABLED(;)
++      if ( !MUSB_IS_HST(pThis) ) {
++              complete_ep_urb(pThis, pEnd, pUrb, 0);
++              return;
++      }
 +
-+static inline void dump_ep_status(MGC_LinuxCd* pThis)
-+      GADGET_DISABLED(;)
-+static inline void dump_ep_queue(int index, int verbose)
-+      GADGET_DISABLED(;)
++
++    SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++    MGC_SelectEnd(pBase, bEnd);
++
++    wVal = wTxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
++
++#if MUSB_DEBUG > 0
++    /* check URB */
++    if(       pUrb && (pUrb->hcpriv != pEnd) ) {
++              ERR("==> end %d has corrupt URB %lx!\n", bEnd, (unsigned long)pUrb);
++              spin_unlock(&pEnd->Lock);
++              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++              return;
++    }
 +#endif
 +
++    DBG(3, "end %d wTxCsrVal=%04x\n", bEnd, wTxCsrVal);
 +
-+#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h
---- linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_epdescriptors.h       2008-09-17 13:23:33.000000000 +0530
-@@ -0,0 +1,48 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_epdescriptors.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 
-+ */
++      do {
++              uint32_t status = 0;
 +
-+struct MUSB_EpFifoDescriptor MUSB_aEpFifoDescriptors[MUSB_C_NUM_EPS] = {
++              /* check for errors */
++              if(wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) {
++                      pEnd->bStalled=TRUE;
++                      DBG(1, "TX end %d stall\n", bEnd);
++                      status = USB_ST_STALL;
++                      MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
++              } else if(wTxCsrVal & MGC_M_TXCSR_H_ERROR) {
++                      WARN("TX data error on ep=%d\n", bEnd);
++                      status = USB_ST_NORESPONSE;
++                      dev_status = status;
++                      /* do the proper sequence to abort the transfer */
++                      wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
++                      wVal |= MGC_M_TXCSR_FLUSHFIFO;
 +
-+{}, /* EP0 use the default */
-+{ MUSB_EPD_T_BULK, MUSB_EPD_D_TX, 512 },
-+{ MUSB_EPD_T_BULK, MUSB_EPD_D_RX, 512 },
-+{ MUSB_EPD_T_INTR, MUSB_EPD_D_RX, 512 }
-+};
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
 +
-+/** 
-+struct MGC_EpFifoDescriptor {
-+    uint8_t bType;    0 for autoconfig, CNTR, ISOC, BULK, INTR 
-+    uint8_t bDir;     0 for autoconfig, INOUT, IN, OUT 
-+    uint16_t wSize;           0 for autoconfig, or the size
-+      uint 8_t bDbe;  double buffering  0 disabled, 1 enabled 
-+};
++#ifdef MUSB_CONFIG_PROC_FS
++                      pEnd->dwErrorTxPackets++;
++#endif
++              }
++              else if( wTxCsrVal & MGC_M_TXCSR_H_NAKTIMEOUT ) {
++                      /* cover it up if retries not exhausted */
++                      if( pUrb->status==-EINPROGRESS && ++pEnd->bRetries < MUSB_MAX_RETRIES )
++                      {
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                                      MGC_M_TXCSR_TXPKTRDY);
 +
-+#define MUSB_EPD_AUTOCONFIG   0
++                              MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
++                              DBG(2, "tx error on ep%d, mgc_slow_device_kludge_delay=%d\n",
++                                      bEnd, mgc_slow_device_kludge_delay);
++                              spin_unlock(&pEnd->Lock);
++                              DBG(2, "==> cover tx error\n");
++                              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++                              return;
++                      }
 +
-+#define MUSB_EPD_T_CNTRL      1
-+#define MUSB_EPD_T_ISOC               2
-+#define MUSB_EPD_T_BULK               3
-+#define MUSB_EPD_T_INTR               4
++                      if ( pUrb->status==-EINPROGRESS ) {
++                              status = -ECONNRESET;
++                      }
 +
-+#define MUSB_EPD_D_INOUT      0
-+#define MUSB_EPD_D_TX         1
-+#define MUSB_EPD_D_RX         2
-+*/
++                      WARN("device not responding on ep=%d\n", bEnd);
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c
---- linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_epfifocfg.c   2008-07-28 15:20:55.000000000 +0530
-@@ -0,0 +1,429 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_epfifocfg.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 "musbdefs.h"
-+#include "musb_epdescriptors.h"
++                      /* do the proper sequence to abort the transfer */
++                      wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
++                      wVal |= MGC_M_TXCSR_FLUSHFIFO;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, 0);
 +
-+#ifdef MUSB_EPFIFOCONFIG_FILE
-+#include CONFIG_USB_INVENTRA_MUSB_EPFIFOCONFIG_FILE
++#ifdef MUSB_CONFIG_PROC_FS
++                      pEnd->dwErrorTxPackets++;
 +#endif
++                      pEnd->bRetries=0;
++              } else if( wTxCsrVal & MGC_M_TXCSR_FIFONOTEMPTY ) {
++                      /* whopps, dbould buffering better be enabled */
++#ifdef MUSB_PARANOID
++      /* guess what?? */
++#endif
++                      skip=TRUE;
++                      break;
++              }
 +
-+#define DYN_FIFO_SIZE (1<<(MUSB_C_RAM_BITS+2))
-+#define CONFIGURE_FIFO(_pThis, _pEnd, _Dsc, _wFifoOffset) \
-+      configure_fifo(_pThis, _pEnd, (_Dsc)->bDir, (_Dsc)->wSize, (_Dsc)->bDbe, _wFifoOffset) 
-+                              
-+                              
-+/* force array based */ 
-+#ifdef MUSB_C_DYNFIFO_DEF
-+
-+#ifdef MUSB_EPDISCRIPTORS_FILE
-+/**
-+ * configure the fifo and make sure the pThis endmask is updated.
-+ *
-+ * @param pThis
-+ * @param pEnd the end to configure 
-+ * @param bDir the direction (in, out, inout)
-+ * @param wSize the fifo size, real fifo size 
-+ * @param bDbe double buffering enabled? 
-+ * @param wFifoOffset the current offset 
-+ */
-+static uint16_t configure_fifo(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd, 
-+      uint8_t bDir, uint16_t wSize, uint8_t bDbe, uint16_t wFifoOffset) 
-+{
-+      uint16_t offset=wSize;
-+    void* pBase = pThis->pRegs;
-+      uint8_t szValue=wSize>>3;
-+      uint16_t addValue=wFifoOffset>>3;
-+      
-+      /* when double buffering is enabled endpoint needs twice the size */
-+      if (bDbe) {
-+              szValue |= (1<<4);
-+              offset*=2;
-+      }
-+      
-+      /* configure the FIFO */
-+      MGC_SelectEnd(pBase, pEnd->bEnd);       
-+      switch ( bDir ) {
-+              case MUSB_EPD_D_TX:
-+                      MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 0x6);
-+                      MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 64 >> 3);
++              if ( status ) {
 +
-+                      pEnd->wMaxPacketSizeTx = wSize;
-+                      pEnd->wMaxPacketSizeRx = 0;
-+                      pEnd->bIsSharedFifo = FALSE;
-+              break;
-+              case MUSB_EPD_D_RX:
-+                      MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 0x6);
-+                      MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, (64 + 512 ) >> 3);
++                      pUrb->status=status; /* */
 +
-+                      pEnd->wMaxPacketSizeTx = 0;
-+                      pEnd->wMaxPacketSizeRx = wSize;
-+                      pEnd->bIsSharedFifo = FALSE;
-+              break;
-+              case MUSB_EPD_D_INOUT:
-+                      MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, szValue);
-+                      MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, addValue);
++                      if ( USB_ST_STALL!=status ) {
++                              DBG(1, "Tx error on bEnd=%d, pUrb=%p, status=%d, proto=%s\n",
++                                      bEnd, pUrb, status, decode_urb_protocol(pUrb));
++                              DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++                      }
 +
-+                      MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, szValue);
-+                      MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, addValue);
++                      /* reset error bits */
++                      wVal &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
++                              MGC_M_TXCSR_H_NAKTIMEOUT);
++                      wVal |= MGC_M_TXCSR_FRCDATATOG;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
++              }
 +
-+                      pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=wSize;
-+                      pEnd->bIsSharedFifo = TRUE;
-+              break;
++      } while (0);
 +
-+              default:
-+                      ERR("direction %d not supported\n", bDir);
-+                      offset=0;
-+              break;
-+      }       
 +
-+      /* make sure the endmask is right */
-+      if ( offset ) {
-+              pThis->wEndMask |= (1 << pEnd->bEnd);
++      if ( !skip && pUrb->status==-EINPROGRESS ) {
++              mgc_linux_packet_tx(pThis, bEnd);
 +      }
 +
-+      /* TODO: flush the FIFO after an ep size change */
-+      
++    /* complete the current request or start next tx transaction */
++    if ( pUrb->status!=-EINPROGRESS ) {
++              int toggle=(pUrb->status==USB_ST_STALL)
++                      ? 0
++                      : ((wVal & MGC_M_TXCSR_H_DATATOGGLE) ? 1 : 0);
++              pUrb->actual_length = pEnd->dwOffset;
++              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++              complete_ep_urb(pThis, pEnd, pUrb, toggle);
++    } else {
++              spin_unlock(&pEnd->Lock);
++              if ( !skip ) {
 +
-+      return offset;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
++                              MGC_M_TXCSR_TXPKTRDY);
++              }
++              DBG(1, "==>\n");
++              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++    }
 +}
 +
 +/**
-+ * Configure the end points for DYNAMIC FIFO: array based End point 
-+ * configuration.
-+ * @param pThis the controller
++ * Service an Rx-Ready interrupt for the given endpoint; see section 18.2.1
++ * of the manual for details.
++ * @param pThis instance pointer
++ * @param bEnd local endpoint
 + */
-+void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
-+    uint8_t bEnd, bSkip;
-+    MGC_LinuxLocalEnd* pEnd;
-+    uint16_t wFifoOffset=0;
++void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
++{
++    struct urb* pUrb;
++    unsigned long flags;
++    uint16_t wRxCount, wRxCsrVal, wVal=0;
++    uint8_t bIsochError = FALSE;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
 +
-+      /* use the defined end points */
-+      pThis->bEndCount=MUSB_C_NUM_EPS;
++      DBG(2, "<== end%d\n", bEnd);
++    spin_lock(&pEnd->Lock);
++      DBG(3, "locked end%d, pUrb=%p\n", bEnd, MGC_GetCurrentUrb(pEnd));
 +
-+#ifdef MUSB_PARANOID
-+      if ( MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_T_CNTRL 
-+              && MUSB_aEpFifoDescriptors[0].bType!=MUSB_EPD_AUTOCONFIG) 
-+      {
-+              WARN("ep0 must be control with fixed size of %d\n", 
-+                      MGC_END0_FIFOSIZE);
++    pUrb = MGC_GetCurrentUrb(pEnd);
++      if ( !pUrb ) {
++              /* THIS SHOULD NEVER HAPPEN */
++              /* stop endpoint since we have no place for its data */
++              MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE;
++              spin_unlock(&pEnd->Lock);
++              DBG(1, "==> no RX URB on end %d!\n", bEnd);
++              return;
 +      }
-+#endif
-+      
-+      /* entry 0 is ep0, the default control endpoint */
-+      for (bEnd=0; bEnd<MUSB_C_NUM_EPS; bEnd++) {
-+              bSkip=0;                
-+              pEnd = &(pThis->aLocalEnd[bEnd]);
-+              pEnd->bEnd=bEnd;
-+              pEnd->bIsSharedFifo = FALSE;
-+              pEnd->wMaxPacketSizeTx=pEnd->wMaxPacketSizeRx=0;
-+              
-+              switch ( MUSB_aEpFifoDescriptors[bEnd].bType ) {                        
-+                      case MUSB_EPD_T_CNTRL:
-+                              if ( bEnd ) {
-+                                      bSkip=1;
-+                                      WARN("Control ep when ep!=0 (ep%d); skipping\n", bEnd);                         
-+                              }
-+                      break;
-+                      
-+                      case MUSB_EPD_T_ISOC: break;
-+                      
-+                      case MUSB_EPD_T_BULK:                           
-+                              switch ( MUSB_aEpFifoDescriptors[bEnd].bDir ) {
-+                                      case MUSB_EPD_D_TX: pThis->bBulkTxEnd = bEnd; break;
-+                                      case MUSB_EPD_D_RX: pThis->bBulkRxEnd = bEnd; break;
-+                                      case MUSB_EPD_D_INOUT:
-+                                              WARN("INOUTBULK: sharing ep%d\n", bEnd);                                
-+                                      break;
-+                                      default:
-+                                              bSkip=1;
-+                                              ERR("direction %d not supported for ep%d\n", 
-+                                                      MUSB_aEpFifoDescriptors[bEnd].bDir, bEnd);
-+                                      break;
-+                              } 
-+                      break;
-+                      
-+                      case MUSB_EPD_T_INTR: break;
-+                      case MUSB_EPD_AUTOCONFIG: break;
-+                      
-+                      default:
-+                              bSkip=1;                        
-+                              ERR("ep%d type %d not supported\n", bEnd, 
-+                                      MUSB_aEpFifoDescriptors[bEnd].bType);
-+                      break;
-+              }               
-+                              
-+              if ( !MUSB_aEpFifoDescriptors[bEnd].wSize ) {
-+                      continue; /* postpone to autoconfig */ 
-+              }
 +
-+              if ( !bSkip ) {
-+                      uint16_t offset=CONFIGURE_FIFO(pThis, &(pThis->aLocalEnd[bEnd]), 
-+                              &MUSB_aEpFifoDescriptors[bEnd], wFifoOffset );
-+                      if ( offset ) {
-+                              wFifoOffset += offset;
-+                      }
-+              }
-+              
++      if ( !pUrb->hcpriv ) {
++              DBG(1, "==> kickstarting it\n");
++              mgc_linux_kickstart_urb(pThis, bEnd);
++              spin_unlock(&pEnd->Lock);
++              return;
 +      }
 +
 +#ifdef MUSB_PARANOID
-+      if ( wFifoOffset > 64 ) {
-+              ERR("Allocated %d bytes, more than the allowed %d\n",
-+                      wFifoOffset, 64);
-+      } else {
-+              INFO("Allocated %d bytes, out of %d\n", wFifoOffset, 
-+                      64);
-+      }
++    /* check URB */
++    if ( pUrb->hcpriv!=pEnd ) {
++        ERR("==> pUrb=%p on bEnd=%d (hcpriv=%p) is corrupt!\n", pUrb, bEnd, pUrb->hcpriv);
++              /* about the urb? */
++              spin_unlock(&pEnd->Lock);
++              return;
++    }
 +#endif
 +
-+}
-+
-+#else
-+/**
-+ * Configure the end points for DYNAMIC FIFO (old method).
-+ * @param pThis the controller
-+ */
-+void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
-+    uint8_t bEnd=1;
-+    MGC_LinuxLocalEnd* pEnd;
-+    void* pBase = pThis->pRegs;
-+    uint16_t wFifoOffset=MGC_END0_FIFOSIZE;
-+
-+    DBG(2, "<==\n");
++      if ( !MUSB_IS_HST(pThis) ) {
++              complete_ep_urb(pThis, pEnd, pUrb, 0);
++              return;
++      }
 +
-+      /* use the defined end points */
-+      pThis->bEndCount=MUSB_C_NUM_EPS;
-+      
-+    /* Dynamic FIFO sizing: use pre-computed values for EP0 */
-+    MGC_SelectEnd(pBase, 0);
-+    MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, 3);
-+    MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, 3);
-+    MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, 0);
-+    MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, 0);
-+      pThis->wEndMask = 1;
-+       
-+#if MGC_DFIFO_ISO_TX >= 0
++      SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
 +    MGC_SelectEnd(pBase, bEnd);
-+    pEnd = &(pThis->aLocalEnd[bEnd]);
-+      pEnd->bEnd=bEnd;
++    wVal = wRxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
++      wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
 +
-+    /* reserve ISO Tx */
-+    MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ISO_TX_VAL);
-+    pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_ISO_TX_VAL & 0xf)+3+(MGC_DFIFO_ISO_TX_VAL>>4));
-+    pEnd->wMaxPacketSizeRx = 0;
-+    MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
-+    /* move to next */
-+    wFifoOffset += pEnd->wMaxPacketSizeTx;
-+    pEnd->bIsSharedFifo = FALSE;
-+      pThis->wEndMask |= (1 << bEnd);
-+    bEnd++;   
-+#endif
++      DBG(3, "end %d wRxCsrVal=%04x, wRxCount=%d, pUrb->actual_length=%d\n", bEnd,
++              wRxCsrVal, wRxCount, pUrb->actual_length);
 +
-+#if MGC_DFIFO_ISO_RX >= 0
-+    MGC_SelectEnd(pBase, bEnd);
-+    pEnd = &(pThis->aLocalEnd[bEnd]);
-+      pEnd->bEnd=bEnd;
++      do {
++              uint32_t status = 0;
 +
-+    /* reserve ISO Rx */
-+    MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ISO_RX_VAL);
-+    pEnd->wMaxPacketSizeTx = 0;
-+    pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_ISO_RX_VAL & 0xf)+3+(MGC_DFIFO_ISO_RX_VAL>>4));
-+    MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
++              /* check for errors, concurrent stall & unlink is not really
++               * handled yet! */
++              if ( wRxCsrVal & MGC_M_RXCSR_H_RXSTALL ) {
++                      pEnd->bStalled=TRUE;
++                      DBG(1, "RX end %d STALL\n", bEnd);
++                      status = USB_ST_STALL;
++              } else if(wRxCsrVal & MGC_M_RXCSR_H_ERROR) {
++                      DBG(1, "end %d Rx error\n", bEnd);
++                      DEBUG_CODE(1, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++                      status=-ECONNRESET;
 +
-+    /* move to next */
-+    wFifoOffset += pEnd->wMaxPacketSizeRx;
-+    pEnd->bIsSharedFifo = FALSE;
-+      pThis->wEndMask |= (1 << bEnd);
-+    bEnd++;
++                      /* do the proper sequence to abort the transfer */
++                      wVal &= ~MGC_M_RXCSR_H_REQPKT;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0);
++
++#ifdef MUSB_CONFIG_PROC_FS
++                      pEnd->dwErrorRxPackets++;
 +#endif
++              } else if(wRxCsrVal & MGC_M_RXCSR_DATAERROR) {
 +
-+    MGC_SelectEnd(pBase, bEnd);
-+    pEnd = &(pThis->aLocalEnd[bEnd]);
-+      pEnd->bEnd=bEnd;
++                      if (PIPE_BULK == pEnd->bTrafficType) {
++                              /* cover it up if retries not exhausted, slow devices might
++                               * not answer quickly enough: I was expecting a packet but the
++                               * packet didn't come. The interrupt is generated after 3 failed
++                               * attempts, it make MUSB_MAX_RETRIESx3 attempts total..
++                               */
++                              if ( pUrb->status==-EINPROGRESS &&
++                                      ++pEnd->bRetries < MUSB_MAX_RETRIES)
++                              {
++                                      /* silently ignore it */
++                                      wRxCsrVal &= ~ MGC_M_RXCSR_DATAERROR;
++                                      wRxCsrVal &= ~MGC_M_RXCSR_RXPKTRDY;
++                                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
++                                                 wRxCsrVal | MGC_M_RXCSR_H_REQPKT);
 +
-+      /* reserve bulk */
-+      pEnd->wMaxPacketSizeRx= 0;
-+    pEnd->wMaxPacketSizeTx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
-+    MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_BLK_VAL);
-+    MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
-+    pThis->bBulkTxEnd = bEnd;
-+    /* move to next */
-+    wFifoOffset += pEnd->wMaxPacketSizeTx;
-+      pThis->wEndMask |= (1 << bEnd);
-+    bEnd++;
++                                      MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
++                                      DBG(1, "rx error on ep%d, mgc_slow_device_kludge_delay=%d\n",
++                                              bEnd, mgc_slow_device_kludge_delay);
++                                      spin_unlock(&pEnd->Lock);
++                                      DBG(2, "==> cover rx error\n");
++                                      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++                                      return;
++                              }
 +
-+    MGC_SelectEnd(pBase, bEnd);
-+    pEnd = &(pThis->aLocalEnd[bEnd]);
-+      pEnd->bEnd=bEnd;
++                              if ( pUrb->status==-EINPROGRESS ) {
++                                      DBG(-1, "urb=%p, protocol=%s timed out\n", pUrb,
++                                              decode_urb_protocol(pUrb));
++                                      status=-ECONNRESET;
++                              }
 +
-+      pEnd->wMaxPacketSizeTx= 0;
-+    pEnd->wMaxPacketSizeRx = 1 << ((MGC_DFIFO_BLK_VAL & 0xf)+3+(MGC_DFIFO_BLK_VAL>>4));
-+    MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_BLK_VAL);
-+    MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
-+    pThis->bBulkRxEnd = bEnd;
-+    /* move to next */
-+    wFifoOffset += pEnd->wMaxPacketSizeRx;
-+      pThis->wEndMask |= (1 << bEnd);
-+    bEnd++;
++                              wVal &= ~MGC_M_RXCSR_H_REQPKT;
++                              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++                              MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0);
++                              pEnd->bRetries=0;
 +
-+    /* take care of the remaining eps */
-+    for(; bEnd < MUSB_C_NUM_EPS; bEnd++) {
-+              MGC_SelectEnd(pBase, bEnd);
-+              pEnd = &(pThis->aLocalEnd[bEnd]);
-+              pEnd->bEnd=bEnd;
-+              
-+              MGC_Write8(pBase, MGC_O_HDRC_TXFIFOSZ, MGC_DFIFO_ALL_VAL);
-+              MGC_Write8(pBase, MGC_O_HDRC_RXFIFOSZ, MGC_DFIFO_ALL_VAL);
-+              pEnd->wMaxPacketSizeTx = pEnd->wMaxPacketSizeRx = 1 << (MGC_DFIFO_ALL_VAL+3);
-+              pEnd->bIsSharedFifo = TRUE;
-+              MGC_Write16(pBase, MGC_O_HDRC_TXFIFOADD, wFifoOffset >> 3);
-+              MGC_Write16(pBase, MGC_O_HDRC_RXFIFOADD, wFifoOffset >> 3);
-+              
-+              wFifoOffset += pEnd->wMaxPacketSizeRx;
-+              pThis->wEndMask |= (1 << bEnd);
-+    }
++                              /* do the proper sequence to abort the transfer;
++                               * am I dealing with a slow device maybe? */
++                              DBG(3, "end=%d device not responding\n", bEnd);
 +
-+#ifdef MUSB_PARANOID
-+      if ( wFifoOffset > 64 ) {
-+              ERR("Allocated %d bytes, more than the allowed %d\n",
-+               wFifoOffset, 64);
-+      } else {
-+              INFO("Allocated %d bytes, out of %d\n",
-+                      wFifoOffset, 64);
-+      }
-+#endif
-+      
-+    DBG(2, "==>\n");
-+}
-+#endif
++                      } else if(PIPE_ISOCHRONOUS == pEnd->bTrafficType) {
++                              DBG(3, "bEnd=%d Isochronous error\n", bEnd);
++                              bIsochError = TRUE;
++                      }
 +
-+#else
-+/**
-+ * Detect and configure the end points (no dynamic fifos).
-+ * @param pThis the controller
-+ */
-+void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis) {
-+    uint8_t bEnd=0, reg;
-+    MGC_LinuxLocalEnd* pEnd;
-+    void* pBase = pThis->pRegs;
-+    /* how many of a given size/direction found: */
-+    uint8_t b2kTxEndCount = 0;
-+    uint8_t b2kRxEndCount = 0;
-+    uint8_t b1kTxEndCount = 0;
-+    uint8_t b1kRxEndCount = 0;
-+    /* the smallest 2k or 1k ends in Tx or Rx direction: */
-+    uint8_t b2kTxEnd = 0;
-+    uint8_t b2kRxEnd = 0;
-+    uint8_t b1kTxEnd = 0;
-+    uint8_t b1kRxEnd = 0;
-+    /* for tracking smallest: */
-+    uint16_t w2kTxSize = 0;
-+    uint16_t w1kTxSize = 0;
-+    uint16_t w2kRxSize = 0;
-+    uint16_t w1kRxSize = 0;
++#ifdef MUSB_CONFIG_PROC_FS
++                      pEnd->dwErrorRxPackets++;
++#endif
++              }
 +
-+      DBG(2, ">==\n");
++              /* an error won't process the data */
++              if ( status ) {
++                      pUrb->status=status;
 +
-+      for(bEnd = 1; bEnd < MUSB_C_NUM_EPS; bEnd++) {
-+        MGC_SelectEnd(pBase, bEnd);
-+              pEnd = &(pThis->aLocalEnd[bEnd]);       
-+              pEnd->bEnd=bEnd;
++                      /* data errors are signaled */
++                      if ( USB_ST_STALL!=status ) {
++                              DBG(3, "end %d Rx error, status=%d\n", bEnd, status);
++                              DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++                      } else {
++                              mgc_hdrc_flush_fifo(pThis, bEnd, 1);
++                      }
 +
-+              /* read from core */
-+              reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_FIFOSIZE, bEnd);
-+              if(!reg) {
-+                /* 0's returned when no more endpoints */
-+                break;
++                      DBG(3, "clearing all error bits, right away\n");
++                      wVal &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_DATAERROR |
++                              MGC_M_RXCSR_H_RXSTALL );
++                      wVal &= ~MGC_M_RXCSR_RXPKTRDY;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
 +              }
-+      
-+              pEnd->wMaxPacketSizeTx = 1 << (reg & 0x0f);
-+              /* shared TX/RX FIFO? */
-+              if((reg & 0xf0) == 0xf0) {
-+                      pEnd->wMaxPacketSizeRx = 1 << (reg & 0x0f);
-+                      pEnd->bIsSharedFifo = TRUE;
++
++    } while (0);
++
++      /* no errors, unload... */
++      if ( pUrb->status==-EINPROGRESS ) {
++
++              /* be sure a packet is ready for unloading */
++              if( !wRxCsrVal & MGC_M_RXCSR_RXPKTRDY ) {
++                      pUrb->status = USB_ST_INTERNALERROR;
++                      /* do the proper sequence to abort the transfer */
++                      wVal &= ~MGC_M_RXCSR_H_REQPKT;
++                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++                      DBG(3, "Rx interrupt with no errors or packet!\n");
 +              } else {
-+                      pEnd->wMaxPacketSizeRx = 1 << ((reg & 0xf0) >> 4);
-+                      pEnd->bIsSharedFifo = FALSE;
-+              }
-+      
-+              /* track certain sizes to try to reserve a bulk resource */
-+              if(pEnd->wMaxPacketSizeTx >= 2048) {
-+                      b2kTxEndCount++;
-+                      if(!b2kTxEnd || (pEnd->wMaxPacketSizeTx < w2kTxSize)) {
-+                              b2kTxEnd = bEnd;
-+                              w2kTxSize = pEnd->wMaxPacketSizeTx;
-+                      }
-+              }
-+      
-+              if(pEnd->wMaxPacketSizeRx >= 2048) {
-+                      b2kRxEndCount++;
-+                      if(!b2kRxEnd || (pEnd->wMaxPacketSizeRx < w2kRxSize)) {
-+                              b2kRxEnd = bEnd;
-+                              w2kRxSize = pEnd->wMaxPacketSizeRx;
-+                      }
-+              }
-+      
-+              if(pEnd->wMaxPacketSizeTx >= 1024) {
-+                      b1kTxEndCount++;
-+                      if(!b1kTxEnd || (pEnd->wMaxPacketSizeTx < w1kTxSize)) {
-+                              b1kTxEnd = bEnd;
-+                              w1kTxSize = pEnd->wMaxPacketSizeTx;
++                      /* we are expecting traffic */
++#ifdef MUSB_DMA
++                      if(pEnd->pDmaChannel) {
++                              if(MGC_DMA_STATUS_FREE==
++                                      pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel))
++                              {
++                                      pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
++                              }
 +                      }
++#endif
++                      mgc_linux_packet_rx(pThis, bEnd, wRxCount, bIsochError);
 +              }
-+              
-+              if(pEnd->wMaxPacketSizeRx >= 1024) {
-+                      b1kRxEndCount++;
-+                      if(!b1kRxEnd || (pEnd->wMaxPacketSizeRx < w1kTxSize)) {
-+                              b1kRxEnd = bEnd;
-+                              w1kRxSize = pEnd->wMaxPacketSizeRx;
-+                      }
-+              }       
-+
-+              pThis->bEndCount++;
-+              pThis->wEndMask |= (1 << bEnd);
-+    } /* init queues etc. etc. etc. */
-+      
-+    /* if possible, reserve the smallest 2k-capable Tx end for bulk */
-+    if(b2kTxEnd && (b2kTxEndCount > 1)) {
-+              pThis->bBulkTxEnd = b2kTxEnd;
-+              INFO("Reserved end %d for bulk double-buffered Tx\n", b2kTxEnd);
-+    }
-+    /* ...or try 1k */
-+    else if(b1kTxEnd && (b1kTxEndCount > 1)) {
-+              pThis->bBulkTxEnd = b1kTxEnd;
-+              INFO("Reserved end %d for bulk Tx\n", b1kTxEnd);
 +    }
 +
-+    /* if possible, reserve the smallest 2k-capable Rx end for bulk */
-+    if(b2kRxEnd && (b2kRxEndCount > 1)) {
-+              pThis->bBulkRxEnd = b2kRxEnd;
-+              INFO("Reserved end %d for bulk double-buffered Rx\n", b2kRxEnd);
-+    }
-+    /* ...or try 1k */
-+    else if(b1kRxEnd && (b1kRxEndCount > 1)) {
-+              pThis->bBulkRxEnd = b1kRxEnd;
-+              INFO("Reserved end %d for bulk Rx\n", b1kRxEnd);
++      /* complete the current request or start next one clearing RxPktRdy
++       * and setting ReqPkt */
++    if ( pUrb->status!=-EINPROGRESS ) {
++              int toggle=(pUrb->status==USB_ST_STALL)
++                      ? 0
++                      : ((wVal & MGC_M_RXCSR_H_DATATOGGLE) ? 1 : 0);
++              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++              complete_ep_urb(pThis, pEnd, pUrb, toggle);
++              DBG(2, "==>\n");
++    } else {
++              spin_unlock(&pEnd->Lock);
++              wVal |= MGC_M_RXCSR_H_REQPKT;
++              wVal &= ~MGC_M_RXCSR_RXPKTRDY;
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
++              DBG(2, "==>\n");
++              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
 +    }
-+
-+    DBG(2, "<==\n");
 +}
-+#endif
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_hcd.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_hcd.c
---- linux-2.6.20/drivers/usb/nomadik/musb_hcd.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_hcd.c 2008-09-17 13:23:33.000000000 +0530
-@@ -0,0 +1,869 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_hcd.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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.
++ **************************************************************************/
++
++/**
++ * Find a local endpoint suitable for transmitting the given urb minimizing
++ * the reconfigurations. The best localendpoint is selceted using the following
++ * criterion:
++ * - ep0 is used for control Urbs
++ * - for bulk Urbs only (when available) choose the Tx or Rx reserved end
++ * - determine direction, size and traffic type
 + *
-+ * 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 
++ * @param pThis instance pointer
++ * @param pURB URB pointer
++ * @return suitable local endpoint
++ * @return -1 if nothing appropriate
 + */
++int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb)
++{
++    MGC_LinuxLocalEnd* pEnd;
++    int32_t dwDiff;
++    uint16_t wBestDiff = 0xffff;
++    uint16_t wBestExactDiff = 0xffff;
++    uint8_t bDirOk, bTrafficOk, bSizeOk, bExact;
++    int nEnd=-1, nBestEnd = -1, nBestExactEnd = -1;
++    unsigned int nOut = usb_pipeout( pUrb->pipe );
++    uint16_t wPacketSize = usb_maxpacket(pUrb->dev, pUrb->pipe, nOut);
++    uint8_t bRemoteEnd = usb_pipeendpoint(pUrb->pipe);
++    uint8_t bIsBulk = usb_pipebulk(pUrb->pipe);
++    uint8_t bRemoteAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
 +
-+#include <asm/arch/pexp.h>
-+static void mgc_hcd_stop(struct usb_hcd *hcd);
-+static int __devinit mgc_hcd_start(struct usb_hcd *hcd);
-+static int mgc_hcd_submit_urb(struct usb_hcd *hcd,struct usb_host_endpoint *ep,
-+      struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
-+static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb);
-+static int mgc_hcd_get_frame_number(struct usb_hcd *hcd);
-+static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd);
-+static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd, 
-+      struct usb_host_endpoint *ep);
-+static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
++    DBG(2, "<== pUrb=%p\n", pUrb);
 +
-+static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 
-+      u16 wIndex, char *pData, u16 wLength);
-+static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData); 
-+int Urb_status=0;
-+/* ------------------------------------------------------- */
-+static int    mgc_bus_resume(struct usb_hcd *phcd)
-+{
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
-+      char* pBase = (char*)pThis->pRegs;
++    /* control is always EP0, and can always be queued */
++    if ( usb_pipecontrol(pUrb->pipe) ) {
++      DBG(2, "==> is a control pipe use ep0\n");
++        return 0;
++    }
 +
-+      nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
-+      /* Reinitialize the interrupt*/
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, 0x20);
-+      MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0xFFFF);
-+      MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0xFFFE);
-+      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xF7);
-+      MGC_Write8(pBase, MGC_O_HDRC_INDEX ,0x00);
-+      
-+      /* Configure the endpoints*/
-+      MGC_HdrcConfigureEps(pThis);
-+      MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);
-+      mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
++    /* use a reserved one for bulk if any */
++    if (bIsBulk) {
++              if (nOut && pThis->bBulkTxEnd) {
++                      DBG(3, "==> use the bulk tx end (%d)\n",  pThis->bBulkTxEnd);
++                      return pThis->bBulkTxEnd;
++              } else if(!nOut && pThis->bBulkRxEnd) {
++                      DBG(3, "==> use the bulk rx end (%d)\n", pThis->bBulkRxEnd);
++                      return pThis->bBulkRxEnd;
++              }
++    }
 +
-+      printk("Got Bus Resume:\n");
-+      return 0;
-+}
-+static int    mgc_bus_suspend(struct usb_hcd *phcd)
-+{
-+      uint8_t  power;
-+      uint8_t  devctrl;
-+      uint8_t  topctrl;
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
-+      char* pBase = (char*)pThis->pRegs;
-+      
-+      /* Delete Timer*/
-+      del_timer(&notify_timer);
-+      MUSB_A_IDLE_MODE(pThis);
-+      
-+      /* 
-+       * Device mode? disconnect the device and then
-+       * proceed
-+       */
-+      if(MUSB_IS_DEV(pThis)){
-+              udc_disconnect_isr();
-+              power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+              MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_SOFTCONN);
-+              devctrl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+              MUSB_B_IDLE_MODE(pThis);
-+              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctrl & ~MGC_M_DEVCTL_SESSION);
-+              dev_safe_remove =0;
-+      }
-+      /* Reset the controller*/
-+      topctrl = MGC_Read8(pBase, MGC_O_HDRC_TOPCONTROL);
-+      MGC_Write8(pBase, MGC_O_HDRC_TOPCONTROL, (topctrl |MGC_M_TOPCTRL_MODE_SRST));
-+      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_ENSUSPEND);
++    /* scan, remembering exact match and best match */
++    for(nEnd = 1; nEnd < pThis->bEndCount; nEnd++) {
++        pEnd = &(pThis->aLocalEnd[nEnd]);
 +
-+      nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG,"OTG");
++              /* consider only if direction is possible  */
++              bDirOk = (nOut && pEnd->wMaxPacketSizeTx) ||
++                (!nOut && pEnd->wMaxPacketSizeRx);
++              /* consider only if size is possible (in the given direction) */
++              bSizeOk = (nOut && (pEnd->wMaxPacketSizeTx >= wPacketSize)) ||
++                (!nOut && (pEnd->wMaxPacketSizeRx >= wPacketSize));
++              /* consider only traffic type */
++              bTrafficOk = (usb_pipetype(pUrb->pipe) == pEnd->bTrafficType);
 +
-+      printk("Got Bus Suspend:\n");
-+      return 0;
-+}
-+#ifdef        CONFIG_USB_SUSPEND
-+static int    mgc_suspend (struct usb_hcd *phcd, pm_message_t message)
-+{
-+      uint8_t power;
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
-+      char* pBase = (char*)pThis->pRegs;
-+      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
-+      printk("Got Suspend\n");
-+      return 0;
-+}
-+static int    mgc_resume(struct usb_hcd *phcd)
-+{
-+      uint8_t power;
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(phcd);
-+      char* pBase = (char*)pThis->pRegs;
-+      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
-+      mdelay(15);
-+      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME);
-+      printk("Got Resume\n");
-+      return 0;
++              if (bDirOk && bSizeOk) {
++                      /* convenient computations */
++                      dwDiff = nOut ? (pEnd->wMaxPacketSizeTx - wPacketSize) :
++                        (pEnd->wMaxPacketSizeRx - wPacketSize);
++                      bExact = bTrafficOk && (pEnd->bRemoteEnd == bRemoteEnd) &&
++                      (pEnd->bRemoteAddress == bRemoteAddress);
++
++                      /* bulk: best size match not claimed (we only claim periodic) */
++                      if(bIsBulk && !pEnd->bIsClaimed && (wBestDiff > dwDiff)) {
++                              wBestDiff = (uint16_t)dwDiff;
++                              nBestEnd = nEnd;
++
++                              /* prefer end already in right direction (to avoid flush) */
++                              if((wBestExactDiff > dwDiff) && (nOut == (int)pEnd->bIsTx)) {
++                                      wBestExactDiff = (uint16_t)dwDiff;
++                                      nBestExactEnd = nEnd;
++                              }
++
++                      } else if(!bIsBulk && (nEnd != pThis->bBulkTxEnd) &&
++                              (nEnd != pThis->bBulkRxEnd))
++                      {
++                              /* periodic: exact match if present; otherwise best unclaimed */
++                              if (bExact) {
++                                      nBestExactEnd = nEnd;
++                                      break;
++                              } else if(!pEnd->bIsClaimed && (wBestDiff > dwDiff)) {
++                                      wBestDiff = (uint16_t)dwDiff;
++                                      nBestEnd = nEnd;
++                              }
++                      }
++              }
++
++    }
++
++    return (nBestExactEnd >= 0) ? nBestExactEnd : nBestEnd;
 +}
++
++static int mgc_check_bandwidth(struct urb* pUrb) {
++    unsigned int pipe = pUrb ? pUrb->pipe : 0;
++#ifdef MUSB_V24
++    struct urb* pNextUrb;
 +#endif
-+/* as platform_data */
-+struct plat_musb_hcd {
-+      unsigned long mapbase;
-+      unsigned irq;
-+      unsigned index;
-+      char name[32];
-+};
 +
-+const struct hc_driver musb_ahb_hc_driver = {
-+      .description =          MGC_HcdName,
-+      .product_desc =         "MUSB HCD",
++          /* some drivers try to confuse us by linking periodic URBs BOTH ways */
++    if(!pUrb->bandwidth && (usb_pipeisoc(pipe) || usb_pipeint(pipe))) {
++              int bustime = usb_check_bandwidth(pUrb->dev, pUrb);
++              if(bustime < 0) {
++                      return bustime;
++              }
 +
-+      /* this will allocate a MGC_LinuxCd at the end of it */ 
-+      .hcd_priv_size =        sizeof(MGC_LinuxCd), 
++              usb_claim_bandwidth(pUrb->dev, pUrb, bustime,
++                      usb_pipeisoc(pipe) ? 1 : 0);
 +
-+      /*
-+       * generic hardware linkage
-+       */
-+#ifdef MUSB_POLL
-+       .irq =                 NULL,
-+#else
-+       .irq =                 mgc_hcd_isr,
++#ifdef MUSB_V24
++              /* propagate through linked URBs */
++              pNextUrb = pUrb->next;
++              while(pNextUrb && (0 == pNextUrb->bandwidth)) {
++                      pNextUrb->bandwidth = bustime;
++                      pNextUrb = pNextUrb->next;
++              }
 +#endif
++    }
++
++      return 0;
++}
 +
-+      /* USB version 2 & memeory usage */
-+      .flags =                HCD_USB2 | HCD_MEMORY,
++/**
++ * Schedule an urb on an endpoint. Assumes the ep locked.
++ * @param pThis the conotroller
++ * @param pEnd the endpoint the urb shoudl be queued to
++ * @param pUrb the urb to queue
++ */
++int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd,
++      struct urb* pUrb)
++{
++    DBG(2, "<== pUrb=%p ep=%d\n", pUrb, pEnd->bEnd);
 +
-+      /*
-+       * basic lifecycle operations
-+       */
-+      .start =                mgc_hcd_start,
-+      .stop =                 mgc_hcd_stop,
++      /* increment urb's reference count, we now control it. */
++      pUrb = usb_get_urb(pUrb);
++      pUrb->hcpriv = NULL; /* paranoid */
 +
-+      /*
-+       * managing i/o requests and associated device resources
-+       */
-+      .urb_enqueue =          mgc_hcd_submit_urb,
-+      .urb_dequeue =          mgc_hcd_unlink_urb,
++      /* async unlink?? */
++      if( pUrb->status!=-EINPROGRESS ) {
 +
-+      .endpoint_disable =     mgc_hcd_disable_endpoint,
++              mgc_linux_complete_urb(pThis, pEnd, pUrb);
++              return 0;
++    }
 +
-+      /*
-+       * scheduling support
-+       */
-+      .get_frame_number =     mgc_hcd_get_frame_number,
++      DEBUG_CODE(3, if(pEnd->bEnd==0) { \
++              MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;\
++              INFO("ctl-request: bmRequestType=%02x, bRequest=%02x, wLength=%04x\n",\
++            pRequest->bmRequestType, pRequest->bRequest,\
++            le16_to_cpu(pRequest->wLength));\
++    } );
 +
-+      /*
-+       * root hub support
-+       */
-+      .hub_status_data =      mgc_root_hub_status,
-+      .hub_control =          mgc_root_hub_control,
-+      
-+      .bus_suspend =          mgc_bus_suspend,
-+      .bus_resume =           mgc_bus_resume,
-+#ifdef        CONFIG_USB_SUSPEND
-+      .suspend=                       mgc_suspend,
-+      .resume=                        mgc_resume,
-+#endif
++      {
++              const int bustime=mgc_check_bandwidth(pUrb);
++              if ( bustime<0 ) {
++                      ERR("==> not enough bustime for it\n");
++                      return bustime;
++              }
++      }
 +
-+      .start_port_reset =     NULL,
-+};
++      /* claim the urb for periodic transfers */
++      pEnd->bIsClaimed=mgc_urb_is_periodic(pUrb);
++      if ( pEnd->bIsClaimed ) {
++              DBG(3, "end %d claimed for proto %s\n", pEnd->bEnd,
++                      decode_urb_protocol(pUrb) );
++      }
 +
-+/* -------------------------------------------------------------------- */
++      { /* queue the urb and start it */
++              int idle=mgc_ep_is_idle(pEnd);
 +
++              if ( mgc_ep_enqueue_urb(pEnd, pUrb)!=0 ) {
++                      ERR("**>cannot queue pUrb=%p to pEnd=%p! this is bad (TM)\n", pUrb, pEnd);
++                      return -EBUSY;
++              }
 +
-+/*
-+ * Scan the urb returning the urb the precede a give urb. When in the musb_hcd
-+ * queue, urbs are linked to each other using the pUrb->hcdpriv field; the last
-+ * urb has pUrb->hcpriv=NULL
-+ * @param pThs the controller
-+ * @param pUrb the urbn to search for
-+ * @return NULL or pUrb1 such that (pUrb1->hcpriv==pUrb)
-+ *
-+ */
-+static struct urb* mgc_hcd_urb_find_prev(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) {
-+      struct urb* temp=pQueue->urb_queue_head;
++              DBG(3, "queued URB %p (current %p) to end %d (bRemoteAddress=%d, bRemoteEnd=%d proto=%d) (idle=%d) pEnd->bBusyCompleting=%d\n",
++                      pUrb, MGC_GetCurrentUrb(pEnd), pEnd->bEnd, (uint8_t)usb_pipedevice(pUrb->pipe),
++                      (uint8_t)usb_pipeendpoint(pUrb->pipe), usb_pipetype(pUrb->pipe), idle, pEnd->bBusyCompleting);
 +
-+      if ( temp==pUrb ) {
-+              return pQueue->urb_queue_head; /* to make clear */      
-+      }
-+      
-+      while ( temp!=NULL && temp->hcpriv!=pUrb) {
-+              temp=(struct urb*)temp->hcpriv;
++              /* when using the HCD driver, idle BETTER be 1 :)) */
++              if ( idle ) {
++                      mgc_linux_kickstart_urb(pThis, pEnd->bEnd);
++              }
 +      }
 +
-+      return temp;
-+}
-+
-+/*
-+ * push back an urb to the hcd queue.
-+ * @param pThs the controller
-+ * @param pUrb the urb push in queue
-+ * @return <0 if error, 0 when the queue is idle, >0 otherwise 
-+ */ 
-+inline static int mgc_hcd_urb_pushback(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) {
 +#ifdef MUSB_PARANOID
-+      if (!pUrb) {
-+              ERR("*** cannot push NULL urb\n");              
-+              return -ENODEV;
++      DEBUG_CODE(5, dump_urb(pUrb); );
++      if ( MGC_ISCORRUPT(pThis) ) {
++              ERR("stopping after submit\n");
++              MGC_HdrcStop(pThis);
++              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
++              DBG(2, "==> -ENOENT\n");
++              return -ENODEV; /* like a disconect */
 +      }
 +#endif
 +
-+      pQueue->urb_queue_count++;
-+      pUrb->hcpriv=pQueue->urb_queue_head;
-+      pQueue->urb_queue_head=pUrb;
-+      if ( !pQueue->urb_queue_tail ) {
-+              pQueue->urb_queue_tail=pUrb;
-+      }
-+
++    DBG(2, "==>\n");
 +      return 0;
 +}
 +
-+/*
-+ * Queue at an urb to the hcd queue. 
-+ * @return <0 if error, 0 when the queue is idle, >0 otherwise 
-+ */ 
-+inline static int mgc_hcd_queue_urb(mgc_hcd_urb_queue *pQueue, struct urb* pUrb) {
-+      int status=0;
++/**
++ * Submit an URB, either to the virtual root hut or to a real device;
++ * it also checks the URB to make sure it's valid.
++ * This is called by the Linux USB core. TSubmit Urb lock pThis
++ * and the End to use, so make sure the caller releases its locks.
++ *
++ * @param pThis the controller
++ * @param pUrb URB pointer (urb = USB request block data structure)
++ * @param iMemFlags memeory flags (see kernel docs)
++ * @return status code (0 succes)
++ */
++int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb,
++      MUSB_MEMFLAG_TYPE iMemFlags)
++{
++      int nEnd=0, rc;
++
++    DBG(2, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s\n",
++              pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb));
 +
 +#ifdef MUSB_PARANOID
-+      if (!pUrb) {
-+              ERR("*** cannot queue NULL urb\n");             
-+              return -ENODEV;
++      if( MGC_ISCORRUPT(pThis) ) {
++              ERR("==> pThis corrupted: stopping before submit\n");
++              MGC_HdrcStop(pThis);
++              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
++              return -ENOENT;
 +      }
 +#endif
-+      
-+      spin_lock(&pQueue->urb_queue_lock);
-+      if ( !pQueue->urb_queue_head ) { /* idle */
-+              pQueue->urb_queue_head=pUrb;
-+              pQueue->urb_queue_tail=pUrb;
-+              pQueue->urb_queue_count++;
-+      } else { /* queue */            
-+              if ( pQueue->urb_queue_tail ) {
-+                      ((struct urb*)pQueue->urb_queue_tail)->hcpriv=pUrb;
-+                      pQueue->urb_queue_tail=pUrb;
-+                      pQueue->urb_queue_count++;
-+                      status=pQueue->urb_queue_count; /* queued */
-+              } else {
-+                      ERR("*** pThis->urb_queue_head=%p, pThis->urb_queue_tail=%p; this is BAD (TM)\n",
-+                              pQueue->urb_queue_head, pQueue->urb_queue_tail);
 +
-+                      status=-ENODEV;
-+              }
-+      }               
-+      spin_unlock(&pQueue->urb_queue_lock);
-+      
-+      return status;
-+}
++#ifndef MUSB_USE_HCD_DRIVER
++    /* if it is a request to the virtual root hub, delegate */
++    /* if( usb_pipedevice(pipe) == pThis->RootHub.bAddress) */
 +
++    /* pUrb->dev->parent==null means that the device is the root hub,
++     this should be fine on every platform. */
++    if( !pUrb->dev->parent ) {
 +/*
-+ * top of the scheduler queue.
-+ * @param pThis the controller
-+ * @return next urb to be queued to hardware, NULL if idle
-+ */
-+inline static struct urb* mgc_hcd_urb_top(mgc_hcd_urb_queue *pQueue) {
-+      return pQueue->urb_queue_head;  
-+}
++      if(pThis->bDelayPortPowerOff)
++      {
++          return -ENODEV;
++      }
++*/
++              const int rc=MGC_VirtualHubSubmitUrb(&(pThis->RootHub), pUrb);
++              DBG(2, "==> sbmitted to vhub rc=%d\n", rc);
++              return rc;
++    }
++#endif
 +
-+/*
-+ * 
-+ */
-+inline static struct urb* mgc_hcd_urb_pop(mgc_hcd_urb_queue *pQueue) {
-+      struct urb* pUrb=pQueue->urb_queue_head;        
++      /* find appropriate local endpoint to do it */
++    nEnd=mgc_linux_find_end(pThis, pUrb);
++    DBG(3, "pUrb=%p, end=%d, bufsize=%x\n", pUrb, \
++      nEnd, pUrb->transfer_buffer_length);
 +
-+      if ( pUrb ) {
-+              pQueue->urb_queue_count--;
-+              pQueue->urb_queue_head=pUrb->hcpriv;
-+              if ( !pQueue->urb_queue_head ) {
-+                      pQueue->urb_queue_tail=NULL;
-+              }               
-+      } else {
-+              pQueue->urb_queue_count=0; /* paranoid */
-+              pQueue->urb_queue_head=NULL;
-+              pQueue->urb_queue_tail=NULL;    
-+      }
-+      
-+      return pUrb;
-+}
++#ifdef MUSB_PARANOID
++    if (nEnd < 0) {
++              unsigned int pipe = pUrb ? pUrb->pipe : 0;
++              pUrb->status = USB_ST_URB_REQUEST_ERROR;
++              ERR("==> no resource for proto=%d, addr=%d, end=%d\n", \
++             usb_pipetype(pipe), usb_pipedevice(pipe), \
++             usb_pipeendpoint(pipe));
++               return USB_ST_URB_REQUEST_ERROR;
++    }
++#endif
 +
-+/* ------------------------------------------------------------------- */
++    /* if no root device, assume this must be it */
++    if ( !pThis->pRootDevice ) {
++              pThis->pRootDevice = pUrb->dev;
++    }
 +
-+static void mgc_hcd_stop(struct usb_hcd *hcd)
-+{     
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
++      { /* queue */
++              unsigned long flags=0;
++              MGC_LinuxLocalEnd *pEnd=&pThis->aLocalEnd[nEnd];
 +
-+#ifdef MUSB_PARANOID
-+      if ( !pThis ) {
-+              ERR("pThis is null");
-+              return;
++              if ( !pEnd->bBusyCompleting ) {
++                      SPIN_LOCK_IRQSAVE(&pEnd->Lock, flags);
++              }
++
++              pUrb->status=-EINPROGRESS;
++              rc=mgc_schedule_urb(pThis, pEnd, pUrb);
++
++              if ( ! pEnd->bBusyCompleting ) {
++                      SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags);
++              }
 +      }
-+#endif
-+      
-+    mgc_hdrc_disable(pThis);
++
++      return rc;
 +}
 +
-+static int __devinit mgc_hcd_start(struct usb_hcd *hcd)
++/**
++ * Generic v26 version (pre10).
++ */
++static inline int
++      mgc_linux_submit_urb_common(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags)
 +{
-+      int rc=0;
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
++    MGC_LinuxCd* pThis;
 +
-+      DBG(2, "<== Starting hcd=%p\n", hcd);
++    DBG(2, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s\n",
++              pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb));
 +
 +#ifdef MUSB_PARANOID
-+      if ( !pThis ) {
-+              ERR("pThis is null");
-+              return -ENODEV;
-+      }
++    if (!pUrb || !pUrb->dev || !pUrb->dev->bus ) {
++              DBG(2, "==> invalid URB");
++              return -EINVAL;
++    }
 +#endif
 +
-+      hcd->state = HC_STATE_RUNNING;
-+      pThis->pBus = &hcd->self;
-+    pThis->pBus->bus_name = pThis->aName;
-+      pThis->pBus->hcpriv = (void *)hcd;
-+      
-+      rc=mgc_init_root_hub(pThis);
-+      if ( rc==0 ) {
-+              DBG(3, "New bus @%p\n", pThis->pBus);
-+      } else {
-+              ERR("*** could not initialize the root hub\n"); 
-+              return -ENODEV;                                                            /* return if not success !! */
++    pThis = (MGC_LinuxCd*)pUrb->hcpriv;
++    if ( !pThis ) {
++              DBG(2, "==> invalid URB: pThis is null");
++              return -EINVAL;
 +      }
 +
-+      DBG(2, "==> rc=0\n");
-+      return 0;
++      return mgc_submit_urb(pThis, pUrb, iMemFlags);
 +}
 +
-+/* ------------------------------------------------------------------- */
 +
-+/**
-+ *
-+ */
-+mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis) {
-+      return &pThis->LocalQueue;
++#ifdef MUSB_V26
++int MGC_LinuxSubmitUrb26(struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags)
++{
++      return mgc_linux_submit_urb_common(pUrb, iMemFlags);
 +}
++#endif
 +
-+/* ------------------------------------------------------------------- */
-+
-+/**
-+ *
-+ */
-+void mgc_hcd_flush(MGC_LinuxCd* pThis) {
-+      struct urb* pUrb;
-+      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);         
-+      
-+      DBG(2, "<== flushing\n");
-+      spin_lock(&pQueue->urb_queue_lock);     
-+      do      {
-+              pUrb=mgc_hcd_urb_pop(pQueue);   
-+              if ( pUrb ) {
-+                      DBG(3, "flushed=%p\n", pUrb);
-+                      pUrb->status=-ENOENT;
-+                      usb_kill_urb(pUrb);
-+              } else {
-+              
-+              }               
-+      } while ( pUrb );
-+      spin_unlock(&pQueue->urb_queue_lock);
-+      DBG(2, "==>\n");
++#ifdef MUSB_V24
++int MGC_LinuxSubmitUrb24(struct urb* pUrb)
++{
++      return mgc_linux_submit_urb_common(pUrb, GFP_ATOMIC);
 +}
++#endif
++
++/* --------------------------------------------------------------------- */
 +
 +/**
++ * Cross version unlink
 + *
++ * @param pThis the controller
++ * @param pUrb the Urb to  unlink
++ * @return
 + */
-+void mgc_hcd_complete_urb(MGC_LinuxCd* pThis, struct urb *pUrb)
++int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb)
 +{
-+      mgc_hcd_get_urb_queue(pThis)->urb_exec_count--;
-+ 
-+      usb_hcd_giveback_urb(musbstruct_to_hcd(pThis), pUrb); /* this call complete */ 
++      unsigned long flags;
++    MGC_LinuxLocalEnd* pEnd;
 +
-+      /*printk("Yes completed:%d\n",usb_pipeendpoint(pUrb->pipe));*/
-+}
++      DBG(-1, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s \n", pUrb, pUrb->hcpriv,
++              decode_urb_protocol(pUrb));
 +
-+/**
-+ * Schedule the urb to the hardware. 
-+ * @param pThis the controller
-+ */
-+int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis)
-+{
++#ifdef MUSB_PARANOID
++    if(MGC_ISCORRUPT(pThis)) {
++              ERR("pThis corrupted: stopping before unlink\n");
++              MGC_HdrcStop(pThis);
++              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
++              DBG(2, "==>\n");
++              return -EINVAL;
++    }
++#endif
 +
-+      
-+      int rc=0, nEnd;
-+      struct urb*pUrb;
-+      MGC_LinuxLocalEnd *pEnd;
-+      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
-+      
-+      do {
++#ifndef MUSB_USE_HCD_DRIVER
++    /* if it is a request to the virtual root hub, delegate */
++    /* if (usb_pipedevice (pUrb->pipe) == pThis->RootHub.bAddress) */
++    if( !pUrb->dev->parent ) {
++              int rc=MGC_VirtualHubUnlinkUrb(&(pThis->RootHub), pUrb);
++              DBG(2, "==> VirtualHub rc=%d\n", rc);
++              return rc;
++    }
++#endif
 +
-+              DBG(2, "<== pQueue->urb_queue_count=%d, pQueue->urb_exec_count=%d\n",
-+                              pQueue->urb_queue_count, pQueue->urb_exec_count);
++      /* which end was the urb queued? */
++    pEnd=(MGC_LinuxLocalEnd*)pUrb->hcpriv;
++      if ( pEnd )
 +
-+              if ( !MUSB_IS_HST(pThis) ) {
-+                      break; /* nothing to do */
-+              }
-+              
-+              spin_lock(&pQueue->urb_queue_lock);     
-+              pUrb=mgc_hcd_urb_pop(pQueue);   
-+              if ( !pUrb ) {
-+                      DBG(3, "scheduler is idle\n");                  
-+                      spin_unlock(&pQueue->urb_queue_lock);
-+                      break;
-+              }
-+              
-+              DBG(3, "pUrb=%p, (proto=%s)\n", pUrb, decode_urb_protocol(pUrb));                       
-+              nEnd=mgc_hcd_find_end(pThis, pUrb);
-+              if ( nEnd<0 ) {
-+                      spin_unlock(&pQueue->urb_queue_lock);
-+                      ERR("***> no resource for proto=%s, addr=%d, end=%d\n", 
-+                         decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe), 
-+                         usb_pipeendpoint(pUrb->pipe));
-+                      if ( !pQueue->urb_exec_count ) {
-+                              /* push it back and give it another chance */                                                   
-+                              mgc_hcd_urb_pushback(pQueue, pUrb);
-+                              ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n", 
-+                                      pUrb, nEnd, rc);
-+                              break;
-+                      } else {
-+                              /* the urb will never be scheduled, kill it and move to next */
-+                              usb_kill_urb(pUrb);
-+                              ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n", 
-+                                      pUrb, nEnd);
-+                              continue;
++      /* somehow, we got passed a dangling URB pointer */
++    if((pEnd < &(pThis->aLocalEnd[0])) ||
++              (pEnd > &(pThis->aLocalEnd[MUSB_C_NUM_EPS-1])))
++    {
++#ifdef MUSB_USE_HCD_DRIVER
++              DBG(-1, "==> cannot unlink pUrb=%p, pEnd=%p is invalid\n", pUrb,
++                      pEnd);
++        return -EINVAL;
++#endif
++    }
++
++      if (  MUSB_IS_HST(pThis) && pUrb->transfer_flags & USB_ASYNC_UNLINK ) {
++              DBG(-1, "Asyncronous unlink of pUrb=%p (pUrb->status=%d)\n",
++                      pUrb, pUrb->status);
++      } else {
++              DBG(-1, "Syncronous unlink of pUrb=%p (pUrb->status=%d)\n", pUrb,
++                      pUrb->status);
++
++              SPIN_LOCK_IRQSAVE(&pEnd->Lock, flags);
++              if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
++                      int status;
++
++                      SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags);
++                      status=mgc_linux_complete_urb(pThis, pEnd, pUrb);
++                      if ( status==-EINVAL ) {
++                              ERR("*** cannot unlink pUrb=%p from bEnd=%d (current=%p)\n", pUrb,
++                                      pEnd->bEnd, MGC_GetCurrentUrb(pEnd));
 +                      }
-+              } 
-+              
-+              pEnd=&pThis->aLocalEnd[nEnd];                           
-+              if ( mgc_ep_is_idle(pEnd) ) {
-+                      DBG(3, "(%d/%d) pUrb=%p, nEnd=%d, %s \n", 
-+                              pQueue->urb_queue_count, pQueue->urb_exec_count, 
-+                              pUrb, nEnd, mgc_ep_is_idle(pEnd)?"idle":"busy");
-+                      spin_unlock(&pQueue->urb_queue_lock);
-+                      rc=mgc_schedule_urb(pThis, pEnd, pUrb);
-+                      if ( rc!=0 ) {
-+                              if ( !pQueue->urb_exec_count ) {
-+                                      /* the urb will never be scheduled, kill it */
-+                                      usb_kill_urb(pUrb);
-+                                      ERR("** ABORTING pUrb=%p to nEnd=%d; this is BAD (TM)\n", 
-+                                              pUrb, nEnd);
-+                              } else {                                
-+                                      /* push it back and give it another chance */                                                   
-+                                      mgc_hcd_urb_pushback(pQueue, pUrb);
-+                                      ERR("??? schedule of pUrb=%p to nEnd=%d FAILED rc=%d\n", 
-+                                              pUrb, nEnd, rc);                                                
-+                              }
-+                      } else {
-+                              /* removed from the queue, scheduled to hardware */
-+                              pQueue->urb_exec_count++;
-+                              break;
-+                      }                       
-+              } else { /* too fast ? */       
-+                      mgc_hcd_urb_pushback(pQueue, pUrb);
-+                      spin_unlock(&pQueue->urb_queue_lock);
-+                      DBG(3, "???> cannot schedule pUrb=%p to nEnd=%d yet (busy with pEnd->pCurrentUrb=%p)\n", 
-+                              pUrb, nEnd, MGC_GetCurrentUrb(pEnd));
-+                      break;
++              } else {
++                      SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags);
++                      ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb,
++                              pEnd->bEnd);
 +              }
-+              
-+      } while ( 1 );
-+      
-+      DBG(2, "==> rc=%d\n", rc);
-+      return rc;
-+}
++      }
 +
-+/* ------------------------------------------------------------------ */
++#ifdef MUSB_PARANOID
++    if(MGC_ISCORRUPT(pThis)) {
++              ERR("stopping after unlink\n");
++              MGC_HdrcStop(pThis);
++              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
++              return -EINVAL;
++    }
++#endif
 +
-+/**
-+ * Find a local endpoint suitable for transmitting the given urb minimizing 
-+ * the reconfigurations. The best localendpoint is selceted using the following 
-+ * criterion:
-+ * - ep0 is used for control Urbs
-+ * - for bulk Urbs only (when available) choose the Tx or Rx reserved end
-+ * - determine direction, size and traffic type 
-+ *
-+ * @param pThis instance pointer
-+ * @param pURB URB pointer
-+ * @return suitable local endpoint
-+ * @return -1 if nothing appropriate
-+ */
-+static int mgc_hcd_find_end(MGC_LinuxCd* pThis, struct urb* pUrb)
-+{
-+      return mgc_linux_find_end(pThis, pUrb);
++    DBG(-1, "==> rc=0\n");
++    return 0;
 +}
 +
 +/**
-+ * Submit an urb to our HCD driver. The urb will be queued and (sooner or later)
-+ * scheduled to the hardware driver. The Urb had been queued to the ep from the
-+ * kernel, DON'T modify with the urb_list otherwise BAD THINGS WILL 
-+ * HAPPEN (TM). 
-+ * @param hcd the HCD driver
-+ * @param pURB URB pointer
++ * unlink an urb, common code.
++ * @param pUrb the urb to unlink
 + */
-+static int mgc_hcd_submit_urb(struct usb_hcd *hcd, struct usb_host_endpoint *ep, 
-+      struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags)
++static int mgc_linux_unlink_urb(struct urb* pUrb, int status)
 +{
++    MGC_LinuxCd* pThis;
 +
-+      int rc=0;
-+
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
-+
-+      if(Urb_status==1)
-+      {
-+              pUrb->status=-ENODEV;
-+              rc=-ENODEV;             
-+              return rc;
-+      }
-+      
-+#ifdef MUSB_PARANOID
-+              if ( !pThis ) {
-+                      ERR("***==> pThis is null\n");
-+                      return -ENODEV;
-+              }
++    DBG(2, "<== pUrb=%p\n", pUrb);
 +
-+              if ( !pUrb ) {
-+                      ERR("***==> pUrb is NULL\n");
-+                      return -ENODEV;         
-+              }       
++    /* sanity */
++    if (!pUrb || !pUrb->hcpriv) {
++              DBG(2, "==> invalid urb%p, pUrb->hcpriv=%p\n", pUrb,
++                      (pUrb)?pUrb->hcpriv:NULL);
++              return -EINVAL;
++    }
 +
-+              pUrb->hcpriv=NULL; /* paranoid!! */
-+              pUrb->status=-EINPROGRESS; /* paranoid!! */
-+#endif
++    if (!pUrb->dev || !pUrb->dev->bus) {
++              DBG(2, "==>\n");
++              return -ENODEV;
++    }
 +
-+              DBG(2, "<== submit pUrb=%p, pUrb->hcpriv=%p, (proto=%s), bRemoteAddress=%d, bRemoteEnd=%d\n", 
-+                              pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb), usb_pipedevice(pUrb->pipe), 
-+                              usb_pipeendpoint(pUrb->pipe));
++    pThis = (MGC_LinuxCd*)pUrb->hcpriv;
++    if(!pThis) {
++              ERR("==> pThis is null: stopping before unlink\n");
++              return -ENODEV;
++    }
 +
-+              if ( pUrb->hcpriv ) {
-+                      ERR("***==> on submission pUrb->hcpriv=%p; this is BAD (TM)\n", pUrb->hcpriv);
-+                      return -ENODEV;
-+              }
++      pUrb->status =status;
++      return mgc_unlink_urb(pThis, pUrb);
++}
 +
-+              {
-+                      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
-+                      int count=mgc_hcd_queue_urb(pQueue, pUrb);              
-+                      if ( count<0 ) {
-+                              rc=-ENODEV;
-+                      } else if ( count==0 ) {
-+                              rc=mgc_hcd_schedule_urb(pThis);
-+                              /*printk("Queued for scheduled:%d\n",usb_pipeendpoint(pUrb->pipe));*/
-+                      } /* count>0 it's been queued */
-+                      /*else
-+                      {
-+                              printk("Count> 0:%d\n",usb_pipeendpoint(pUrb->pipe));
-+                      }*/
-+              }
++/**
++ * Cancel URB.
++ * @param pUrb URB pointer
++ */
++#ifdef MUSB_V26
++int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status) {
++      return mgc_linux_unlink_urb(pUrb, status);
++}
++#endif
 +
++#ifdef MUSB_V24
++ /* ENOENT=kill ECONNRESET=unlink */
++int MGC_LinuxUnlinkUrb24(struct urb* pUrb) {
++      return mgc_linux_unlink_urb(pUrb, -ENOENT);
++}
++#endif
 +
 +
-+      DBG(2, "==> rc=%d\n", rc);      
-+      return rc;
-+}
++/* --------------------------------------------------------------------- */
 +
 +/**
-+ * unlink an urb, hcd version. First check if the urb was queued to the
-+ * hardware, if not search it in the hcd queue, if not... this is BAD 
-+ * (TM).
-+ * @param hcd the HCD driver
-+ * @param pURB URB pointer
++ * Initialize the local end points; pThis->bEndCount must be initialized.
++ * @param pThis the controller
 + */
-+static int mgc_hcd_unlink_urb(struct usb_hcd *hcd, struct urb *pUrb)
-+{     
-+      int rc=0;
-+      MGC_LinuxLocalEnd* pEnd;
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(hcd);
-+      mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
-+      
++void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis) {
++    uint8_t bEnd;
++    MGC_LinuxLocalEnd* pEnd;
++
 +#ifdef MUSB_PARANOID
 +      if ( !pThis ) {
-+              ERR("pThis is null");
-+              return -ENODEV;
++              ERR("Controller not initialized\n");
++              return;
++      }
++
++      if ( !pThis->bEndCount ) {
++              WARN("pThis->bEndCount=%d might be wrong\n", pThis->bEndCount);
 +      }
 +#endif
 +
-+    DBG(-1, "<== Unlinking pUrb=%p (%s), pUrb->hcpriv=%p\n", pUrb, 
-+              decode_urb_protocol(pUrb), pUrb->hcpriv); 
-+      spin_lock(&pQueue->urb_queue_lock);
-+      pEnd=mgc_ep_find_end(pThis, pUrb);
-+      if ( pEnd ) { /* was submitted */
-+              spin_unlock(&pQueue->urb_queue_lock);
-+              rc=mgc_unlink_urb(pThis, pUrb);
-+      } else { /* remove the urb */
-+              struct urb* prev;
-+              prev=mgc_hcd_urb_find_prev(pQueue, pUrb);
-+              if ( prev==NULL ) { /* not mine! */
-+                      ERR("*** cannot find pUrb=%p: is not mine! this is bad (tm)\n", 
-+                              pUrb);
-+              } else if ( prev==pUrb ) { /* list head */
-+                      pQueue->urb_queue_head=prev->hcpriv;
-+                      if ( pQueue->urb_queue_tail==prev ) {
-+                              pQueue->urb_queue_tail=prev->hcpriv;                    
++    for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++              pEnd = &(pThis->aLocalEnd[bEnd]);
++              pEnd->bEnd=bEnd;
++
++#ifdef MUSB_PARANOID
++              if ( bEnd ) {
++                      if ( spin_is_locked(&pEnd->Lock) ) {
++                              WARN("End=%d is locked\n", bEnd);
 +                      }
-+              } else {
-+                      prev->hcpriv=pUrb->hcpriv;
-+              }                               
-+              spin_unlock(&pQueue->urb_queue_lock);           
-+      }
 +
-+      DBG(2, "==> Unlinked urb=%p\n", pUrb);  
-+      return rc;
-+}
++                      if ( !mgc_ep_is_idle( pEnd ) ){
++                              WARN("pEnd=%d pEnd->urb_list=%p: not idle\n", pEnd->bEnd,
++                                      MGC_GetCurrentUrb(pEnd));
++                      }
++              }
++#endif
 +
-+/**
-+ * return the frame number
-+ * @param hcd the HCD driver
-+ * @return the frame number
-+ */
-+static int mgc_hcd_get_frame_number(struct usb_hcd *hcd) {
-+      return mgc_get_frame_number( hcd_to_musbstruct(hcd) );
-+}
++              mgc_ep_idle( pEnd );
++              spin_lock_init( &pEnd->Lock );
 +
-+/**
-+ * Interrupt service routine, redirect it to the main routine/
-+ * @param hcd the HCD driver
-+ * @param r the pt registers
-+ * @return 
-+ */
-+static irqreturn_t mgc_hcd_isr(struct usb_hcd *hcd)
-+{
-+      return mgc_linux_isr( hcd_to_musbstruct(hcd) );
++              /* restore the pads */
++#if MUSB_DEBUG > 0
++              pEnd->dwPadFront = MGC_PAD_FRONT;
++              pEnd->dwPadBack = MGC_PAD_BACK;
++#endif
++
++              /* reset the counters */
++#ifdef MUSB_CONFIG_PROC_FS
++              pEnd->dwTotalRxBytes = 0;
++              pEnd->dwTotalRxPackets = 0;
++              pEnd->dwErrorRxPackets = 0;
++              pEnd->dwTotalTxBytes = 0;
++              pEnd->dwTotalTxPackets = 0;
++              pEnd->dwErrorTxPackets = 0;
++              pEnd->dwWaitFrame = 0;
++#endif
++
++              /* reset the softstate */
++              pThis->aLocalEnd[bEnd].bIsClaimed=FALSE;
++              pEnd->wPacketSize = 0;
++              pEnd->bRemoteAddress = 0;
++              pEnd->bRemoteEnd = 0;
++              pEnd->bTrafficType = 0;
++              pEnd->bIsTx=0;
++      }
++
++      mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY;
 +}
 +
 +/**
-+ * @param hcd the HCD driver
-+ * @param ep the endpoint to disable
++ * initialize the root hub.
++ * @param pThis the controller.
++ * @return 0 for success, <0 for error
++ * @warning I will move this to virthub.c
 + */
-+static void mgc_hcd_disable_endpoint(struct usb_hcd *hcd, 
-+      struct usb_host_endpoint *ep)
-+{
-+   DBG(-1, "hw sync with ep=%d (%s) list_empty(&ep->urb_list)=%d\n", 
-+      0x7f&ep->desc.bEndpointAddress, (ep->desc.bEndpointAddress==0) ? "in/out"
-+                      : (ep->desc.bEndpointAddress>=0x80)?"in":"out",  
-+                      list_empty(&ep->urb_list) );
-+                      
-+   DBG(2, "<== disable endpoint %d (%s)\n", 0x7f&ep->desc.bEndpointAddress, 
-+              (ep->desc.bEndpointAddress==0) ? "in/out"
-+                      : (ep->desc.bEndpointAddress>=0x80)?"in":"out");                        
-+   
-+   DBG(2, "==>disabled endpoint %d\n", 0x7f&ep->desc.bEndpointAddress);    
-+}
++int mgc_init_root_hub(MGC_LinuxCd *pThis) {
++      int rc=0;
 +
-+/* --------------------------------------------------------------- */
-+/* Virtual hub */
-+/* --------------------------------------------------------------- */
++    pThis->PortServices.pPrivateData = pThis;
++    pThis->PortServices.pfSetPortPower = MGC_LinuxSetPortPower;
++    pThis->PortServices.pfSetPortEnable = MGC_LinuxSetPortEnable;
++    pThis->PortServices.pfSetPortSuspend = MGC_LinuxSetPortSuspend;
++    pThis->PortServices.pfSetPortReset = MGC_LinuxSetPortReset;
 +
-+/** 
-+ * Report the virtual hub status.
-+ *
-+ * @param hcd the hcd
-+ * @param pData the buffer to store the status in
-+ */
-+static int mgc_root_hub_status(struct usb_hcd *hcd, char *pData)
-+{
-+      MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd);
-+      MGC_VirtualHub* pHub = &(pThis->RootHub);
-+      int len = 0;
++      rc=MGC_VirtualHubInit(&(pThis->RootHub), pThis->pBus, 1,
++              &(pThis->PortServices));
 +
-+      spin_lock(&pHub->Lock); 
-+      len = mgc_rh_port_status(pHub, pData);
-+    pHub->bIsChanged = FALSE; 
-+      spin_unlock(&pHub->Lock);       
-+      DBG(5, "len=%d, status=%02x\n", len, pData[0]); 
-+      return len;
++      return rc;
 +}
 +
-+/** MGC_VirtualhubControl Instead of MGC_VirtualHubSubmitUrb
-+ * @param hcd the HCD driver
++
++#if 0
++#if MUSB_DEBUG > 0
++/*
++ * Test endpoint FIFO (only endpoint 0 until the others have a way)
 + */
-+static int mgc_root_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 
-+      u16 wIndex, char *pData, u16 wLength)
++static uint8_t MGC_HdrcTestFifo(uint8_t* pBase, uint8_t bEnd,
++      uint8_t bDatum, uint16_t wCount)
 +{
-+      MGC_LinuxCd* pThis = hcd_to_musbstruct(hcd);
-+      MGC_VirtualHub* pHub = &(pThis->RootHub);
-+    uint8_t bPort = (uint8_t)(wIndex & 0xff) - 1;
-+    uint16_t wSize = 0xffff;
-+      int retval = 0;
-+      int     ports = (pHub->bPortCount + 1);
-+  
-+      DBG("<==\n");   
-+      DBG("Setup_Data: bmReqtype-bmRequest=%04x | wValue=%x | wIndex=%x | wLength=%04x \n", \
-+              typeReq, wValue, wIndex, wLength); 
-+      DBG("Setup_Data: wValue=%04x | wIndex=%04x | wLength=%04x | \n", \
-+               wValue, wIndex, wLength); 
++    uint8_t aTest[64];
++    uint16_t wReg, wIndex, wReadCount;
++    uint8_t bReadVal, bReg;
++    uint8_t bResult = TRUE;
 +
-+      switch (typeReq) {
-+              case ClearHubFeature:
-+                      switch (wValue) {
-+                              case C_HUB_LOCAL_POWER:
-+                              case C_HUB_OVER_CURRENT:
-+                                      wSize = 0;
-+                                      break;
-+                              default:
-+                                      goto error;
-+                      }
-+                      break;
-+              case ClearPortFeature:
-+                      if (!wIndex || wIndex > ports)
-+                              goto error;
-+                      wIndex--;
-+                      switch (wValue) {
-+                              case USB_PORT_FEAT_ENABLE:
-+                                      DBG("enable port %d\n", bPort); 
-+                                      pHub->pPortServices->pfSetPortEnable(
-+                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_C_ENABLE:
-+                                      DBG("ack enable port %d\n", bPort); 
-+                                      pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE;
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_SUSPEND:
-+                                      DBG("suspend port %d\n", bPort); 
-+                                      pHub->pPortServices->pfSetPortSuspend(
-+                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_C_SUSPEND:
-+                                      DBG("ack suspend port %d\n", bPort); 
-+                                      pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND;
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_POWER:
-+                                      DBG("feat feat power port %d\n", bPort); 
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_C_CONNECTION:
-+                                      DBG("ack connection port %d\n", bPort); 
-+                                      pHub->aPortStatusChange[bPort].wChange &= ~1;
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_C_OVER_CURRENT:
-+                                      DBG("ack over current port %d\n", bPort); 
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_C_RESET:
-+                                      DBG("ack reset port %d\n", bPort); 
-+                                      pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET;
-+                                      wSize = 0;
-+                                      break;
-+                              default:
-+                                      goto error;
-+                      }
-+                      break;
-+              case GetHubDescriptor:
-+                      DBG("GET_CLASS_DESCRIPTOR()\n");
-+                      pData[0] = 9;
-+                      pData[1] = 0x29;
-+                      pData[2] = pHub->bPortCount;
-+                      /* min characteristics */
-+                      pData[3] = 1;  /* invidual port power switching */
-+                      pData[4] = 0;
-+                      /* PowerOn2PowerGood */
-+                      pData[5] = 50;
-+                      /* no current */
-+                      pData[6] = 0;
-+                      /* removable ports */
-+                      pData[7] = 0;
-+                      /* reserved */
-+                      pData[8] = 0xff;
-+                      wSize = pData[0];
-+                      break;
-+              case GetHubStatus:
-+                      /* hub status */
-+                      memset(pData, 0, 4);
-+                      wSize = 4;
-+                      DBG("hub statusreport=%02x%02x%02x%02x\n", 
-+                              pData[0], pData[1], pData[2], pData[3]); 
-+                      break;
-+              case GetPortStatus:
-+                      if (!wIndex || wIndex > ports)
-+                              goto error;
-+                      /* port status/change report */
-+                      memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2);
-+                      memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange), 2);
-+                      /* reset change (TODO: lock) */
-+                      pHub->aPortStatusChange[wIndex-1].wChange = 0;
-+                      wSize = 4;
-+                      DBG("port status report=%02x%02x%02x%02x\n", 
-+                              pData[0], pData[1], pData[2], pData[3]); 
-+                      break;
++    INFO("Testing FIFO on endpoint %d...\n", bEnd);
 +
-+              case SetHubFeature:
-+                      switch (wValue) {
-+                              case C_HUB_OVER_CURRENT:
-+                              case C_HUB_LOCAL_POWER:
-+                                      break;
-+                              default:
-+                                      goto error;
-+                      }
-+                      break;
-+              case SetPortFeature:
-+                      if (!wIndex || wIndex > ports)
-+                              goto error;
-+                      switch (wValue) {
-+                              case USB_PORT_FEAT_SUSPEND:
-+                                      DBG("suspend port %d\n", bPort); 
-+                                      pHub->pPortServices->pfSetPortSuspend(
-+                                              pHub->pPortServices->pPrivateData, bPort, TRUE);
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND;
-+                                      pHub->bIsChanged = TRUE;
-+                                      wSize = 0;
-+                                      break;
-+                              case USB_PORT_FEAT_POWER:
-+                                      DBG("power port %d\n", bPort); 
-+                                      
-+                                        #if 1
-+                                              {
-+                                                      int err;
-+                                                      err = STMPE2401_SetGpioAltFunction(STMPE1,EGPIO_PIN_0,STMPE2401_PRIMARY_FUNCTION);
-+                                                      if (err != STMPE2401_OK)
-+                                                    DBG("Couldn't set STMPE%d %d as primary function\n",STMPE1,EGPIO_PIN_0);
-+                                                      err = STMPE2401_SetGpioDir( STMPE1,EGPIO_PIN_0,STMPE2401_GPIO_OUT );
-+                                                      if (err != STMPE2401_OK)
-+                                                      DBG("Couldn't set STMPE EGPIO:%d in Output direction\n", EGPIO_PIN_0);
-+                                                     err = STMPE2401_SetGpioVal( STMPE1, EGPIO_PIN_0, 0); 
-+                                                    if (err != STMPE2401_OK)
-+                                                    DBG("Couldn't set STMPE GPIO12\n");
++    for(wIndex = 0; wIndex < min(wCount, (uint16_t)64); wIndex++) {
++              aTest[wIndex] = bDatum;
++    }
 +
-+                                              }
-+                                      #endif
-+                                      pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData, 
-+                                              bPort,TRUE);
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER;
-+                                      wSize = 0;
++    wReg = MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
++    MGC_Write16(pBase, MGC_O_HDRC_INTRTX, wReg & ~1);
++    MGC_SelectEnd(pBase, bEnd);
++    if(bEnd) {
++    } else {
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
++                      MGC_M_CSR0_FLUSHFIFO);
++    }
++    MGC_HdrcLoadFifo(pBase, bEnd, wCount, aTest);
++    MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, MGC_M_TEST_FIFO_ACCESS);
++    memset(aTest, 0, 64);
++    do {
++              bReg = MGC_Read8(pBase, MGC_O_HDRC_TESTMODE);
++    } while(bReg & MGC_M_TEST_FIFO_ACCESS);
 +
-+                                      break;
-+                              case USB_PORT_FEAT_RESET:
-+                                      DBG("USB_Class set feature USB_PORT_FEAT_RESET Port_no:%d \n",
-+                                              bPort);    
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET;
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
-+                                      pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET;
-+                                      pHub->bIsChanged = TRUE;
-+              
-+                                      pHub->pPortServices->pfSetPortReset(
-+                                              pHub->pPortServices->pPrivateData, bPort, TRUE);
-+                                      wSize = 0;
-+                                      break;
-+                              default:
-+                                      goto error;
-+                      }
-+                      break;
++    if(bEnd) {
++              wReadCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
++    } else {
++              wReadCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
++    }
 +
-+              default:
-+error:
-+                      /* "protocol stall" on error */
-+                      retval = -EPIPE;
-+      }
++      if(wReadCount != wCount) {
++              ERR("Error: loaded FIFO with %04x bytes, RxCount=%04x\n",
++              wCount, wReadCount);
++                      bResult = FALSE;
++    }
++    wReadCount = min(wReadCount, (uint16_t)64);
++    MGC_HdrcUnloadFifo(pBase, bEnd, wReadCount, aTest);
++    if(bEnd) {
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, 0);
++    } else {
++              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY);
++    }
 +
-+      DBG("==> retval=%d\n", retval);         
-+      return retval;
++      MGC_Write16(pBase, MGC_O_HDRC_INTRTX, wReg);
++    for(wIndex = 0; wIndex < wReadCount; wIndex++) {
++              if(bDatum != aTest[wIndex]) {
++                      ERR("Error: FIFO Tx data=%02x, Rx data=%02x\n", bDatum,
++                              aTest[wIndex]);
++                      bResult = FALSE;
++              }
++    }
++    return bResult;
 +}
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbhdrc.h ../new/linux-2.6.20/drivers/usb/nomadik/musbhdrc.h
---- linux-2.6.20/drivers/usb/nomadik/musbhdrc.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musbhdrc.h 2008-08-08 19:15:31.000000000 +0530
-@@ -0,0 +1,315 @@
++#endif
++#endif
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_host.h
+@@ -0,0 +1,101 @@
 +/*
-+ * linux/drivers/usb/nomadik/musbhdrc.h
++ * linux/drivers/usb/nomadik/musb_host.h
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -195093,310 +198200,454 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbhdrc.h ../new/linux-2.6.20/dri
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+#ifndef __MUSB_HDRC_DEFS_H__
-+#define __MUSB_HDRC_DEFS_H__
++#ifndef _MUSB_HOST_H
++#define _MUSB_HOST_H
 +
-+/*
-+ * HDRC-specific definitions
-+ * $Revision: 1.8 $
-+ */
++extern int mgc_slow_device_kludge_delay;
 +
-+#define MGC_MAX_USB_ENDS       16
++#define SPIN_LOCK_IRQSAVE(l, f) do { spin_lock_irqsave(l, f); if ( mgc_slow_device_kludge_delay) { udelay(mgc_slow_device_kludge_delay*2); } DBG(3, "IRQ DISABLED\n"); } while (0)
++#define SPIN_UNLOCK_IRQRESTORE(l,f) do { DBG(3, "IRQ ENABLED\n"); spin_unlock_irqrestore(l, f); } while (0)
 +
-+#define MGC_END0_FIFOSIZE      64      /* this is non-configurable */
++struct urb;
 +
-+/*
-+ *     MUSBMHDRC Register map 
-+ */
++int mgc_init_root_hub(MGC_LinuxCd *pThis);
++int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd);
++MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb);
 +
-+/* Common USB registers */
++int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
++int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd,
++      struct urb* pUrb);
 +
-+#define MGC_O_HDRC_FADDR      0x00    /* 8-bit */
-+#define MGC_O_HDRC_POWER      0x01    /* 8-bit */
++static inline int mgc_urb_is_periodic(struct urb *pUrb) {
++      return (usb_pipeint(pUrb->pipe) || usb_pipeisoc(pUrb->pipe));
++}
 +
-+#define MGC_O_HDRC_INTRTX     0x02    /* 16-bit */
-+#define MGC_O_HDRC_INTRRX       0x04
-+#define MGC_O_HDRC_INTRTXE      0x06  
-+#define MGC_O_HDRC_INTRRXE      0x08  
-+#define MGC_O_HDRC_INTRUSB      0x0A   /* 8 bit */
-+#define MGC_O_HDRC_INTRUSBE     0x0B   /* 8 bit */
-+#define MGC_O_HDRC_FRAME        0x0C  
-+#define MGC_O_HDRC_INDEX        0x0E   /* 8 bit */
-+#define MGC_O_HDRC_TESTMODE     0x0F   /* 8 bit */
++extern char* decode_urb_protocol(struct urb* pUrb);
 +
-+/* Get offset for a given FIFO */
-+#define MGC_FIFO_OFFSET(_bEnd) (0x20 + (_bEnd * 4))
 +
-+/* Additional Control Registers */
++#ifdef MUSB_USE_HCD_DRIVER
++int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis);
++#endif
 +
-+#define       MGC_O_HDRC_DEVCTL       0x60       /* 8 bit */
++#ifdef MUSB_HOST
++extern int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb);
++extern int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
 +
-+/* These are actually indexed: */
-+#define MGC_O_HDRC_TXFIFOSZ   0x62    /* 8-bit (see masks) */
-+#define MGC_O_HDRC_RXFIFOSZ   0x63    /* 8-bit (see masks) */
-+#define MGC_O_HDRC_TXFIFOADD  0x64    /* 16-bit offset shifted right 3 */
-+#define MGC_O_HDRC_RXFIFOADD  0x66    /* 16-bit offset shifted right 3 */
++#ifdef MUSB_V26
++extern int MGC_LinuxSubmitUrb26(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
++extern int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status);
++#endif
 +
-+#define MGC_O_HDRC_TOPCONTROL 0x204   /* top control register 16-bit */
++#ifdef MUSB_V24
++extern int MGC_LinuxSubmitUrb24(struct urb* pUrb);
++extern int MGC_LinuxUnlinkUrb24(struct urb* pUrb);
++#endif
 +
-+/* offsets to registers in flat model */
-+#define MGC_O_HDRC_TXMAXP     0x00
-+#define MGC_O_HDRC_TXCSR      0x02
-+#define MGC_O_HDRC_CSR0       MGC_O_HDRC_TXCSR        /* re-used for EP0 */
-+#define MGC_O_HDRC_RXMAXP     0x04
-+#define MGC_O_HDRC_RXCSR      0x06
-+#define MGC_O_HDRC_RXCOUNT    0x08
-+#define MGC_O_HDRC_COUNT0     MGC_O_HDRC_RXCOUNT      /* re-used for EP0 */
-+#define MGC_O_HDRC_TXTYPE     0x0A
-+#define MGC_O_HDRC_TYPE0      MGC_O_HDRC_TXTYPE       /* re-used for EP0 */
-+#define MGC_O_HDRC_TXINTERVAL 0x0B
-+#define MGC_O_HDRC_NAKLIMIT0  MGC_O_HDRC_TXINTERVAL   /* re-used for EP0 */
-+#define MGC_O_HDRC_RXTYPE     0x0C
-+#define MGC_O_HDRC_RXINTERVAL 0x0D
-+#define MGC_O_HDRC_FIFOSIZE   0x0F
-+#define MGC_O_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE     /* re-used for EP0 */
++extern void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis);
 +
-+#define MGC_END_OFFSET(_bEnd, _bOffset)       (0x100 + (0x10*_bEnd) + _bOffset)
 +
-+/* "bus control" registers */
-+#define MGC_O_HDRC_TXFUNCADDR 0x00
-+#define MGC_O_HDRC_TXHUBADDR  0x02
-+#define MGC_O_HDRC_TXHUBPORT  0x03
++#else /* host not defined */
 +
-+#define MGC_O_HDRC_RXFUNCADDR 0x04
-+#define MGC_O_HDRC_RXHUBADDR  0x06
-+#define MGC_O_HDRC_RXHUBPORT  0x07
++#ifdef MUSB_V26_POST10
++extern int MGC_LinuxHubSuspend(struct usb_bus *pBus);
++extern int MGC_LinuxHubResume(struct usb_bus *pBus);
++#endif
 +
-+#define MGC_BUSCTL_OFFSET(_bEnd, _bOffset)    (0x80 + (8*_bEnd) + _bOffset)
++inline void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd) {
++      DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd) {
++      DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd) {
++      DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) {
++      DBG(3, "#HOST DISABLED\n");
++}
++
++inline void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis) {
++      DBG(3, "#HOST DISABLED\n");
++}
++#endif
 +
++
++#endif /* _MUSB_HOST_H */
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c
+@@ -0,0 +1,321 @@
 +/*
-+ *     MUSBHDRC Register bit masks
++ * linux/drivers/usb/nomadik/musb_ioctl.c
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
 + */
 +
-+/* POWER */
++#include <asm/uaccess.h>
++#include <linux/kernel.h>
 +
-+#define MGC_M_POWER_ISOUPDATE   0x80 
-+#define       MGC_M_POWER_SOFTCONN    0x40
-+#define       MGC_M_POWER_HSENAB      0x20
-+#define       MGC_M_POWER_HSMODE      0x10
-+#define MGC_M_POWER_RESET       0x08
-+#define MGC_M_POWER_RESUME      0x04
-+#define MGC_M_POWER_SUSPENDM    0x02
-+#define MGC_M_POWER_ENSUSPEND   0x01
++#include <linux/usb.h>
++
++#include "musbdefs.h"
++#include "musb_host.h"
++
++#ifdef MUSB_DEBUG
++extern int mgc_slow_device_kludge_delay;
++#endif
++
++/**
++ * Zap the driver (warm start)
++ * @param pThis the controller
++ */
++void MGC_Zap(MGC_LinuxCd* pThis) {
++
++#ifdef MUSB_PARANOID
++      if ( !pThis ) {
++              ERR("Controller not initialized\n");
++              return;
++      }
++#endif
++
++      MGC_HdrcStop(pThis);
++
++#ifdef MUSB_VIRTHUB
++      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
++      pThis->pRootDevice = NULL;
++      mgc_hcd_flush(pThis);
++#endif
 +
-+/* INTRUSB */
-+#define MGC_M_INTR_SUSPEND    0x01
-+#define MGC_M_INTR_RESUME     0x02
-+#define MGC_M_INTR_RESET      0x04
-+#define MGC_M_INTR_BABBLE     0x04
-+#define MGC_M_INTR_SOF        0x08 
-+#define MGC_M_INTR_CONNECT    0x10
-+#define MGC_M_INTR_DISCONNECT 0x20
-+#define MGC_M_INTR_SESSREQ    0x40
-+#define MGC_M_INTR_VBUSERROR  0x80   /* FOR SESSION END */
-+#define MGC_M_INTR_EP0      0x01  /* FOR EP0 INTERRUPT */
++      WARN("Controller Stopped\n");
 +
-+/* DEVCTL */
-+#define MGC_M_DEVCTL_BDEVICE    0x80   
-+#define MGC_M_DEVCTL_FSDEV      0x40
-+#define MGC_M_DEVCTL_LSDEV      0x20
-+#define MGC_M_DEVCTL_VBUS       0x18
-+#define MGC_S_DEVCTL_VBUS       3
-+#define MGC_M_DEVCTL_HM         0x04
-+#define MGC_M_DEVCTL_HR         0x02
-+#define MGC_M_DEVCTL_SESSION    0x01
 +
-+/* TESTMODE */
++#ifdef MUSB_HOST
++      MGC_InitLocalEndPoints(pThis);
++#endif
 +
-+#define MGC_M_TEST_FORCE_HOST   0x80
-+#define MGC_M_TEST_FIFO_ACCESS  0x40
-+#define MGC_M_TEST_FORCE_FS     0x20
-+#define MGC_M_TEST_FORCE_HS     0x10
-+#define MGC_M_TEST_PACKET       0x08
-+#define MGC_M_TEST_K            0x04
-+#define MGC_M_TEST_J            0x02
-+#define MGC_M_TEST_SE0_NAK      0x01
++#ifdef MUSB_GADGET
 +
-+/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
-+#define MGC_M_FIFOSZ_DPB      0x10
-+/* allocation size (8, 16, 32, ... 4096) */
-+#define MGC_M_FIFOSZ_SIZE     0x0f
++#endif
 +
-+/* CSR0 */
-+#define       MGC_M_CSR0_FLUSHFIFO      0x0100
-+#define MGC_M_CSR0_TXPKTRDY       0x0002
-+#define MGC_M_CSR0_RXPKTRDY       0x0001
++      WAIT_MS(1000);
++      MGC_HdrcStart( pThis );
++      WARN("Controller Restarted\n");
++}
 +
-+/* CSR0 in Peripheral mode */
-+#define MGC_M_CSR0_P_SVDSETUPEND  0x0080
-+#define MGC_M_CSR0_P_SVDRXPKTRDY  0x0040
-+#define MGC_M_CSR0_P_SENDSTALL    0x0020
-+#define MGC_M_CSR0_P_SETUPEND     0x0010
-+#define MGC_M_CSR0_P_DATAEND      0x0008
-+#define MGC_M_CSR0_P_SENTSTALL    0x0004
++/**
++ * Start a session. Depeing on the controller mode (cable end) it will
++ * pwer VBUS/initiate SRP and/or it will behave like a gadget.
++ * @param pThis the controller
++ *
++ */
++void MGC_Session(MGC_LinuxCd* pThis) {
++      uint8_t bReg, sesn=0;
 +
-+/* CSR0 in Host mode */
-+#define MGC_M_CSR0_H_NO_PING    0x0800
-+#define MGC_M_CSR0_H_WR_DATATOGGLE   0x0400   /* set to allow setting: */
-+#define MGC_M_CSR0_H_DATATOGGLE           0x0200      /* data toggle control */
-+#define       MGC_M_CSR0_H_NAKTIMEOUT   0x0080
-+#define MGC_M_CSR0_H_STATUSPKT    0x0040
-+#define MGC_M_CSR0_H_REQPKT       0x0020
-+#define MGC_M_CSR0_H_ERROR        0x0010
-+#define MGC_M_CSR0_H_SETUPPKT     0x0008
-+#define MGC_M_CSR0_H_RXSTALL      0x0004
++#ifdef MUSB_PARANOID
++      if ( !pThis ) {
++              ERR("Controller not initialized\n");
++              return;
++      }
++#endif
 +
-+/* TxType/RxType */
-+#define MGC_M_TYPE_SPEED      0xc0
-+#define MGC_S_TYPE_SPEED      6
-+#define MGC_TYPE_SPEED_HIGH   1
-+#define MGC_TYPE_SPEED_FULL   2
-+#define MGC_TYPE_SPEED_LOW    3
-+#define MGC_M_TYPE_PROTO      0x30
-+#define MGC_S_TYPE_PROTO      4
-+#define MGC_M_TYPE_REMOTE_END 0xf
++      if ( MUSB_IS_ERR(pThis) ) {
++              WARN("Error mode, zap the driver first\n");
++      }
 +
-+/* CONFIGDATA */
 +
-+#define MGC_M_CONFIGDATA_MPRXE      0x80      /* auto bulk pkt combining */
-+#define MGC_M_CONFIGDATA_MPTXE      0x40      /* auto bulk pkt splitting */
-+#define MGC_M_CONFIGDATA_BIGENDIAN  0x20
-+#define MGC_M_CONFIGDATA_HBRXE      0x10      /* HB-ISO for RX */
-+#define MGC_M_CONFIGDATA_HBTXE      0x08      /* HB-ISO for TX */
-+#define MGC_M_CONFIGDATA_DYNFIFO    0x04      /* dynamic FIFO sizing */
-+#define MGC_M_CONFIGDATA_SOFTCONE   0x02      /* SoftConnect */
-+#define MGC_M_CONFIGDATA_UTMIDW     0x01   /* data width 0 => 8bits, 1 => 16bits */
++      if ( sesn ) {
++              ERR("A %s session is active; terminate it first\n",
++                      MUSB_MODE(pThis));
++              return;
++      }
 +
-+/* TXCSR in Peripheral and Host mode */
 +
-+#define MGC_M_TXCSR_AUTOSET       0x8000
-+#define MGC_M_TXCSR_ISO           0x4000
-+#define MGC_M_TXCSR_MODE          0x2000
-+#define MGC_M_TXCSR_DMAENAB       0x1000
-+#define MGC_M_TXCSR_FRCDATATOG    0x0800
-+#define MGC_M_TXCSR_DMAMODE       0x0400
-+#define MGC_M_TXCSR_CLRDATATOG    0x0040
-+#define MGC_M_TXCSR_FLUSHFIFO     0x0008
-+#define MGC_M_TXCSR_FIFONOTEMPTY  0x0002
-+#define MGC_M_TXCSR_TXPKTRDY      0x0001
++      /* WHY!?!?! this looks like a race condition to me */
++      bReg = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL);
++      MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, bReg | MGC_M_DEVCTL_SESSION);
++}
 +
-+/* TXCSR in Peripheral mode */
 +
-+#define MGC_M_TXCSR_P_INCOMPTX    0x0080
-+#define MGC_M_TXCSR_P_SENTSTALL   0x0020
-+#define MGC_M_TXCSR_P_SENDSTALL   0x0010
-+#define MGC_M_TXCSR_P_UNDERRUN    0x0004
++/**
++ * Change the debug level.
++ * @param level the new level
++ */
++void MGC_SetDebugLevel(int level) {
++#if MUSB_DEBUG > 0
++      MGC_DebugLevel=level;
++      INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel);
++#endif
++}
 +
-+/* TXCSR in Host mode */
++/**
++ * Change the slow device delay.
++ * @param delay the new delay
++ */
++int MGC_SetDeviceDelay(int delay) {
++      if ( delay>0 ) {
++              mgc_slow_device_kludge_delay=delay;
++      }
++      return mgc_slow_device_kludge_delay;
++}
 +
-+#define MGC_M_TXCSR_H_WR_DATATOGGLE   0x0200
-+#define MGC_M_TXCSR_H_DATATOGGLE      0x0100
-+#define MGC_M_TXCSR_H_NAKTIMEOUT  0x0080
-+#define MGC_M_TXCSR_H_RXSTALL     0x0020
-+#define MGC_M_TXCSR_H_ERROR       0x0004
++/** Dump the current status and compile options.
++ * @param pThis the device driver instance
++ * @param buffer where to dump the status; it must be big enough hold the
++ * result otherwise "BAD THINGS HAPPENS(TM)".
++ */
++int dump_header_stats(MGC_LinuxCd* pThis, char *buffer) {
++    int code, count=0;
++    const uint8_t* pBase=pThis->pRegs;
 +
-+/* RXCSR in Peripheral and Host mode */
++    *buffer=0;
 +
-+#define MGC_M_RXCSR_AUTOCLEAR     0x8000
-+#define MGC_M_RXCSR_DMAENAB       0x2000
-+#define MGC_M_RXCSR_DISNYET       0x1000
-+#define MGC_M_RXCSR_DMAMODE       0x0800
-+#define MGC_M_RXCSR_INCOMPRX      0x0100
-+#define MGC_M_RXCSR_CLRDATATOG    0x0080
-+#define MGC_M_RXCSR_FLUSHFIFO     0x0010
-+#define MGC_M_RXCSR_DATAERROR     0x0008
-+#define MGC_M_RXCSR_FIFOFULL      0x0002
-+#define MGC_M_RXCSR_RXPKTRDY      0x0001
++      code=sprintf(&buffer[count],
++              "Compile Options: [debug=%d][dma=%s][gadget=%s][otg=%s][eps=%d]\n",
++#if MUSB_DEBUG>0
++          MGC_DebugLevel
++#else
++              -1
++#endif
++      ,
++#ifdef MUSB_DMA
++              "yes"
++#else
++              "no"
++#endif
++      ,
++#ifdef MUSB_GADGET
++              "yes"
++#else
++              "no"
++#endif
++      ,
++#ifdef MUSB_OTG
++              "yes"
++#else
++              "no"
++#endif
++      ,pThis->bEndCount);
++      if ( code<0 ) {
++              ERR("A problem generating the report\n");
++              return count;
++      } else {
++              count+=code;
++      }
 +
-+/* RXCSR in Peripheral mode */
++    code=sprintf(&buffer[count],
++              "Current Status: %sDRC, Mode=%s (%s=%d) (Power=%02x, DevCtl=%02x)\n",
++              ( pThis->bIsMultipoint ? "MH" : "H"),
++              MUSB_MODE(pThis),
++#ifdef MUSB_GADGET
++              "address",
++              (MUSB_IS_DEV(pThis)?pThis->bAddress:0,
++#else
++              "delay",
++              mgc_slow_device_kludge_delay,
++#endif
++              MGC_Read8(pBase, MGC_O_HDRC_POWER),
++              MGC_Read8(pBase, MGC_O_HDRC_DEVCTL));
++    if ( code<0 ) {
++              ERR("A problem generating the report\n");
++              return count;
++      } else {
++              count+=code;
++      }
 +
-+#define MGC_M_RXCSR_P_ISO         0x4000
-+#define MGC_M_RXCSR_P_SENTSTALL   0x0040
-+#define MGC_M_RXCSR_P_SENDSTALL   0x0020
-+#define MGC_M_RXCSR_P_OVERRUN     0x0004
++#ifdef MUSB_USE_HCD_DRIVER
++      {
++              int i=0;
++              mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
 +
-+/* RXCSR in Host mode */
++              code=sprintf(&buffer[count],
++                      "HCD: urb_queue_count=%d urb_exec_count=%d\n",
++                      pQueue->urb_queue_count, pQueue->urb_exec_count);
++              if ( code<0 ) {
++                      ERR("A problem generating the report\n");
++                      return count;
++              } else {
++                      count+=code;
++              }
 +
-+#define MGC_M_RXCSR_H_AUTOREQ     0x4000
-+#define MGC_M_RXCSR_H_WR_DATATOGGLE   0x0400
-+#define MGC_M_RXCSR_H_DATATOGGLE        0x0200
-+#define MGC_M_RXCSR_H_RXSTALL     0x0040
-+#define MGC_M_RXCSR_H_REQPKT      0x0020
-+#define MGC_M_RXCSR_H_ERROR       0x0004
++              for (i=0; i<pThis->bEndCount; i++) {
++                      if ( !mgc_ep_is_idle( &pThis->aLocalEnd[i] ) ) {
++                              code=sprintf(&buffer[count], "ep%d, current=%p\n",
++                                      i, MGC_GetCurrentUrb(&pThis->aLocalEnd[i]));
++                              if ( code<0 ) {
++                                      ERR("A problem generating the report\n");
++                                      return count;
++                              } else {
++                                      count+=code;
++                              }
++                      }
++              }
++      }
++#endif
 +
-+/* HUBADDR */
-+#define MGC_M_HUBADDR_MULTI_TT                0x80
++      return count;
++}
 +
 +
-+/* TXCSR in Peripheral and Host mode */
++/**
++ * decode (convert to a name) the protocol used on an endpoint.
++ * @param pThis the controller
++ * @param bEnd the endpoint
++ */
++static char* decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
++    char* pProto = "Err ";
 +
-+#define MGC_M_TXCSR2_AUTOSET       0x80
-+#define MGC_M_TXCSR2_ISO           0x40
-+#define MGC_M_TXCSR2_MODE          0x20
-+#define MGC_M_TXCSR2_DMAENAB       0x10
-+#define MGC_M_TXCSR2_FRCDATATOG    0x08
-+#define MGC_M_TXCSR2_DMAMODE       0x04
++      if ( MUSB_IS_DEV(pThis) ) {
++#ifdef MUSB_GAGDET
++              pProto=decode_dev_ep_protocol(pThis, bEnd);
++#endif
++      } else if ( MUSB_IS_HST(pThis) ) {
++#ifdef MUSB_HOST
++              pProto=decode_hst_ep_protocol(pThis, bEnd);
++#endif
++      }
 +
-+#define MGC_M_TXCSR1_CLRDATATOG    0x40
-+#define MGC_M_TXCSR1_FLUSHFIFO     0x08
-+#define MGC_M_TXCSR1_FIFONOTEMPTY  0x02
-+#define MGC_M_TXCSR1_TXPKTRDY      0x01
++      return pProto;
++}
 +
-+/* TXCSR in Peripheral mode */
++#ifdef MUSB_HOST
 +
-+#define MGC_M_TXCSR1_P_INCOMPTX    0x80
-+#define MGC_M_TXCSR1_P_SENTSTALL   0x20
-+#define MGC_M_TXCSR1_P_SENDSTALL   0x10
-+#define MGC_M_TXCSR1_P_UNDERRUN    0x04
++/**
++ * Dump statistics for a local end (driver operaiting in host mode).
++ * @param pThis the device driver instance
++ * @param bEnd
++ * @param aBuffer the buffer to print the report to
++ */
++int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer) {
++      int code, count=0;
++      MGC_LinuxLocalEnd* pEnd=&pThis->aLocalEnd[bEnd];
 +
-+/* TXCSR in Host mode */
++      spin_lock(&pEnd->Lock);
 +
-+#define MGC_M_TXCSR1_H_NAKTIMEOUT  0x80
-+#define MGC_M_TXCSR1_H_RXSTALL     0x20
-+#define MGC_M_TXCSR1_H_ERROR       0x04
++      do {
 +
-+/* RXCSR in Peripheral and Host mode */
++              if ( mgc_ep_is_idle(pEnd) ) {
++                      code=snprintf(aBuffer, 256-count,
++                              "End-%01x: Idle (%s, proto=%s, pktsize=%04x, address=%02x, end=%02x\n",
++                              bEnd, ( pEnd->bIsTx ? "Tx" : "Rx" ), decode_protocol(pThis, bEnd),
++                              pEnd->wPacketSize, pEnd->bRemoteAddress, pEnd->bRemoteEnd);
++              } else {
++                      code=snprintf(aBuffer, 256-count,
++                              "End-%01x: %s (urb=%p), %s, proto=%s, pkt size=%04x, address=%02x, end=%02x\n",
++                              bEnd, "Busy", MGC_GetCurrentUrb(pEnd),
++                              ( pEnd->bIsTx ? "Tx" : "Rx" ),
++                              decode_protocol(pThis, bEnd),
++                              pEnd->wPacketSize,
++                              pEnd->bRemoteAddress,
++                              pEnd->bRemoteEnd);
++              }
 +
-+#define MGC_M_RXCSR2_AUTOCLEAR     0x80
-+#define MGC_M_RXCSR2_DMAENAB       0x20
-+#define MGC_M_RXCSR2_DISNYET       0x10
-+#define MGC_M_RXCSR2_DMAMODE       0x08
-+#define MGC_M_RXCSR2_INCOMPRX      0x01
++              if ( code<0 ) {
++                      break;
++              } else {
++                      count+=code;
++              }
 +
-+#define MGC_M_RXCSR1_CLRDATATOG    0x80
-+#define MGC_M_RXCSR1_FLUSHFIFO     0x10
-+#define MGC_M_RXCSR1_DATAERROR     0x08
-+#define MGC_M_RXCSR1_FIFOFULL      0x02
-+#define MGC_M_RXCSR1_RXPKTRDY      0x01
++              if ( MUSB_IS_HST(pThis) ) {
++                      code = snprintf(&aBuffer[count], 256-count,
++                              "  %10ld bytes Rx in %10ld pkts; %10ld errs, %10ld overruns\n",
++                              pEnd->dwTotalRxBytes,
++                              pEnd->dwTotalRxPackets,
++                              pEnd->dwErrorRxPackets,
++                              pEnd->dwMissedRxPackets);
++                      if ( code<0 ) {
++                              break;
++                      } else {
++                              count+=code;
++                      }
 +
-+/* RXCSR in Peripheral mode */
++                      code=snprintf(&aBuffer[count], 256-count,
++                              "  %10ld bytes Tx in %10ld pkts; %10ld errs, %10ld underruns\n",
++                              pEnd->dwTotalTxBytes,
++                              pEnd->dwTotalTxPackets,
++                              pEnd->dwErrorTxPackets,
++                              pEnd->dwMissedTxPackets);
++                      if ( code<0 ) {
++                              break;
++                      } else {
++                              count+=code;
++                      }
++              } else {
++                      /* no stats for gadget, yet! */
++              }
++      } while(0);
 +
-+#define MGC_M_RXCSR2_P_ISO         0x40
-+#define MGC_M_RXCSR1_P_SENTSTALL   0x40
-+#define MGC_M_RXCSR1_P_SENDSTALL   0x20
-+#define MGC_M_RXCSR1_P_OVERRUN     0x04
++      spin_unlock(&pEnd->Lock);
++      if ( code<0 ) {
++              ERR("An error generating the report");
++              return code;
++      }
 +
-+/* RXCSR in Host mode */
++      return count;
++}
++#endif
 +
-+#define MGC_M_RXCSR2_H_AUTOREQ     0x40
-+#define MGC_M_RXCSR1_H_RXSTALL     0x40
-+#define MGC_M_RXCSR1_H_REQPKT      0x20
-+#define MGC_M_RXCSR1_H_ERROR       0x04
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h
+@@ -0,0 +1,32 @@
++/*
++ * linux/drivers/usb/nomadik/musb_ioctl.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ */
 +
-+/* Top control register */
-+#define MGC_M_TOPCTRL_MODE_ULPI          0x09
-+#define MGC_M_TOPCTRL_MODE_SRST    0x04
++#include "musbdefs.h"
 +
-+#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.c
---- linux-2.6.20/drivers/usb/nomadik/musb_host.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.c        2008-08-08 19:15:25.000000000 +0530
-@@ -0,0 +1,2791 @@
++void MGC_Zap(MGC_LinuxCd* pThis);
++void MGC_Session(MGC_LinuxCd* pThis);
++void MGC_SetDebugLevel(int level);
++int MGC_SetDeviceDelay(int delay);
++int dump_header_stats(MGC_LinuxCd* pThis, char *buffer);
++char*decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
++#ifdef MUSB_HOST
++int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
++#endif
++
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c
+@@ -0,0 +1,2306 @@
 +/*
-+ * linux/drivers/usb/nomadik/musb_host.c
++ * linux/drivers/usb/nomadik/musb_plat_uds.c
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -195412,7 +198663,80 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/dr
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++/*
++ * Introduction.
++ * The ICD works like the other Linux HCDs/Gadgets: it is threadless,
++ * so it does everything either in response to an interrupt,
++ * or during a call from an upper layer.
++ * It implements a virtual root hub, so as to make uniform use
++ * of the Linux hub driver.Linux
++
++ *
++ * The Linux (host-side) USB core has no concept of binding (the authors
++ * apparently missed the point of the pipe discussion in the USB spec).
++ * Instead, class drivers simply submit URBs, and an HCD may reject
++ * or defer them if sufficient resources are not available.
++ * This means class drivers have no way to know if their requirements
++ * can possibly be fulfilled, and may be blocked indefinitely by others,
++ * without the end-user knowing why.
++ * Therefore, whether things will work depends on the order of URB submissions
++ * (which is dictated by the order of device insertion and/or driver loading
++ * and thread scheduling).
++ *
++ * The URB encodes pipe information in an integer,
++ * requiring table searches (hurting performance).
++ *
++ * For the HDRC, local endpoint 0 is the only choice for control traffic,
++ * so it is reprogrammed as needed, and locked during transfers.
++ * Bulk transfers are queued to the available local endpoint with
++ * the smallest possible FIFO in the given direction
++ * that will accomodate the transactions.
++ *
++ * A typical response to the completion of a periodic URB is immediate
++ * submission of another one, so the HCD does not assume it can reprogram
++ * a local periodic-targetted endpoint for another purpose.
++ * Instead, submission of a periodic URB is taken as a permanent situation,
++ * so that endpoint is untouched.
++ * One could imagine reprogramming periodic endpoints for other uses
++ * between their polling intervals, effectively interleaving traffic on them.
++ * Unfortunately, this assumes no device would ever NAK periodic tokens.
++ * This is because the core no notification to software when an attempted
++ * periodic transaction is NAKed (its NAKlimit feature is only for
++ * control/bulk).
++ */
++
++/*
++ * Optional macros:
++ *
++ * MUSB_FLAT_REG      if defined, use the core's flag register model
++ *
++ * MUSB_DEBUG         0 => absolutely no diagnostics
++ *                    1 => minimal diagnostics (basic operational states)
++ *                    2 => 1 + detailed debugging of interface with USB core
++ *                    3 => 2 + internal debugging (e.g. every register write)
++ *                    4 => 3 + shared-IRQ-related checking
++ *
++ * MUSB_DMA           if defined, include DMA support.
++ *                    The DMA code to use is included below,
++ *                    so may need to be edited if a non-Inventra DMA
++ *                    controller is used with the Inventra core.
++ *
++ * MUSB_AHB_ID                if defined, the core's identity is read from offset 0x400
++ *                    to verify that the expected core is present
++ *
++ * MUSB_CONFIG_PROC_FS        enables statistics/state info in /proc/musbhdrc<n>
++ *                    where 0 <= n < number of instances of driver
++ *
++ *
++ * MUSB_HARD_IRQ try SA_INTERRUPT first when acquiring the irq (fallback to
++ *                             SA_SHIRQ when that fails.
++ *
++ *
++ * Options taken from linux/config.h:
++ * CONFIG_PM          enables power-management
 + */
 +
 +#include <linux/module.h>
@@ -195420,7 +198744,6 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/dr
 +#include <linux/delay.h>
 +#include <linux/sched.h>
 +#include <linux/slab.h>
-+#include <linux/errno.h>
 +#include <linux/init.h>
 +#include <linux/list.h>
 +#include <linux/usb.h>
@@ -195428,2875 +198751,2212 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/dr
 +#include <asm/uaccess.h>
 +
 +#ifdef CONFIG_USB_DEBUG
-+    #define DEBUG 
++#define DEBUG
 +#else
-+    #undef DEBUG
++#undef DEBUG
 +#endif
 +
-+#include <linux/usb.h>
 +
 +#include "musbdefs.h"
 +#include "musb_host.h"
-+#include "../core/hub.h"
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+#define HAS_USB_TT_MULTI
 +#include "../core/hcd.h"
-+#endif
++#include <asm/arch/gpio.h>
++#include <asm/arch/i2c.h>
++/********************** RETURN TYPES FOR IRQ ********************************/
 +
-+/** how much to "scale" response timeouts */
-+#define MUSB_MAX_RETRIES         8
++#ifdef MUSB_V26
++#define RETURN_IRQ_HANDLED return(IRQ_HANDLED)
++#define RETURN_IRQ_NONE return(IRQ_NONE)
++#endif
 +
-+/*************************** Forwards ***************************/
++#ifdef MUSB_V24
++typedef void irqreturn_t;
++#define RETURN_IRQ_HANDLED return
++#define RETURN_IRQ_NONE return
++#endif
 +
-+/* HCD helpers */
-+static uint8_t find_first1(unsigned int nValue);
-+static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
-+static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd);
-+static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis);
-+int *Urb_test;
-+extern int Urb_status;
-+/**************************************************************************
-+ * 
-+ **************************************************************************/
 +
-+#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY 0
++/* define this on command line */
++#ifndef MUSB_DEFAULT_IRQTYPE
++#define MUSB_DEFAULT_IRQTYPE  SA_SHIRQ
 +#endif
 +
-+#ifndef MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_MIN 0
-+#endif
++/****************************** CONSTANTS ********************************/
 +
-+#ifndef DEBUG
++#define DRIVER_AUTHOR "STMicroelectronics"
++#define DRIVER_DESC "Nomadik USB Driver"
++
++#ifndef MUSB_VERSION
++#define MUSB_VERSION "x.x"
 +#endif
 +
-+int mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY;
++#define DRIVER_INFO DRIVER_DESC "v" MUSB_VERSION
++#define DRIVER_NAME "HCD_NAME"
 +
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE {  } 
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE {  }
-+#define MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP {  }
++static const char longname[] = DRIVER_INFO;
++static const char shortname[] = DRIVER_NAME;
 +
-+/**************************************************************************
-+ * Glue for virtual root hub
-+**************************************************************************/
++/* this module is always GPL, the gadget might not... */
++MODULE_DESCRIPTION (DRIVER_INFO);
++MODULE_AUTHOR (DRIVER_AUTHOR);
++MODULE_LICENSE ("GPL");
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+/**
-+ * Decode an host endpoint protocol.
-+ * @param pUrn the uRb protocol shoudl be decoded
-+ * @return a const char* to the name of the protocol.
-+ */
-+char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
-+    char* pProto = "Err ";
-+      
-+      switch(pThis->aLocalEnd[bEnd].bTrafficType) {
-+              case PIPE_ISOCHRONOUS: pProto = "Isoc"; break;
-+              case PIPE_INTERRUPT: pProto = "Intr"; break;
-+              case PIPE_CONTROL: pProto = "Ctrl"; break;
-+              case PIPE_BULK: pProto = "Bulk"; break;
-+      }
-+      
-+      return pProto;
-+}
-+#endif
++/* time (millseconds) to wait before a restart */
++#define MUSB_RESTART_TIME       5000
++/* how many babbles to allow before giving up */
++#define MUSB_MAX_BABBLE_COUNT 10
++/* how many buss errors before stopping the operations */
++#define MUSB_MAX_VBUS_ERRORS  3
 +
-+/**
-+ * Decode an urb protocol.
-+ * @param pUrn the uRb protocol shoudl be decoded
-+ * @return a const char* to the name of the protocol.
-+ */
-+char* decode_urb_protocol(struct urb* pUrb) {
-+      static char buffer[8];
-+    
-+      if ( !pUrb ) {
-+              strcpy(&buffer[0], "NULL");
-+              return buffer;
-+      }
-+      
-+      buffer[0]=usb_pipein(pUrb->pipe)?'I':'O';
-+      if ( usb_pipeint(pUrb->pipe) ) {
-+              strcpy(&buffer[1], " int");
-+      } else if ( usb_pipeisoc(pUrb->pipe) ) {
-+              strcpy(&buffer[1], " isoc");            
-+      } else if ( usb_pipebulk(pUrb->pipe) ) {
-+              strcpy(&buffer[1], " bulk");            
-+      } else if ( usb_pipecontrol(pUrb->pipe) ) {
-+              strcpy(&buffer[0], " ctl");             
-+      }
-+       
-+      return buffer; 
-+}
++/* WEIRD KLUDGE! */
++#define IS_INVALID_ADDRESS(_x) (((unsigned long)_x)<(unsigned long)1024)
 +
-+/* Root speed need to be translated (addapted)
-+ */
-+static uint8_t MGC_TranslateVirtualHubSpeed(uint8_t source) {
-+    uint8_t speed=2;
-+    
-+    switch ( source ) {
-+      case 3: speed=0; break;
-+      case 2: speed=1; break;
-+    }
++#define A_IDLE          1
++#define B_IDLE          2
++#define PERIPHERAL      3
++#define HOST            4
 +
-+    return speed;
-+}
++#define MAJOR_NUMBER_OTG        0x0
++#define OTG_DEEP_SLEEP          0x1
++#define OTG_WAKEUP              0x2
++#define SRP_TEST                0x3
++#define HNP_TEST                0x4
++#define PRINT_REG               0x5
++#define HOST_A_IDLE             0x6
++#define OTG_SUSPEND             0x7
++#define OTG_RESUME              0x8
 +
-+/**
-+ * Timer completion callback to turn off reset and get connection speed
-+ */
-+static void MGC_HdrcResetOff(unsigned long param)
-+{
-+    uint8_t power;
-+    MGC_LinuxCd* pThis = (MGC_LinuxCd*)param;
-+    void* pBase = pThis->pRegs;
-+    unsigned long flags;
-+    
-+    DBG(2, "<== Stopping root port reset...\n");
-+      
-+    SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);   
-+    pThis->bIgnoreDisconnect = FALSE;    
-+    power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+    MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
++#define SUSPEND                 0x0
++#define RESUME                  0x1
 +
-+    /* check for high-speed and set in root device if so */
-+    power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+    if(power & MGC_M_POWER_HSMODE) {
-+              DBG(3, "high-speed device connected\n");
-+              pThis->bRootSpeed = 1;
-+    }
 +
++/******************************* FORWARDS ********************************/
++MGC_LinuxCd *udc_address;
++struct usb_hcd *hcd1;
++int udcinitmonitorflag_isr=0,udcinitmonitorflag_init=0;
++extern void driver_change_mode_handler(uint8_t role);
++void otg_disconnect(MGC_LinuxCd *pThis);
++int dev_safe_remove=0;
++extern int Urb_status;
++struct urb *Urb_struct;
++uint8_t temp;
++uint8_t b_hnp_suspend=0;
++uint8_t b_hnp_init=0;
++void  del_timer_func(void);
++extern int udc_setup(void);
++extern void  udc_reset(void);
++extern void udc_resume(void);
++extern void udc_suspend(void);
++extern void  udc_intr_disable(void);
++extern uint8_t host_a_idle;
++static void funct_host_notify_timer(unsigned long pThis);
++static struct timer_list notify_timer;
++extern int nomadik_udc_init(MGC_LinuxCd *pThis);
++extern void musb_reset_isr(void);
++extern void udc_disconnect_isr(void);
++extern uint8_t udc_ep0_irq(void);
++extern void udc_ep_tx_irq(uint8_t bEnd) ;
++extern void udc_ep_rx_irq(uint8_t bEnd) ;
++
++#ifndef MUSB_USE_HCD_DRIVER
 +#ifdef MUSB_VIRTHUB
-+    MGC_VirtualHubPortResetDone(&(pThis->RootHub), 0, 
-+    MGC_TranslateVirtualHubSpeed(pThis->bRootSpeed));
++#ifndef MUSB_V26_POST10
++/* Linux USBD glue */
++STATIC int mgc_linux_alloc_device(struct usb_device* pDevice);
++STATIC int mgc_linux_free_device(struct usb_device* pDevice);
++#endif
++STATIC int MGC_LinuxGetFrameNumber(struct usb_device* pDevice);
++#endif
 +#endif
 +
-+      DBG(2, "==>\n");
-+    SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+}
++STATIC void mgc_reset(MGC_LinuxCd* pThis);
++uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData);
++/* Interrupt service routine */
++#ifndef MUSB_USE_HCD_DRIVER
++STATIC irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r);
++#endif
 +
-+/* see virthub.h */
-+void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
-+    uint8_t bPower)
-+{
-+    DBG(2, "<==\n");
-+    if(bPower) {
-+        DBG(3, "Root port power on\n");
-+              MGC_HdrcStart((MGC_LinuxCd*)pPrivateData);
-+    } else {
-+        DBG(3, "Root port power off\n");
-+              MGC_HdrcStop((MGC_LinuxCd*)pPrivateData);
-+    }
-+    DBG(2, "==>\n");
-+}
++#ifdef MUSB_USE_HCD_DRIVER
++void mgc_hcd_flush(MGC_LinuxCd* pThis);
++#endif
 +
-+/* see virthub.h */
-+void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
-+    uint8_t bEnable)
-+{    
-+    DBG(2, "<==\n");
-+    if (bEnable) {
-+              DBG(3, "Root port power enabled\n");
-+    } else {
-+      DBG(3, "Root port power disabled\n");
-+    }
-+      
-+    DBG(2, "==>\n");
-+}
++/* HDRC functions */
++STATIC void MGC_HdrcDropResume(unsigned long pParam);
++STATIC void MGC_HdrcRestart(unsigned long pParam);
 +
-+/* see virthub.h */
-+void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
-+      uint8_t bSuspend)
-+{
-+    uint8_t power;
-+    MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
-+    void* pBase = pThis->pRegs;
++STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis);
 +
-+    DBG(2, "<==\n");    
++#ifdef MUSB_V26
++void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
++      unsigned iMemFlags, dma_addr_t* pDmaAddress);
++void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
++      void* address, dma_addr_t DmaAddress);
++#endif
 +
-+    power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+    if(bSuspend) {
-+        DBG(3, "Root port power suspended\n");
-+              MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
-+    } else if(power & MGC_M_POWER_SUSPENDM) {
-+        DBG(3, "Root port power resumed\n");
-+              power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME);
-+              MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
-+              WAIT_MS(20);
-+              MGC_Write8(pBase, MGC_O_HDRC_POWER, power);
-+    }
-+    
-+      DBG(2, "==>\n");
-+}
++STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis);
 +
-+/* see virthub.h */
-+void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
-+      uint8_t bReset)
-+{
-+    uint8_t power;
-+    MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
-+    void* pBase = pThis->pRegs;
-+    
-+    DBG(2, "<==\n");
++#ifdef MUSB_V26_POST10
++struct usb_bus;
++int MGC_LinuxHubSuspend(struct usb_bus *pBus);
++int MGC_LinuxHubResume(struct usb_bus *pBus);
++#endif
 +
-+    power = MGC_Read8(pBase, MGC_O_HDRC_POWER) & 0xf0;
-+    if (bReset) {
-+              pThis->bIgnoreDisconnect = TRUE;
-+              MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESET);
-+              MGC_LinuxSetTimer(pThis, MGC_HdrcResetOff, (unsigned long)pThis, 60);
-+    } else if(power & MGC_M_POWER_RESET) {
-+        DBG(3, "root port reset stopped\n");
-+              MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESET);
-+    }
++#ifdef MUSB_V26
++void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress);
++#endif
 +
-+      DBG(2, "==>\n");
-+}
 +
-+/**************************************************************************
-+ * 
-+ **************************************************************************/
++/******************************* GLOBALS *********************************/
 +
-+ /**
-+ * return the current urb for a given endpoint. Caller is responsible for 
-+ * locking
-+ * @param pEnd the end point (pEnd!=NULL)
-+ * @return the urb or NULL when the end point is idle
-+ */
-+struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd) {      
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      return pEnd->pCurrentUrb;
-+#else
-+    DBG(8 ,"GetCurrentUrb urb_list_ptr:0x%p \n",&(pEnd->urb_list));
-+    DBG(8 ,"GetCurrentUrb urb_list->next:0x%p \n",pEnd->urb_list.next);
-+    DBG(8 ,"GetCurrentUrb urb_list->prev:0x%p \n",pEnd->urb_list.prev);                   
-+    return list_empty(&(pEnd->urb_list)) ? NULL 
-+              : list_entry(pEnd->urb_list.next, struct urb, urb_list);
-+#endif                
-+}
 +
-+/**
-+ * Test whether a local endpoint is idle.
-+ * @param pEnd the endpoint
-+ * @return !=0 when idle, 0 otherwise 
-+ */
-+int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd)
++MGC_LinuxCd *hcd_to_musbstruct(void *ptr)
 +{
 +#ifdef MUSB_USE_HCD_DRIVER
-+      return (pEnd->pCurrentUrb)==NULL;
++      return (MGC_LinuxCd*)((struct usb_hcd *)ptr)->hcd_priv;
 +#else
-+      return list_empty(&pEnd->urb_list);
-+#endif        
++      return (MGC_LinuxCd*)ptr;
++#endif
 +}
 +
-+
-+void mgc_ep_idle(MGC_LinuxLocalEnd* pEnd) {
++struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis)
++{
 +#ifdef MUSB_USE_HCD_DRIVER
-+      pEnd->pCurrentUrb=NULL;
++      return container_of((void*)pThis, struct usb_hcd, hcd_priv);
 +#else
-+      INIT_LIST_HEAD(&(pEnd->urb_list));
-+#endif                
++      return NULL;
++#endif
 +}
 +
++/******************************* GLOBALS *********************************/
++
++unsigned int MGC_nIndex = 0;
++
++static const char MGC_HcdName [] = "musb-hcd";
 +
++#ifndef MUSB_USE_HCD_DRIVER
 +/**
-+ * Dequeue an urb from an endpoint.
-+ * @param pEnd the endpoint
-+ * @param pUrb the urb to be removed
++ * Virtual hub functions: Linux USBD calls these
 + */
-+static int mgc_ep_dequeue_urb(MGC_LinuxLocalEnd* pEnd, struct urb *pUrb,MGC_LinuxCd* pThis) 
++#ifdef MUSB_VIRTHUB
++static struct usb_operations MGC_LinuxOperations =
 +{
-+      int rc=0;
++#ifndef MUSB_V26_POST10
++      .allocate       =               mgc_linux_alloc_device,
++      .deallocate =           mgc_linux_free_device,
++#endif
 +
-+#ifdef MUSB_USE_HCD_DRIVER
-+      if ( pEnd->pCurrentUrb==pUrb ) {
-+              pUrb->hcpriv=NULL;
-+              pEnd->pCurrentUrb=NULL;         
-+      } else {
-+              rc=-EINVAL;
-+              ERR("*** Trying to dequeue pUrb=%p from ep%d while pEnd->pCurrentUrb=%p\n",             
-+                      pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
-+      }
-+#else
-+      pUrb->hcpriv=NULL;
-+      list_del_init(&pUrb->urb_list);
++      .get_frame_number =     MGC_LinuxGetFrameNumber,
++
++#ifdef MUSB_V24
++      .submit_urb =           MGC_LinuxSubmitUrb24,
 +#endif
 +
-+      /* clear endpoint status (preserving the softstate for find_end() ) */
-+      mgc_ep_linux_clear(pEnd,pThis);
++#ifdef MUSB_V26
++      .submit_urb =           MGC_LinuxSubmitUrb26,
++#endif
 +
-+      DBG(1, "==> dequeued pUrb=%p from pEnd->bEnd=%d rc=%d\n", 
-+              pUrb, pEnd->bEnd, rc);
-+      return rc=0;
-+}                             
++#ifdef MUSB_V24
++      .unlink_urb =           MGC_LinuxUnlinkUrb24,
++#endif
++#ifdef MUSB_V26
++      .unlink_urb =           MGC_LinuxUnlinkUrb26,
++#endif
 +
-+/**
-+ * @return 0 success, != when the ep is busy with another request
-+ */
-+static int mgc_ep_enqueue_urb(MGC_LinuxLocalEnd* pEnd, struct urb* pUrb) 
++#ifdef MUSB_V26
++      .buffer_alloc =         MGC_LinuxBufferAlloc,
++      .buffer_free =          MGC_LinuxBufferFree,
++      .disable =                      mgc_linux_disable,
++#endif
++
++#ifdef MUSB_V26_POST10
++      .hub_suspend =          MGC_LinuxHubSuspend,
++      .hub_resume =           MGC_LinuxHubResume,
++#endif
++};
++#endif
++#endif
++
++const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE] = {
++    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++    0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
++    0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
++    0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf,
++    0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf,
++    0xef, 0xf7, 0xfb, 0xfd, 0x7e
++};
++
++
++
++int  otg_ioctl                          (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++int  otg_open                           (struct inode *inode, struct file *file);
++int  otg_close                          (struct inode *inode, struct file *file);
++extern void  otg_deep_sleep(void);
++extern void  otg_wakeup(void);
++extern void set_host_a_idle(void);
++extern void hnp_initiate(void);
++extern void srp_initiate(void);
++
++static struct file_operations otg_fops = {
++        owner:                 THIS_MODULE,
++        read:                  NULL,
++        write:                 NULL,
++        ioctl:                 otg_ioctl,
++        open:                  otg_open,
++        flush:                 NULL,
++        release:               otg_close,
++};
++
++
++/******************************* GLOBALS *********************************/
++
++int otg_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
 +{
-+      int rc=0;
-+      
-+#ifdef MUSB_USE_HCD_DRIVER
-+      if ( pEnd->pCurrentUrb ) {
-+              ERR("*** urb=%p, ep=%d wile busy with urb=%p, this is BAD (tm)\n",
-+                      pUrb, pEnd->bEnd, pEnd->pCurrentUrb);
-+              rc=-EBUSY;
-+      } else {
-+              pEnd->pCurrentUrb=pUrb;
++      /* to prevent compiler warnings */
++      inode=inode;
++      filp=filp;
++      arg=arg;
++
++      switch(cmd) {
++
++      case OTG_DEEP_SLEEP:
++              del_timer(&notify_timer);
++              otg_deep_sleep();
++              break ;
++
++      case OTG_WAKEUP:
++              otg_wakeup();
++              break ;
++
++      case HOST_A_IDLE:
++              set_host_a_idle ();
++              break;
++
++      case SRP_TEST:
++              srp_initiate();
++              break ;
++
++      case HNP_TEST:
++              hnp_initiate();
++              break ;
++
++      case PRINT_REG:
++              break;
++
++      case OTG_SUSPEND:
++              break ;
++
++      case OTG_RESUME:
++              break ;
 +      }
-+#else
-+      list_add_tail(&(pUrb->urb_list), &(pEnd->urb_list));
-+#endif
 +
-+      return rc;
++      return 0;
 +}
 +
-+/**
-+ * find the end an urb is posted to
-+ * @param pUrb 
-+ * @return the pEnd or NULL when not found.
-+ */
-+MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb) 
++
++int otg_open (struct inode *inode, struct file *file)
 +{
-+      int bEnd=0;
-+      
-+      for (bEnd=0; bEnd<MUSB_C_NUM_EPS-1; bEnd++) {
-+              if ( MGC_GetCurrentUrb(&pThis->aLocalEnd[bEnd])==pUrb ) {
-+                      return &pThis->aLocalEnd[bEnd];
-+              }
-+      }
-+    
-+      return NULL;
++        /* to prevent compiler warnings */
++        inode=inode;
++        file=file;
++
++        return 0;
++}
++
++
++int otg_close (struct inode *inode, struct file *file)
++{
++        /* to prevent compiler warnings */
++        inode = inode;
++        file  = file;
++
++        return 0;
 +}
 +
++
++
++
++
 +/**************************************************************************
-+ * 
-+ **************************************************************************/
++ * HDRC functions
++**************************************************************************/
 +
-+void mgc_complete_urb(MGC_LinuxCd *pThis, struct urb *pUrb) { 
-+      /* give it back */
-+      usb_put_urb(pUrb);
-+      if (pUrb->status) {
-+              DBG(1, "completing urb=%p,status=%d\n", pUrb, pUrb->status);
-+      }
++/**
++ * Timer completion callback to finish resume handling started in ISR
++ * @param pParam the driver instance
++ */
++STATIC void MGC_HdrcDropResume(unsigned long pParam)
++{
++      uint8_t power;
++      MGC_LinuxCd* pThis = (MGC_LinuxCd*)pParam;
++      void* pBase = pThis->pRegs;
 +
-+#ifdef MUSB_USE_HCD_DRIVER
-+      mgc_hcd_complete_urb(pThis, pUrb);
-+#else
-+      if ( pUrb->complete ) {
-+              COMPLETE_URB(pUrb, NULL);
-+      }       
-+#endif        
++      DBG(2, "<==\n");
 +
-+      if (pUrb->status) {
-+              DBG(1, "done completing pUrb=%p\n", pUrb);
-+      }
++      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME);
++
++#ifdef MUSB_VIRTHUB
++      MGC_VirtualHubPortResumed(&(pThis->RootHub), 0);
++#endif
 +}
 +
 +/**
-+ * complete an urb. Since urb completion generally post new urbs via 
-+ * submit urn, this  make sure the ep won't kickstart it during the
-+ * completion. 
-+ *
-+ * @param pEnd the end point urb is posted to
-+ * @param pUrb the urb to complete !=NULL
-+ * @return 0 success
++ * Timer completion callback to request session again
++ * (to avoid self-connecting)
++ * @param pParam the driver instance
 + */
-+static inline int mgc_linux_complete_urb(MGC_LinuxCd *pThis, 
-+      MGC_LinuxLocalEnd* pEnd, struct urb *pUrb) 
++STATIC void MGC_HdrcRestart(unsigned long pParam)
 +{
-+ 
-+      int periodic=mgc_urb_is_periodic(pUrb);
-+      int status=periodic; /* 0 needs start next */
-+      int error=(pUrb->status==-ENOENT) || (pUrb->status==-ECONNRESET) ||
-+              (pUrb->status==-ESHUTDOWN) || (pUrb->status==-ETIMEDOUT)
-+              || (pUrb->status==-EBUSY);
-+      
-+      DBG(2, "<== completing URB %p, on pEnd->bEnd=%d status=%d, proto=%s\n", 
-+              pUrb, pEnd->bEnd, pUrb->status, decode_urb_protocol(pUrb));
-+      
-+    if ( error && periodic ) {
-+              pEnd->bIsClaimed=FALSE;
-+      }
++      MGC_HdrcStart((MGC_LinuxCd*)pParam);
++}
 +
-+      /* prevents locking&kickstarting */
-+      pEnd->bBusyCompleting=1;
++/* -------------------------------------------------------------------------
++ *
++ * ------------------------------------------------------------------------ */
 +
-+      mgc_complete_urb(pThis, pUrb);
-+      
-+#ifdef MUSB_V24                       
-+      /* Under 2.4 interrupt IN URBs must be re-submitted from the driver
-+       * unless they are unlinked; 2.6 urbs do that from the completition
-+       * routine. ENODEV means we raced disconnect() */
-+    if ( !error && periodic ) {                               
-+              DBG(1, "periodic pUrb=%p, proto=%s, (status=%d)\n", pUrb, 
-+                      decode_urb_protovol(pUrb), pUrb->status);                                                               
-+              status=mgc_schedule_urb(pThis, pEnd, pUrb);
-+              if ( (status!= 0) && (status != -ENODEV) ) {
-+                      DBG(3, "error resubmitting intr URB %p (status=%d)\n", 
-+                              pUrb, status);
-+              }
-+              
++/**
++ * Load an HDRC FIFO
++ *
++ * @param pBase base address of HDRC
++ * @param bEnd local endpoint
++ * @param wCount how many bytes to load
++ * @param pSource data buffer
++ */
++void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd,
++                    uint16_t wCount, const uint8_t* pSource)
++{
++      uint16_t wIndex, wIndex32;
++      uint16_t wCount32 = wCount >> 2;
++      uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd);
++      DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pSrc=%p\n",
++              pBase, bEnd, wCount, pSource);
++
++#ifdef MUSB_PARANOID
++      if ( IS_INVALID_ADDRESS(pSource) ) {
++              ERR("loading fifo from a null buffer; why did u do that????\n");
++              return;
 +      }
-+#else
-+      status=0; /* kickstart next */
 +#endif
 +
-+      /* allows locking&kickstarting again */
-+      pEnd->bBusyCompleting=0;
++      /* doublewords when possible */
++      for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) {
++              MGC_Write32(pBase, bFifoOffset, *((uint32_t*)&(pSource[wIndex])));
++      }
 +
-+      DBG(2, "==> status=%d, periodic=%d\n", status, periodic);
-+      return status;
++      for(; wIndex < wCount; wIndex++) {
++              MGC_Write8(pBase, bFifoOffset, pSource[wIndex]);
++      }
 +}
-+ 
++
 +/**
-+ * Start transmit. Caller is responsible for locking the ep.
-+ * On EP0 only PING is disabled.
++ * Unload an HDRC FIFO
 + *
-+ * @param pThis instance pointer
++ * @param pBase base address of HDRC
 + * @param bEnd local endpoint
++ * @param wCount how many bytes to unload
++ * @param pDest data buffer
 + */
-+void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd)
++void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd,
++                      uint16_t wCount, uint8_t* pDest)
 +{
-+    uint16_t wCsr;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+
-+    DBG(2, "<== bEnd=%d ==>\n", bEnd);
-+    /* NOTE: no locks here; caller should lock */
-+    MGC_SelectEnd(pBase, bEnd);    
-+    if(bEnd) {
-+        wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
-+              wCsr |= MGC_M_TXCSR_TXPKTRDY;
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
-+    } else {
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                      MGC_M_CSR0_H_NO_PING | MGC_M_CSR0_H_SETUPPKT | MGC_M_CSR0_TXPKTRDY);
-+    }    
-+}
-+
-+/**************************************************************************
-+ * 
-+ **************************************************************************/
++      uint16_t wIndex=0, wIndex32;
++      uint16_t wCount32 = wCount >> 2;
++      uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd);
 +
-+ /**
-+  * return the buffer associated to an urb (map it too)
-+  */
-+static inline uint8_t* get_urb_buffer(struct urb* pUrb) {
-+       uint8_t *pBuffer=NULL;
-+       
 +#ifdef MUSB_PARANOID
-+      if ( !pUrb ) {
-+              return NULL;
++      if ( IS_INVALID_ADDRESS(pDest) ) {
++              ERR("unloading fifo from a null buffer\n");
++              return;
 +      }
 +#endif
 +
-+       pBuffer=pUrb->transfer_buffer;
-+#ifndef MUSB_LINUX_MV21
-+      if ( !pBuffer ) {
-+              pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
++      DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pDest=%p\n", pBase, bEnd,
++              wCount, pDest);
++
++      /* doublewords when possible */
++      for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) {
++              *((uint32_t*)&(pDest[wIndex])) = MGC_Read32(pBase, bFifoOffset);
 +      }
-+#endif
 +
-+      return pBuffer;
++      while(wIndex < wCount) {
++              pDest[wIndex++]=MGC_Read8(pBase, bFifoOffset);
++      }
 +}
-+ 
-+/** 
-+ * Xmit a packet. pEnd->dwOffset is updated as well 
-+ * @param pThis
-+ * @param bEnd the EP urb is queued to
++
++/* -------------------------------------------------------------------------
++ *
++ * ------------------------------------------------------------------------ */
++
++/**
++ * Stop the host controller driver. Stop the controller and disconnect the
++ * virtual hub.
++ * @param pThis the controller
++ * @param vberr !=0 if a VBUs error was discovered.
 + */
-+static uint8_t mgc_linux_packet_tx(MGC_LinuxCd* pThis, uint8_t bEnd) {
-+      uint32_t wLength=0;
-+    uint8_t bDone = FALSE;
-+      uint8_t *pBase = (uint8_t*)pThis->pRegs;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+      struct urb* pUrb=MGC_GetCurrentUrb(pEnd);
-+      uint8_t *pBuffer=get_urb_buffer(pUrb);
-+    int nPipe = pUrb ? pUrb->pipe : 0;
++static void hdrc_stop_host(MGC_LinuxCd* pThis, int vberr)
++{
++      MGC_HdrcStop(pThis);
 +
-+      DBG(2, "<== bEnd=%d\n", bEnd);
++#ifdef MUSB_VIRTHUB
++      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
++      pThis->pRootDevice = NULL;
++      mgc_hcd_flush(pThis);
++#endif
 +
-+      /* abort the transfer */
-+    if ( !pBuffer ) { 
-+              ERR("***> no buffer was given, BAD things are happening (TM)!\n");
-+              return TRUE;  
-+    }
++}
 +
-+      /* see if more transactions are needed */
-+#ifdef MUSB_DMA
-+      if(pEnd->pDmaChannel) {
-+              if (MGC_DMA_STATUS_FREE == 
-+                      pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel)
-+              ) {
-+                      pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
-+              }
-+      } else {
-+              pEnd->dwOffset += pEnd->dwRequestSize;
-+      }
-+#else
-+      pEnd->dwOffset += pEnd->dwRequestSize;
++/**
++ * Interrupt Service Routine to record USB "global" interrupts.
++ * Since these do not happen often and signify things of
++ * paramount importance, it seems OK to check them individually;
++ * there is an ORDER to perform the tests check p35 of the MUSBHDRC
++ * manual.
++ *
++ * @param pThis instance pointer
++ * @param bIntrUSB register contents
++ * @param devctl
++ * @param power
++ */
++static int mgc_hdrc_service_usb_stage0(MGC_LinuxCd* pThis, uint8_t bIntrUSB,
++                                     uint8_t devctl, uint8_t power)
++{
++      int handled=0;
++#ifdef MUSB_HOST
++      uint8_t bSpeed = 1;
++      uint8_t bHubSpeed = 2;
 +#endif
++      uint8_t bResetBabble = FALSE;
++      uint8_t* pBase = (uint8_t*)pThis->pRegs;
 +
-+      if (usb_pipeisoc(nPipe)) {
-+              /* isoch case */
-+              if(++pEnd->dwIsoPacket >= pUrb->number_of_packets) {
-+                      bDone = TRUE;
-+              } else {
-+                      pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
-+                      wLength = pUrb->iso_frame_desc[pEnd->dwIsoPacket].length;
++      /* in host mode when a device resume me (from power save)
++       * in device mode when the host resume me; it shold not change
++       * "identity".
++       */
++      if (bIntrUSB & MGC_M_INTR_RESUME) {
++              handled++;
++              DBG(2, "RESUME\n");
++
++              if (devctl & MGC_M_DEVCTL_HM) {
++#ifdef MUSB_HOST
++                      printk("Host Mode : resume\n");
++                      power &= ~MGC_M_POWER_SUSPENDM;
++                      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
++                      MGC_LinuxSetTimer(pThis, MGC_HdrcDropResume,
++                              (unsigned long)pThis, 40);
++#endif
 +              }
-+      } else {                                        
-+              pBuffer += pEnd->dwOffset;
-+              wLength = min((uint32_t)(pEnd->wPacketSize), 
-+                        (uint32_t)(pUrb->transfer_buffer_length - pEnd->dwOffset));
-+              if(pEnd->dwOffset >= pUrb->transfer_buffer_length) {
-+                      /* sent everything; see if we need to send a null */
-+                      if(!((pEnd->dwRequestSize == pEnd->wPacketSize) &&
-+                       (pUrb->transfer_flags & USB_ZERO_PACKET))) 
-+                      {
-+                              bDone = TRUE;
-+                      }
++              else {
++                      udc_resume();
++                      printk("Device Mode : resume\n");
 +              }
 +      }
 +
-+      if (bDone) {
-+              pUrb->status=0;
-+      } else if ( wLength ) { /* @assert bDone && !wLength */
-+              MGC_HdrcLoadFifo(pBase, bEnd, wLength, pBuffer);
-+              pEnd->dwRequestSize = wLength;
-+      }
++      /* p35 MUSBHDRC manual for the order of the tests */
++      if (bIntrUSB & MGC_M_INTR_SESSREQ) {
++              DBG(2, "SESSION_REQUEST\n");
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+      pEnd->dwTotalTxBytes += pEnd->dwRequestSize;
-+      pEnd->dwTotalTxPackets++;
++              /* NOTE i might get a sesison request WHILE switchign between B and A
++               * device investigatge about that; check p35 of the manual
++               */
++#ifdef MUSB_PARANOID
++              if ( HDRC_IS_DEV(pThis) ) {
++                      ERR("Received a SESSION_REQUEST when connected to the B end; am I switching?!\n");
++              }
 +#endif
 +
-+      DBG(2, "==> bDone=%d\n", bDone);
-+      return bDone;
-+}
-+              
-+ 
-+/**
-+ * Receive a packet (or part of it).
-+ * @requires pThis->Lock locked
-+ * @param pThis
-+ * @param bEnd
-+ * @param bIsochError
-+ * @return TRUE if URB is complete
-+ */
-+static uint8_t mgc_linux_packet_rx(MGC_LinuxCd* pThis, uint8_t bEnd,
-+      uint16_t wRxCount, uint8_t bIsochError)
-+{
-+    uint16_t wLength, wCsr;
-+    uint8_t bDone = FALSE;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+    struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
-+    uint8_t* pBuffer=get_urb_buffer(pUrb);
-+    int nPipe = pUrb ? pUrb->pipe : 0;
++              /* time critical code (turn on VBUS); inherent race condition */
++              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
++              pThis->bEnd0Stage = MGC_END0_START;
++
++              handled++;
 +
-+      DBG(2, "<== end %d RxCount=%04x\n", bEnd, wRxCount); 
++      }
++
++      /* VBUSError is bad, shutdown &  go to error mode and ignore
++      * the other interrups; p35 MUSBHDRC manual for the order
++      of the tests */
++      if (bIntrUSB & MGC_M_INTR_VBUSERROR) {
++              handled++;
 +
 +#ifdef MUSB_PARANOID
-+    if ( !pUrb || ((pUrb->transfer_buffer_length - pEnd->dwOffset)<0) )  {
-+              ERR("***> Rx error: pUrb=%p, pUrb->transfer_buffer_length=%d pEnd->dwOffset=%d\n", \
-+                      pUrb, pUrb->transfer_buffer_length, pEnd->dwOffset );
-+              return TRUE;
-+    }    
++              if ( !(devctl & MGC_M_DEVCTL_HM) ) {
++                      ERR("Received a MGC_M_INTR_VBUSERROR when connected to the B end!\n");
++                      hdrc_stop_host(pThis, FALSE);
++                      return handled;
++              }
 +#endif
 +
-+    DBG(3, "bEnd=%d, pUrb->transfer_flags=0x%x pUrb->transfer_buffer=%p\n", \
-+              bEnd, pUrb->transfer_flags, pUrb->transfer_buffer); 
-+      DBG(3, "pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, wRxCount=%d\n", 
-+              pUrb->transfer_buffer_length, pEnd->dwOffset, wRxCount); 
-+      
-+      /* abort the transfer */        
-+    if ( !pBuffer ) { 
-+              ERR("***> pBuffer=NULL, BAD things are happening (TM)!\n");
-+              return TRUE;  
-+    }
-+
-+    /* unload FIFO */
-+    if( usb_pipeisoc(nPipe) ) {
-+              /* isoch case */
-+              pBuffer += pUrb->iso_frame_desc[pEnd->dwIsoPacket].offset;
-+              wLength = min((unsigned int)wRxCount, 
-+                                pUrb->iso_frame_desc[pEnd->dwIsoPacket].length);
-+              pUrb->actual_length += wLength;
-+              
-+              /* update actual & status */
-+              pUrb->iso_frame_desc[pEnd->dwIsoPacket].actual_length = wLength;
-+              if(bIsochError) {
-+                      pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_CRC;
-+                      pUrb->error_count++;
-+              } else {
-+                      pUrb->iso_frame_desc[pEnd->dwIsoPacket].status = USB_ST_NOERROR;
++              DBG(2, "V_BUS ERROR??? this is bad (TM)\n");
++              if ( pThis->bVbusErrors++ > MUSB_MAX_VBUS_ERRORS ) {
++                      printk("Vbus Error\n");
++                      hdrc_stop_host(pThis, TRUE);
++                      MUSB_ERR_MODE(pThis, MUSB_ERR_VBUS);
 +              }
-+      
-+              /* see if we are done */
-+              bDone = (++pEnd->dwIsoPacket >= pUrb->number_of_packets);
++      }
 +
-+              DBG(3, "pEnd->dwIsoPacket=%d, pUrb->number_of_packets=%d, wLength=%d\n",
-+                      pEnd->dwIsoPacket, pUrb->number_of_packets, wLength);           
-+              DEBUG_CODE(3, if ( bDone ) { \
-+                              INFO("completing %d-packet isoch URB; len=%x, errors=%d\n", \
-+                              pUrb->number_of_packets, pUrb->actual_length, pUrb->error_count); \
-+                      } );
-+    } else {
-+              DBG(3, "(bEnd=%d), wRxCount=%d, pUrb->transfer_buffer_length=%d, pEnd->dwOffset=%d, pEnd->wPacketSize=%d\n", 
-+                 bEnd, wRxCount, pUrb->transfer_buffer_length, pEnd->dwOffset, pEnd->wPacketSize);                                               
++      /* connect is valid only when in host mode; ignore it if in device mode;
++      p35 MUSBHDRC manual for the order of the tests */
 +
-+              /* non-isoch */
-+              pBuffer += pEnd->dwOffset;
-+              wLength = min((unsigned int)wRxCount, 
-+                                pUrb->transfer_buffer_length - pEnd->dwOffset);
-+              pUrb->actual_length += wLength;
-+              pEnd->dwOffset += wLength;
-+              
-+              /* see if we are done */
-+              bDone = (pEnd->dwOffset >= pUrb->transfer_buffer_length)
-+                      || (wRxCount < pEnd->wPacketSize);
-+                 
-+              DEBUG_CODE(3, if ( bDone ) { \
-+                      INFO("will complete URB; pUrb=%p (%s) len=%x, errors=%d\n", \
-+                      pUrb, decode_urb_protocol(pUrb), pUrb->actual_length, \
-+                      pUrb->error_count); \
-+              } );
-+    }
 +
-+      if ( wLength ) {
-+              MGC_HdrcUnloadFifo(pBase, bEnd, wLength, pBuffer);
-+      }
-+      
-+#ifdef MUSB_CONFIG_PROC_FS
-+    pEnd->dwTotalRxBytes += wLength;
-+    pEnd->dwTotalRxPackets++;
++      if(bIntrUSB & MGC_M_INTR_CONNECT) {
++              handled++;
++              Urb_status=0;
++
++              if(host_a_idle==1){
++                      host_a_idle=0;
++              }
++              DBG(2, "RECEIVED A CONNECT (goto host mode)\n");
++              printk("connect interrupt\n");
++#ifdef MUSB_PARANOID
++              if ( !(devctl & MGC_M_DEVCTL_HM) ) {
++                      ERR("Received a CONNECT when connected to the B end!\n");
++              }
 +#endif
-+    
-+    if( wRxCount <= wLength ) { /* test for short packet */
-+              wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
-+                                 wCsr & ~MGC_M_RXCSR_RXPKTRDY);
-+    }
-+      if ( bEnd && bDone ) {
-+              pUrb->status=0;
-+      }
-+      
-+      DBG(2, "==> bDone=%d\n", bDone); 
-+    return bDone;    
-+}
++              MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
++              MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
 +
-+/* *************************************************************************
-+ 
-+ **************************************************************************/
++#ifdef MUSB_HOST
++              pThis->pRootDevice = NULL;
++              pThis->bEnd0Stage = MGC_END0_START;
 +
-+/**
-+ * Find first (lowest-order) 1 bit
-+ * @param nValue value in which to search
-+ * @return bit position (0 could mean no bit; caller should check)
-+ */
-+static uint8_t find_first1(unsigned int nValue)
-+{
-+    uint8_t bResult;
-+    unsigned int nWork = nValue;
++              /* reset the addres... probably not needed*/
++              MGC_Write8(pThis->pRegs, MGC_O_HDRC_FADDR, 0);
++              /* flush endpoints when transitioning from Device Mode*/
++              if ( MUSB_IS_A_IDLE(pThis) ) {
++                      uint8_t bEnd;
 +
-+    for(bResult = 0; bResult < 32; bResult++) {
-+              if(nWork & 1) {
-+                      return bResult;
++                      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++                              MGC_HdrcStopEnd(pThis, bEnd);
++                      }
 +              }
-+              nWork >>= 1;
-+    }
-+      
-+    return bResult;
-+}
 +
-+/**
-+ * @param nPipe
-+ */
-+static inline char *pipe_type(const unsigned int nPipe) {
-+      if ( usb_pipeisoc(nPipe) ) {
-+              return "isoc";
-+      } else if ( usb_pipebulk(nPipe) ) {
-+              return "bulk";
-+      } else if ( usb_pipeint(nPipe) ) {
-+              return "int";
-+      } else {
-+              return "cntl";
-+      }               
-+}
 +
-+/** Calculate the interval (or NAK limit for bulk) for isoc and
-+ * inter requests.
-+ * @param pUrb the urb interval should be determined for
-+ * @return the interval
-+ */
-+static uint8_t hdrc_interval(struct urb* pUrb) {
-+    const unsigned int nPipe = pUrb->pipe;
-+    uint8_t bInterval = (uint8_t)pUrb->interval;
-+ 
-+    if( usb_pipeint(nPipe) ) {                
-+              /* correct interval for high-speed */
-+              if((USB_SPEED_HIGH == ((uint8_t)pUrb->dev->speed)) && (pUrb->interval > 255)) {
-+                      bInterval = find_first1(pUrb->interval);
-+              }               
-+    } else {
-+              /* normalize value */
-+              if(pUrb->interval > 16) {
-+                      bInterval = find_first1(pUrb->interval);
-+              }
-+              
-+              if(usb_pipeisoc(nPipe) && (bInterval < 1)) {
-+                      bInterval = 1;
++              if(devctl & MGC_M_DEVCTL_LSDEV) {
++                      bSpeed = 3;
++                      bHubSpeed = 0;
++              } else if(devctl & MGC_M_DEVCTL_FSDEV) {
++                      /* NOTE: full-speed is "speculative" until reset */
++                      bSpeed = 2;
++                      bHubSpeed = 1;
 +              }
 +
-+              if( usb_pipebulk(nPipe) && (bInterval < 2)) {
-+                      /* this is the NACK time */
-+                      bInterval = 0;/*16;*/  
++              pThis->bRootSpeed = bSpeed;
++              if(pThis->bIsMultipoint) {
++                      /* set speed for EP0 */
++                      MGC_SelectEnd(pBase, 0);
++                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0,
++                              (bSpeed << 6));
 +              }
-+    }         
-+      
-+      DBG(2, "pipe_type=%s bInterval=%d\n", pipe_type(nPipe), bInterval);
-+              
-+      return bInterval;
-+}
-+      
-+/**
-+ * @param pUrb
-+ */
-+static inline uint8_t hdrc_type(struct urb* pUrb) {
-+    uint8_t bStdType = 0;
-+    const unsigned int nPipe = pUrb->pipe;
-+      
-+    if(usb_pipeisoc(nPipe)) {
-+        bStdType = 1;
-+    } else if(usb_pipeint(nPipe)) {
-+        bStdType = 3;
-+    } else if( usb_pipebulk(nPipe) ) { 
-+        bStdType = 2;
-+      }
-+      
-+      return bStdType;
-+}
 +
-+/**
-+ * program hdrc_registers for the device address of a given urb.
-+ * @param pTjos
-+ * @param pUrb
-+ * @param bEnd
-+ * @param bXmt
-+ */
-+static void hdrc_set_address(MGC_LinuxCd* pThis, struct urb* pUrb, uint8_t bEnd, 
-+      unsigned int bXmt) 
-+{
-+#ifdef MUSB_LINUX_MV21
-+    struct usb_device* pParent;
++              MUSB_HST_MODE(pThis);
++
++              /* indicate new connection to OTG machine */
++              MGC_VirtualHubPortConnected(&(pThis->RootHub), 0,
++                      bHubSpeed);
 +#endif
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    uint8_t bAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
-+    uint8_t bHubAddr = 0, bHubPort = 0, bIsMulti = FALSE;
++      }
 +
++      /* saved one bit: bus reset and babble share the same bit;
++      * If I am host is a babble! i must be the only one allowed
++      * to reset the bus; when in otg mode it means that I have
++      * to switch to device
++      */
++      if (bIntrUSB & MGC_M_INTR_RESET) {
 +
-+      /* NOTE: there is always a parent due to the virtual root hub */
-+    bHubAddr = (uint8_t)pUrb->dev->parent->devnum;    
-+      /* but not if parent is our virtual root hub */
-+    if(bHubAddr == pThis->RootHub.bAddress) {
-+              bHubAddr = 0;
-+    }
++#ifndef MUSB_OTG
 +
-+#ifdef MUSB_LINUX_MV21
-+    /* parent hub address */
-+      pParent = pUrb->dev->parent;
-+      
-+    /* this distribution doesn't support directly, so try to find ourselves */
-+    if((USB_SPEED_HIGH!=((uint8_t)pUrb->dev->speed)) && 
-+       (pParent->devnum != pThis->RootHub.bAddress))
-+    {
-+              int nChild;
-+              struct usb_device* pDevice;
-+              
-+        /* walk up to first high-speed hub and remember our subtree's child */
-+              pDevice = pUrb->dev;
-+              while(pParent && (USB_SPEED_HIGH != pParent->speed) &&
-+                        (pParent->devnum != pThis->RootHub.bAddress))
-+              {
-+                      pDevice = pParent;
-+                      pParent = pParent->parent;
-+              }
-+              
-+              if(pParent && (pParent->devnum != pThis->RootHub.bAddress)) {
-+                      /* correlate to port and check for multi-TT */
-+                      for(nChild = 0; nChild < pParent->maxchild; nChild++) {
-+                              if(pParent->children[nChild] == pDevice) {
-+                                      bHubPort = nChild + 1;
-+                                      bIsMulti = (2 == pParent->descriptor.bDeviceProtocol);
-+                                      break;
-+                              }
-+                      }
++              /* This is added since, Mentor IP same bit is shared for RESET and BABBLE.
++               * In host mode if this bit is set to indicate BABBLE, but when this bit
++               * get set the controller clears the session bit and the host mode bit in
++               * device control register and driver reads it as RESET and tries to enter
++               * in device mode. So if OTG is not set we will check the driver status and
++               * the appropriate action.
++               */
++
++              if(MUSB_IS_HST(pThis)){
++                      bResetBabble = TRUE;
 +              }
-+    }
 +#else
-+    /* if tt pointer, use its info */
-+    if(pUrb->dev->tt) {
-+              bHubPort = (uint8_t)pUrb->dev->ttport;
-+#ifdef HAS_USB_TT_MULTI
-+              bIsMulti = (uint8_t)pUrb->dev->tt->multi;
-+#endif
-+    }
++              bResetBabble = devctl & MGC_M_DEVCTL_HM;
 +#endif
-+      
-+      if ( bIsMulti ) {
-+              bHubAddr |=0x80;
-+      }
-+      
-+      /* tx address */
-+      if(pThis->bIsMultipoint) {                      
-+              /* target addr & hub addr/port */
-+              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR), 
-+                         bAddress);
-+              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR), 
-+                         bHubAddr);
-+              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT), 
-+                         bHubPort);
-+                         
-+              /* also, try Rx (this is a bug ion the core: I always need to to do 
-+               * both (at least for ep0), needs to be changed when the core is
-+               * fixed */
-+              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR), 
-+                         bAddress);
-+              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR), 
-+                         bHubAddr);
-+              MGC_Write8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT), 
-+                         bHubPort);
-+      } else {
-+              /* non-multipoint core */
-+
-+              MGC_Write8(pBase, 0x80 + 8*bEnd, bAddress);
-+              MGC_Write8(pBase, 0x84 + 8*bEnd, bAddress);
-+
-+      }
++              DBG(2, "BUS RESET\n");
 +
-+      DBG(2, "end %d, device %d, parent %d, port %d, multi-tt: %d, speed:%d\n", \
-+              bEnd, pUrb->dev->devnum, bHubAddr, bHubPort, bIsMulti, pUrb->dev->speed ); 
-+}
++              if (bResetBabble) {
++                      printk("Host Mode : reset\n");
++                      hdrc_stop_host(pThis, FALSE);
++                      /* restart session after cooldown unless threshold reached */
++                      if( pThis->nBabbleCount++ < MUSB_MAX_BABBLE_COUNT) {
++                              MGC_LinuxSetTimer(pThis, MGC_HdrcRestart,
++                                      (unsigned long)pThis, MUSB_RESTART_TIME);
++                      }
++              } else {
 +
-+/**
-+ * @param pThis
-+ * @param pUrb
-+ * @param bEnd
-+ * @param bXmt
-+ */
-+static void hdrc_set_protocol(MGC_LinuxCd* pThis, struct urb* pUrb, 
-+      uint8_t bEnd, unsigned int bXmt) 
-+{
-+    uint8_t reg;
-+    uint8_t bStdType = hdrc_type(pUrb);
-+    unsigned int nPipe = pUrb->pipe;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs; 
-+                              
-+      reg = (bStdType << 4 ) | 
-+              (((uint8_t)usb_pipeendpoint(nPipe)) & 0xf);     
-+              switch( ((uint8_t)pUrb->dev->speed) ) {
-+                case USB_SPEED_LOW:
-+                      reg |= 0xc0;
-+                      break;
-+                case USB_SPEED_FULL:
-+                      reg |= 0x80;
-+                      break;
-+                default:
-+                      reg |= 0x40;
-+              }
-+      
-+      if ( bXmt ) {
-+              if(bEnd) {
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd, reg);
-+              } else if(pThis->bIsMultipoint) {
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
-+              }
-+      } else {
-+              if(bEnd) {
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXTYPE, bEnd, reg);
-+              } else if(pThis->bIsMultipoint) {
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, reg & 0xc0);
-+              }       
-+      }                                   
-+}
++                      del_timer(&notify_timer);
++                      pThis->bEnd0Stage = MGC_END0_START;
++                      MUSB_DEV_MODE(pThis);
++                      printk("Device Mode : reset\n");
 +
-+static void mgc_hdrc_flush_fifo(MGC_LinuxCd* pThis, uint8_t bEnd, int rx) 
-+{
-+      if ( rx ) {
-+              /* twice in case of double packet buffering */
-+              MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd, 
-+                      MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
-+              MGC_WriteCsr16((uint8_t*)pThis->pRegs, MGC_O_HDRC_RXCSR, bEnd, 
-+              MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
-+      }
-+}
++                      if(b_hnp_init == 1){
++                              otg_disconnect(udc_address);
++                              driver_change_mode_handler(2);
++                              devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +
-+static void mgc_hdrc_flush_end(MGC_LinuxCd* pThis, uint8_t bEnd) {
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
++                      }
 +
-+      if(bEnd) {
-+              /* general endpoint */
-+              /* if not ready, flush and restore data toggle */
-+              if(!pEnd->bIsReady && pThis->bIsMultipoint) {
-+                      pEnd->bIsReady = TRUE;
-+                      
-+                      /* twice in case of double packet buffering */
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 
-+                                         MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG);
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 
-+                                         MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_CLRDATATOG);
++                      if(udcinitmonitorflag_isr==0){
++                              nomadik_udc_init(udc_address);
++                      }
++                      udcinitmonitorflag_init=1;
++                      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++                      musb_reset_isr();
++                      dev_safe_remove=1;
 +              }
-+      } else {
-+              /* endpoint 0: just flush */
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd,
-+                         MGC_M_CSR0_FLUSHFIFO);
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, bEnd,
-+                         MGC_M_CSR0_FLUSHFIFO);
++              handled++;
 +      }
++
++      return handled;
 +}
 +
++
 +/**
-+ * Program an HDRC endpoint as per the given URB
++ * Interrupt Service Routine to record USB "global" interrupts.
++ * Since these do not happen often and signify things of
++ * paramount importance, it seems OK to check them individually;
++ * there is an ORDER to perform the tests check p35 of the MUSBHDRC
++ * manual.
++ *
 + * @param pThis instance pointer
-+ * @param bEnd local endpoint
-+ * @param pURB URB pointer
-+ * @param nOut zero for Rx; non-zero for Tx
-+ * @param pBuffer buffer pointer
-+ * @param dwLength how many bytes to transmit or expect to receive
++ * @param bIntrUSB register contents
++ * @param devctl
++ * @param power
 + */
-+static void mgc_hdrc_program_end(MGC_LinuxCd* pThis, uint8_t bEnd, 
-+      struct urb* pUrb, unsigned int nOut, unsigned int bXmt,
-+      uint8_t* pBuffer, uint32_t dwLength)
++static int mgc_hdrc_service_usb_stage1(MGC_LinuxCd* pThis, uint8_t bIntrUSB,
++      uint8_t devctl, uint8_t power)
++
 +{
-+    uint16_t wIntrTxE;
-+    uint8_t bDone = FALSE;
++      int handled=0;
++    uint8_t bEnd;
++    uint16_t wFrame;
++      uint8_t state;
 +    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    unsigned int nPipe = pUrb->pipe;
-+    uint16_t wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut);
-+    uint8_t bIsBulk = usb_pipebulk(nPipe);
-+    uint8_t bInterval=hdrc_interval(pUrb);
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+    uint8_t bStdType = hdrc_type(pUrb);
-+      uint8_t bDmaOk=FALSE;
-+#ifdef MUSB_DMA
-+      MGC_DmaChannel* pDmaChannel;
-+      MGC_DmaController* pDmaController;
-+#endif        
-+      unsigned long flags;
++      /* p35 MUSBHDRC manual for the order of the tests */
++    if(bIntrUSB & MGC_M_INTR_SOF) {
++              DBG(2, "START_OF_FRAME\n");
++              handled++;
 +
-+    DBG(2, "<==(bEnd=%d, pUrb=%p) bRemoteAddress=%d\n", bEnd, pUrb, (uint8_t)usb_pipedevice(nPipe));
-+    DBG(3, "end %d, device %d, speed:%d\n", bEnd, pUrb->dev->devnum, 
-+              pUrb->dev->speed ); 
++        /* start any periodic Tx transfers waiting for current frame */
++        wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME);
++              for(bEnd = 1;
++              (bEnd < pThis->bEndCount) && (pThis->wEndMask >= (1 << bEnd));
++                      bEnd++)
++              {
++                      if(pThis->aLocalEnd[bEnd].dwWaitFrame &&
++                              pThis->aLocalEnd[bEnd].dwWaitFrame >= wFrame)
++                      {
++                              pThis->aLocalEnd[bEnd].dwWaitFrame = 0;
++                              MGC_HdrcStartTx(pThis, bEnd);
++                      }
++              }
++      }
 +
-+    /* prepare endpoint registers according to flags */
-+      SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
-+    MGC_SelectEnd(pBase, bEnd);
-+      
-+      if ( bStdType==0 ) {
-+              bXmt=TRUE;
-+      }               
-+      
-+      hdrc_set_protocol(pThis, pUrb, bEnd, bXmt);
-+      hdrc_set_address(pThis, pUrb, bEnd, bXmt);              
++      /* p35 MUSBHDRC manual for the order of the tests */
++      if((bIntrUSB & MGC_M_INTR_DISCONNECT) && !pThis->bIgnoreDisconnect) {
++              DBG(2, "DISCONNECT()\n");
 +
++              mdelay(500);
++              handled++;
++              /* need to check it against pThis, because the devctl is going
++               * low as soon as the device gets disconnected */
++              if ( MUSB_IS_HST(pThis) ) {
++                      printk("Host Disconnect\n");
++                      DBG(3, "Disconnecting a port of VirtualHub\n");
 +
-+#ifdef MUSB_DMA
-+              pDmaController = pThis->pDmaController;
-+              pDmaChannel = pEnd->pDmaChannel;
-+              
-+              if( !WANTS_DMA(pUrb) && pDmaChannel) {
-+                      /* release previously-allocated channel */
-+                      pDmaController->pfDmaReleaseChannel(pDmaChannel);
-+                      pEnd->pDmaChannel = NULL;
-+              } else if( WANTS_DMA(pUrb) ) {
-+      
-+                      /* candidate for DMA */
-+                      if(pDmaController && !pDmaChannel) {
-+                              pDmaChannel = pEnd->pDmaChannel = pDmaController->pfDmaAllocateChannel(
-+                              pDmaController->pPrivateData, bEnd, nOut ? TRUE : FALSE, 
-+                                      bStdType, wPacketSize);
-+              
-+                      }
-+                      
-+                      if(pDmaChannel) {
-+                              pDmaChannel->dwActualLength = 0L;
-+                              pEnd->dwRequestSize = min(dwLength, pDmaChannel->dwMaxLength);
-+                              bDmaOk = pDmaController->pfDmaProgramChannel(pDmaChannel, 
-+                                      wPacketSize, pDmaChannel->bDesiredMode, DMA_BUFFER(pUrb), 
-+                                      pEnd->dwRequestSize);
-+                              if(!bDmaOk) {   
-+                                      pDmaController->pfDmaReleaseChannel(pDmaChannel);
-+                                      pEnd->pDmaChannel = NULL;
-+                              }
-+                      }
-+              }
-+#endif
-+      
-+    if ( bXmt ) { /* transmit */
-+              uint16_t wLoadCount=0;
-+              uint16_t wCsr= MGC_M_TXCSR_MODE;        
-+      
-+              if ( !bDmaOk ) {
-+                      if( bIsBulk && pThis->bBulkSplit ) {
-+                              wLoadCount = min((uint32_t)pEnd->wMaxPacketSizeTx, dwLength);
-+                      } else {
-+                              wLoadCount = min((uint32_t)wPacketSize, dwLength);
-+                      }
-+              }
-+              
-+              /* disable interrupt in case we flush */
-+              wIntrTxE = MGC_Read16(pBase, MGC_O_HDRC_INTRTXE);               
-+              MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE & ~(1 << bEnd));
++#ifdef MUSB_VIRTHUB
++                      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
++                      pThis->pRootDevice = NULL;
 +
-+              /* data toggle, make sure nothing is there! */
-+              mgc_hdrc_flush_end(pThis, bEnd);                                
-+              
-+              if( bEnd) {
-+                      wCsr |= MGC_M_TXCSR_H_WR_DATATOGGLE;
-+                      if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 1)) {
-+                              wCsr |= MGC_M_TXCSR_H_DATATOGGLE;
-+                      } else {
-+                              wCsr &= ~MGC_M_TXCSR_H_DATATOGGLE;
-+                      }
-+                      
-+                      /* protocol/endpoint/interval/NAKlimit */
-+                      if(bIsBulk && pThis->bBulkSplit) {
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, 
-+                                      wPacketSize | 
-+                                      ((pEnd->wMaxPacketSizeTx / wPacketSize) - 1) << 11);
-+                      } else {
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, wPacketSize);
-+                      }
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, bInterval);
-+                      
-+#ifdef MUSB_DMA
-+                      if (bDmaOk) {
-+                              wCsr |= (MGC_M_TXCSR_AUTOSET | MGC_M_TXCSR_DMAENAB | 
-+                              (pDmaChannel->bDesiredMode ? MGC_M_TXCSR_DMAMODE : 0)); 
++                      Urb_status=1;
++                      /* flush endpoints */
++                      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++                              MGC_HdrcStopEnd(pThis, bEnd);
 +                      }
-+#endif
 +
-+                      mgc_linux_packet_tx(pThis, bEnd);
-+              } else {                
-+                      /* protocol/endpoint/interval/NAKlimit */
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, bInterval);
-+                      if ( wLoadCount ) {                             
-+                              pEnd->dwRequestSize = wLoadCount;
-+                              MGC_HdrcLoadFifo(pThis->pRegs, bEnd, wLoadCount, pBuffer);
-+                      }
-+              }                       
-+              
-+              /* re-enable interrupt and write CSR to transmit */
-+              MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE);
++                      mgc_hcd_flush(pThis);
 +
-+              if (bEnd) {
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wCsr);
-+              }
-+    } else { /* receive */
-+              
-+              /* if was programmed for Tx, be sure it is ready for re-use */
-+              uint16_t wCsr=MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);                     
-+        if ( pEnd->bIsSharedFifo && wCsr & MGC_M_TXCSR_MODE) {
-+                      pEnd->bIsReady = FALSE;
-+                      
-+                      DBG(1, "reprogramming ep%d for rx\n", bEnd);
-+                      
-+                      if ( wCsr & MGC_M_TXCSR_FIFONOTEMPTY ) {
-+                              /* this shouldn't happen */
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 
-+                                         MGC_M_TXCSR_FRCDATATOG);
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 
-+                                         MGC_M_TXCSR_FRCDATATOG);
++                      MUSB_A_IDLE_MODE(pThis);
++            mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
 +
-+                              ERR("*** switching end %d to Rx but Tx FIFO not empty\n", bEnd);
-+                              MGC_SLOW_DEVICE_KLUDGE_DELAY_TOP;                               
-+                      }
-+                      
-+                      /* clear mode (and everything else) to enable Rx */
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 0);
-+              }
-+              
-+              /* grab Rx residual if any */
-+              wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
-+              if (wCsr & MGC_M_RXCSR_RXPKTRDY) {
-+                      uint16_t wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
-+                      bDone = mgc_linux_packet_rx(pThis, bEnd, wRxCount, FALSE);
-+                      DBG(1, "residual found bDone=%d\n", bDone);
-+              }
++#endif
 +
-+              /* protocol/endpoint/interval/NAKlimit */
-+              if(bEnd) {
-+#if 0
-+                      /* doesn't work reliably */
-+                      if(bIsBulk && pThis->bBulkCombine) {
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize | 
-+                                      ((min(pEnd->wMaxPacketSizeRx, dwLength) / wPacketSize) - 1) << 11);
-+                      } else {
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize);
++#ifdef MUSB_CONFIG_PROC_FS
++                      if(pThis->pfDisconnectListener) {
++                              pThis->pfDisconnectListener(pThis->pDisconnectListenerParam);
 +                      }
 +#endif
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, wPacketSize);
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, bInterval);
 +              }
++               else if (MUSB_IS_DEV(pThis) ){
 +
-+              /* first time or re-program and shared FIFO, flush & clear toggle */
-+              if(!pEnd->bIsReady && pEnd->bIsSharedFifo) {
-+                      DBG(4, "shared fifo\n");
-+                      
-+                      /* twice in case of double packet buffering */
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, 
-+                                 MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, 
-+                                 MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_CLRDATATOG);
-+                      pEnd->bIsReady = TRUE;
++               if(b_hnp_init == 1){
++                      del_timer(&notify_timer);
++                      b_hnp_init=0;
 +              }
-+      
-+              /* program data toggle if possibly switching use */
-+              if(!pEnd->bIsReady && pThis->bIsMultipoint) {
-+                      DBG(4, "multipoint\n");
-+                      
-+                      wCsr = MGC_M_RXCSR_H_WR_DATATOGGLE;
-+                      if(usb_gettoggle(pUrb->dev, pEnd->bEnd, 0)) {
-+                              wCsr |= MGC_M_RXCSR_H_DATATOGGLE;
++
++               else {
++                      printk("Device Disconnect\n");
++                      udc_disconnect_isr();
++                      MUSB_B_IDLE_MODE(pThis);
++                      mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
 +                      }
-+                      
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr);
++                }
++
++              /* KLUDGE: race condition, doing this right away might prevent
++               * the virtual hub/usbcore to process the last urbs. As a matter
++               * of facts this code should be called after the "disconnect" */
++    }
++
++      /* I cannot get suspend while in host mode! go to error mode and ignore
++       * the other signals; need to be last (see manual p35)s  */
++      if (bIntrUSB & MGC_M_INTR_SUSPEND) {
++              DBG(2, "RECEIVED SUSPEND\n");
++              if( b_hnp_suspend ==1)
++                {
++                      uint8_t linestate;
++                      MGC_HdrcReadUlpiReg(pThis, 0x15, &linestate);
++                      b_hnp_suspend = 0;
++                      driver_change_mode_handler(1);
 +              }
-+      
-+              /* kick things off */
-+              if( bEnd && !bDone) {
-+                      wCsr = MGC_M_RXCSR_H_REQPKT;
-+                      if(usb_pipeint(nPipe)) {
-+                              wCsr |= MGC_M_RXCSR_DISNYET;
-+                      }
-+#ifdef MUSB_DMA
-+                      if(bDmaOk) {
-+                              wCsr &= ~MGC_M_RXCSR_H_REQPKT;
-+                              wCsr |= MGC_M_RXCSR_H_AUTOREQ;
-+                              wCsr |= (MGC_M_RXCSR_AUTOCLEAR | MGC_M_RXCSR_DMAENAB | 
-+                                      (pDmaChannel->bDesiredMode ? MGC_M_RXCSR_DMAMODE : 0));         
-+                      }
-+#endif
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wCsr);
++              handled++;
++
++              if(devctl & MGC_M_DEVCTL_HM) {
++                      hdrc_stop_host(pThis, FALSE);
++              }
++              if(dev_safe_remove==1)
++              {
++                      udc_suspend();
++                      printk("Device Removed Safely \n");
++                      dev_safe_remove=0;
++                      state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
 +              }
 +    }
-+      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+    DBG(2, "==>\n");    
++
++      return handled;
 +}
 +
-+/* *************************************************************************
-+ * 
-+ **************************************************************************/
 +
-+static void mgc_ep_linux_clear(MGC_LinuxLocalEnd* pEnd,MGC_LinuxCd* pThis)
++/**
++* Program the HDRC to start (enable interrupts, etc.).
++ * @param pThis the controller
++*/
++void MGC_HdrcStart(MGC_LinuxCd* pThis)
 +{
-+      uint16_t wVal=0;
-+      unsigned long flags;
-+      uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    uint8_t bEnd=1;
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
 +
-+    pEnd->dwOffset = 0;
-+    pEnd->dwRequestSize = 0;
-+    pEnd->dwIsoPacket = 0;
-+    pEnd->dwWaitFrame = 0;
-+    pEnd->bRetries = 0;
++    DBG(2, "<==\n");
 +
-+      /* do the proper sequence to abort the transfer */
-+      SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
++    /* init the local ends */
++#ifdef MUSB_CONFIG_PROC_FS
++    pThis->aLocalEnd[0].dwTotalRxBytes = 0;
++    pThis->aLocalEnd[0].dwTotalRxPackets = 0;
++    pThis->aLocalEnd[0].dwErrorRxPackets = 0;
++    pThis->aLocalEnd[0].dwTotalTxBytes = 0;
++    pThis->aLocalEnd[0].dwTotalTxPackets = 0;
++    pThis->aLocalEnd[0].dwErrorTxPackets = 0;
++#endif
 +
-+      MGC_SelectEnd(pBase, pEnd->bEnd);
-+      
-+      if((pEnd->bRemoteEnd & 0x0F) == 0)
-+      {
-+              wVal |= MGC_M_CSR0_FLUSHFIFO;
-+              wVal &= ~MGC_M_CSR0_H_REQPKT;
-+              wVal &= ~MGC_M_CSR0_TXPKTRDY;
++      /* init counters and local data */
++    for(bEnd=1; bEnd < pThis->bEndCount; bEnd++) {
++      spin_lock( &pThis->aLocalEnd[bEnd].Lock );
++#ifdef MUSB_CONFIG_PROC_FS
++              pThis->aLocalEnd[bEnd].dwTotalRxBytes = 0;
++              pThis->aLocalEnd[bEnd].dwTotalRxPackets = 0;
++              pThis->aLocalEnd[bEnd].dwErrorRxPackets = 0;
++              pThis->aLocalEnd[bEnd].dwTotalTxBytes = 0;
++              pThis->aLocalEnd[bEnd].dwTotalTxPackets = 0;
++              pThis->aLocalEnd[bEnd].dwErrorTxPackets = 0;
++#endif
++#ifndef MUSB_USE_HCD_DRIVER
++      INIT_LIST_HEAD( &(pThis->aLocalEnd[bEnd].urb_list) );
++#endif
++              pThis->aLocalEnd[bEnd].bIsClaimed=FALSE;
++      spin_unlock( &pThis->aLocalEnd[bEnd].Lock );
++    }
 +
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, wVal);
-+      }
-+      else
-+      {
-+              if(pEnd->bIsTx)
-+              {
-+                      wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
-+                      wVal |= MGC_M_TXCSR_FLUSHFIFO;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal);
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, pEnd->bEnd, wVal);
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, pEnd->bEnd, 0);
-+              }
-+              else
-+              {
-+                      wVal &= ~MGC_M_RXCSR_H_REQPKT;                  
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, pEnd->bEnd, wVal);
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, pEnd->bEnd, 0);
-+              }
-+      }
++      /* reset the counters */
++      pThis->bVbusErrors=0;
 +
-+      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+              
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      pEnd->pCurrentUrb=NULL;
++    /*  Set INT enable registers, enable interrupts */
++    MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
++    MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
++      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xf7); /* don't enable suspend! */
++
++    DBG(1, "INTRUSBE reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE));
++      DBG(1, "INTRTXE  reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRTXE));
++      DBG(1, "INTRRXE  reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRRXE));
++
++    /* TODO: always set ISOUPDATE in POWER (periph mode) and leave it on! */
++    MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 0);
++
++    /* enable high-speed/low-power and start session */
++   MGC_Write8(pBase, MGC_O_HDRC_POWER,
++              MGC_M_POWER_SOFTCONN | MGC_M_POWER_HSENAB);
++
++
++#ifndef MUSB_GADGET
++    /* enable high-speed/low-power and start session & suspend IM host*/
++    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
++#else
++    {
++              uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
++    }
 +#endif
++
++    DBG(2, "==>\n");
 +}
 +
 +/**
-+ * Start the current URB on an endpoint; wants ep to be 
-+ * locked and pThis to be locked as well; end must be claimed 
-+ * from the caller.
-+ *
-+ * @param pThis instance pointer
-+ * @param bEnd local endpoint
-+ * @pre the endpoint is locked from the caller
-+ * @pre pThis is NOT locked
++ * Disable the HDRC (disable & flush interrupts);
++ * @param pThis the controller to disable
 + */
-+static void mgc_linux_kickstart_urb(MGC_LinuxCd* pThis, uint8_t bEnd)
++STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis)
 +{
-+    uint16_t wFrame;
-+    uint32_t dwLength;
-+    void* pBuffer;
++    uint16_t temp;
 +    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);      
-+    struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
-+    unsigned int nPipe, nOut, bXmt;
-+    uint16_t wPacketSize;
-+    uint8_t bRemoteAddress, bRemoteEnd;
-+    
-+      /* I should not have called!!! */
-+      if ( !pUrb ) {
-+              ERR("***> bEnd=%d is idle!\n", bEnd);
-+              return; 
-+      }
-+      
-+      if ( pUrb->hcpriv ) {
-+              ERR("==> pUrb=%p, pUrb->hcpriv=%p, pEnd=%p, bEnd=%d (%s) was kickstarted already! this is not good (TM)\n", 
-+                      pUrb, pUrb->hcpriv, pEnd, bEnd, decode_urb_protocol(pUrb));
-+      } 
-+      
-+    nPipe = pUrb->pipe;
-+    nOut = usb_pipeout(nPipe);
-+      bXmt = nOut ? TRUE : FALSE;
-+    wPacketSize = usb_maxpacket(pUrb->dev, nPipe, nOut);
-+    bRemoteAddress = (uint8_t)usb_pipedevice(nPipe);
-+    bRemoteEnd = (uint8_t)usb_pipeendpoint(nPipe);
 +
-+      DBG(2, "<== pUrb=%p, bEnd=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, nOut=%d\n", 
-+              pUrb, bEnd, wPacketSize, bRemoteAddress, bRemoteEnd, nOut); 
++    DBG(2, "<==\n");
 +
-+    /* if no root device, assume this must be it */
-+    if(!pThis->pRootDevice) {
-+              pThis->pRootDevice = pUrb->dev;
-+              switch(pThis->bRootSpeed) {
-+                case 1:
-+                      pThis->pRootDevice->speed = USB_SPEED_HIGH;
-+                      break;
-+                case 2:
-+                      pThis->pRootDevice->speed = USB_SPEED_FULL;
-+                      break;
-+                case 3:
-+                      pThis->pRootDevice->speed = USB_SPEED_LOW;
-+                      break;
-+              }
-+    }
++    /* disable interrupts */
++    MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0);
++    MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0);
++    MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0);
 +
-+    /* indicate in progress */
-+    pUrb->actual_length = 0;
-+    pUrb->error_count = 0;
-+      pUrb->hcpriv = pEnd; 
-+      /* remember software state - find_end() will use this - */      
-+    pEnd->bRemoteAddress = bRemoteAddress;    
-+    pEnd->bRemoteEnd = bRemoteEnd;    
-+    pEnd->bTrafficType = (uint8_t)usb_pipetype(nPipe);
-+    pEnd->bIsTx=bXmt;
++    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 0);
++    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1);
 +
-+    /* init urb */
-+    pEnd->dwOffset = 0;
-+    pEnd->dwRequestSize = 0;
-+    pEnd->dwIsoPacket = 0;
-+    pEnd->dwWaitFrame = 0;
-+    pEnd->bRetries = 0;
-+    pEnd->wPacketSize = wPacketSize;
-+              
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      pEnd->pCurrentUrb=pUrb;
-+#endif
++    /*  flush pending interrupts */
++    temp = MGC_Read8(pBase, MGC_O_HDRC_INTRUSB);
++    temp = MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
++    temp = MGC_Read16(pBase, MGC_O_HDRC_INTRRX);
 +
-+    /* pEnd->bIsClaimed=(usb_pipeisoc(nPipe) || usb_pipeint(nPipe)) ?TRUE:FALSE; 
-+     * end must be claimed from my caller
-+     */    
-+    if( usb_pipecontrol(nPipe) ) {
-+              /* control transfers always start with an OUT */
-+              bXmt=TRUE;
-+              pEnd->bIsTx=TRUE;
-+              pThis->bEnd0Stage = MGC_END0_START;
-+    }
++    DBG(2, "==> HDRC Interrupts disabled\n");
++}
 +
-+    /* gather right source of data */
-+    if( usb_pipeisoc(nPipe) ) {
-+              pBuffer = pUrb->transfer_buffer + pUrb->iso_frame_desc[0].offset;
-+              dwLength = pUrb->iso_frame_desc[0].length;
-+    } else if(usb_pipecontrol(nPipe)) {
-+              pBuffer = pUrb->setup_packet;
-+              dwLength = 8;
-+    } else {
-+              /* - */
-+              pBuffer = pUrb->transfer_buffer;
-+              dwLength = pUrb->transfer_buffer_length;
-+    }
 +
-+#ifndef MUSB_LINUX_MV21
-+    if ( !pBuffer ) {
-+      pBuffer=(void*)phys_to_virt(pUrb->transfer_dma);
-+    }
-+#endif
++STATIC void mgc_reset(MGC_LinuxCd* pThis)
++{
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    uint8_t temp;
 +
-+      /* abort the transfer */
-+    if ( !pBuffer ) { 
-+              ERR("Rx requested but no buffer was given, BAD things are happening (TM)! aborting\n");
-+              return;  
++    DBG(2, "<==\n");
++
++      temp = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++      MGC_Write8(pBase, MGC_O_HDRC_POWER, temp | MGC_M_POWER_RESET);
++    DBG(1, "%s power reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_POWER));
++
++}
++
++/**
++ * Enable the HDRC
++ * @param pThis the controller to disable
++ */
++void mgc_hdrc_enable(MGC_LinuxCd* pThis)
++{
++    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++
++    DBG(2, "<==\n");
++
++      /*  Set INT enable registers, enable interrupts */
++    MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
++    MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
++      /* don't enable suspend mode! */
++      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xf7);
++
++    DBG(1, "%s INTRUSBE reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE));
++      DBG(1, "%s INTRTXE  reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRTXE));
++      DBG(1, "%s INTRRXE  reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRRXE));
++
++      /* no test mode */
++    MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 0);
++
++#ifndef MUSB_GADGET
++    /* enable high-speed/low-power and start session & suspend IM host*/
++    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
++#else
++    {
++              uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
 +    }
-+              
-+    DBG(3, "(%p): dir=%s, type=%d, wPacketSize=%d, bRemoteAddress=%d, bRemoteEnd=%d, pBuffer=%p\n", \
-+              pUrb, (nOut)?"out":"in", usb_pipetype(nPipe), wPacketSize, bRemoteAddress, 
-+              bRemoteEnd, pBuffer); 
-+    
-+    /* Configure endpoint */  
-+    mgc_hdrc_program_end(pThis, bEnd, pUrb, nOut, bXmt, pBuffer, dwLength);
-+        
-+    /* if transmit, start it if it is time */
-+    if ( !bXmt ) {
-+              DBG(2, "==>\n");                
-+              return;
-+      }
-+              
-+      /* determine if the time is right for a periodic transfer */
-+      if( usb_pipeisoc(nPipe) || usb_pipeint(nPipe) ) {
-+              DBG(3, "check whether there's still time for periodic Tx\n");                   
-+              pEnd->dwIsoPacket = 0;
-+              wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME);
-+              
-+              if((pUrb->transfer_flags & USB_ISO_ASAP) || 
-+                 (wFrame >= pUrb->start_frame))
-+              {
-+                      pEnd->dwWaitFrame = 0;
-+                      MGC_HdrcStartTx(pThis, bEnd);
-+              } else {
-+                      pEnd->dwWaitFrame = pUrb->start_frame;
-+                      /* enable SOF interrupt so we can count down */
-+                      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xff);
-+              }
-+      } else {
-+              MGC_HdrcStartTx(pThis, bEnd);
-+      }
++#endif
 +
-+      DBG(2, "==>\n");
 +}
 +
 +/**
-+ * Start the next URB on an endpoint. Wants the _endpoint_ to be locked.
-+ * It might call MGC_LinuxStartUrb pThis needs to be locked as well..
-+ * THIS UNLOCK THE END POINT.
-+ *
-+ * @param pThis instance pointer
-+ * @param bEnd local endpoint
-+ */
-+static void mgc_linux_start_next_urb(MGC_LinuxCd* pThis, uint8_t bEnd)
-+{     
-+#ifndef MUSB_USE_HCD_DRIVER
-+    struct urb* pUrb;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+      
-+    DBG(1, "<== bEnd=%d\n", bEnd);    
-+      pUrb=MGC_GetCurrentUrb(pEnd);
-+      if ( !pUrb ) {
-+              DBG(2, "==> bEnd=%d idle\n", bEnd); 
-+              return; 
-+      }
-+      
-+      /* introduce a delay between urbs, to accomodate slow devices. The counter
-+       * is increased on every NAK/TIMEOUT and decreased on successful transfers 
-+       * (eps != 0 )
-+       */
-+      if ( mgc_slow_device_kludge_delay ) {
-+              DBG(1, "Delay mgc_slow_device_kludge_delay=%d\n",
-+                      mgc_slow_device_kludge_delay);
-+              udelay( mgc_slow_device_kludge_delay*20 );
-+      }
-+      
-+    /* check for linked URB and jump start the next one */
-+      mgc_linux_kickstart_urb(pThis, bEnd);
-+#else
-+    DBG(1, "<== bEnd=%d\n", bEnd);    
-+      if ( MUSB_IS_HST(pThis) ) { 
-+              mgc_hcd_schedule_urb(pThis);
++* Program the HDRC to stop (disable interrupts, etc.).
++*/
++void MGC_HdrcStop(MGC_LinuxCd* pThis)
++{
++    DBG(2, "<==\n");
++
++    /* flush endpoints */
++#ifdef MUSB_VIRTHUB
++      {
++              uint8_t bEnd;
++
++              mgc_hdrc_disable(pThis);
++              for(bEnd = 0; bEnd < min(16, (int)pThis->bEndCount); bEnd++) {
++                      MGC_HdrcStopEnd(pThis, bEnd);
++              }
 +      }
 +#endif
-+      DBG(1, "==>\n"); 
 +}
 +
-+/* *************************************************************************
-+ * 
-+ **************************************************************************/
++/* ------------------------------------------------------------------------ */
 +
-+/**
-+ * Try to stop traffic on the given local endpoint. Don;t worry about the 
-+ * urbs, they will be flushed from the system (later on). 
-+ *
-+ * @param pThis the controller 
-+ * @param bEnd the endpoint number.
-+ */
-+void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd)
++#define MUSB_HDRC_ULPI_ACCESS
++#ifdef MUSB_HDRC_ULPI_ACCESS
++
++uint8_t MGC_HdrcUlpiVbusControl(MGC_LinuxCd* pThis, uint8_t bExtSource, uint8_t bExtIndicator)
 +{
-+      uint16_t wCsr;
-+      uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+      const uint8_t reg=(bEnd)?MGC_O_HDRC_RXCSR:MGC_O_HDRC_CSR0;
++    uint8_t bVal;
++    uint8_t* pBase = pThis->pRegs;
 +
-+    DBG(2, "<== ep%d\n", bEnd);       
-+      wCsr = MGC_ReadCsr16(pBase, reg, bEnd);
-+      wCsr &= (bEnd)?~MGC_M_RXCSR_H_REQPKT:~MGC_M_CSR0_H_REQPKT;
-+      MGC_WriteCsr16(pBase, reg, bEnd, wCsr);
-+    DBG(2, "==>\n");  
-+}
++    /* ensure not powered down */
++    if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
++              return FALSE;
++    }
 +
-+/* *************************************************************************
-+ 
-+ **************************************************************************/
++    bVal = bExtSource ? MGC_M_ULPI_VBUSCTL_USEEXTVBUS : 0;
++    bVal |= bExtIndicator ? MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND : 0;
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_VBUSCTL, bVal);
 +
-+/**
-+ * Service the default endpoint (ep0) as host.
-+ * @param pThis this
-+ * @param wCount current byte count in FIFO
-+ * @param pUrb URB pointer for EP0
-+ * @return TRUE if more packets are required for this transaction
-+ */ 
-+static uint8_t mgc_hdrc_service_host_default(MGC_LinuxCd* pThis, 
-+      uint16_t wCount, struct urb* pUrb)
++    return TRUE;
++}
++
++uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData)
 +{
-+    uint8_t bMore = FALSE;
-+    uint8_t* pFifoDest = NULL;
-+    uint16_t wFifoCount = 0;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]);
-+    MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;
++    uint8_t bCtl = 0;
++      uint8_t* pBase = pThis->pRegs;
 +
-+    DBG(2, "<== (wCount=%04x, pUrb=%lx, bStage=%02x)\n",  
-+      wCount, (unsigned long)pUrb, pThis->bEnd0Stage); 
++    /* ensure not powered down */
++    if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
++              return FALSE;
++    }
 +
-+    if(MGC_END0_IN == pThis->bEnd0Stage) {
-+        /* we are receiving from peripheral */
-+        pFifoDest = pUrb->transfer_buffer + pUrb->actual_length;
-+              wFifoCount = min(wCount, ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length)));
++    /* polled */
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr);
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL,
++      MGC_M_ULPI_REGCTL_READNOTWRITE | MGC_M_ULPI_REGCTL_REG);
 +
-+      DBG(3, "Receiving %d bytes in &%p[%d] (pUrb->actual_length=%u)\n", 
-+              wFifoCount, pUrb->transfer_buffer, (unsigned int)pUrb->actual_length, 
-+                      pUrb->actual_length ); 
 +
-+              MGC_HdrcUnloadFifo(pBase, 0, wFifoCount, pFifoDest);
++ while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) {
++      bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL);
++   }
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+              pEnd->dwTotalRxBytes += wFifoCount;
-+              pEnd->dwTotalRxPackets++;
-+#endif
++    *pbData = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGDATA);
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
++    return TRUE;
++}
 +
-+              pUrb->actual_length += wFifoCount;
-+              if((pUrb->actual_length < pUrb->transfer_buffer_length) &&
-+                 (wCount == pEnd->wPacketSize))
-+              {
-+                      bMore = TRUE;
-+              }
-+    } else {
-+        /* we are sending to peripheral */
-+        if((MGC_END0_START == pThis->bEnd0Stage) && 
-+                      (pRequest->bmRequestType & USB_DIR_IN)) 
-+              {
-+                      DBG(3, "just did setup, switching to IN\n");
-+      
-+                      /* this means we just did setup; switch to IN */
-+                      pThis->bEnd0Stage = MGC_END0_IN;
-+                      bMore = TRUE;
-+          
-+#ifdef MUSB_CONFIG_PROC_FS
-+          pEnd->dwTotalTxBytes += 8;
-+          pEnd->dwTotalTxPackets++;
-+#endif
-+              } else if(pRequest->wLength && (MGC_END0_START == pThis->bEnd0Stage)) {
-+                      pThis->bEnd0Stage = MGC_END0_OUT;
-+                      pFifoDest = (uint8_t*)(pUrb->transfer_buffer + pUrb->actual_length);
-+                      wFifoCount = min(pEnd->wPacketSize, 
-+                      ((uint16_t)(pUrb->transfer_buffer_length - pUrb->actual_length)));
-+                      DBG(3, "Sending %d bytes to %p\n", wFifoCount, pFifoDest); 
-+                      MGC_HdrcLoadFifo(pBase, 0, wFifoCount, pFifoDest);
++uint8_t MGC_HdrcWriteUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t bData)
++{
++    uint8_t bCtl = 0;
++      uint8_t* pBase = pThis->pRegs;
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+                      pEnd->dwTotalTxBytes += wFifoCount;
-+                      pEnd->dwTotalTxPackets++;
-+#endif
-+                      pEnd->dwRequestSize = wFifoCount;
-+                      pUrb->actual_length += wFifoCount;
-+                      if(wFifoCount) {
-+                              bMore = TRUE;
-+                      }
-+              }
++    /* ensure not powered down */
++    if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
++              return FALSE;
 +    }
 +
-+    return bMore;
++    /* polled */
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr);
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGDATA, bData);
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, MGC_M_ULPI_REGCTL_REG);
++
++    while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) {
++              bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL);
++    }
++
++    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
++
++    return TRUE;
 +}
++#endif
 +
-+/* *************************************************************************
-+ * Default end (end 0) 
-+ **************************************************************************/
++/* ------------------------------------------------------------------------ */
 +
 +/**
-+ * Handle default endpoint interrupt as host. Only called in IRQ time
-+ * from the LinuxIsr() interrupt service routine.
-+ * @param pThis this
-+ */
-+void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis)
++* Discover HDRC configuration.
++* @param wType
++* @param pThis the controller instance
++*/
++STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis)
 +{
-+    struct urb* pUrb;
-+    unsigned long flags;
-+    uint16_t wCsrVal, wCount;
-+    int status = USB_ST_NOERROR;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[0]);
-+    uint8_t bVal, bOutVal = 0, bComplete = FALSE, bError = FALSE;
-+      struct usb_descriptor_header *header;
-+      MUSB_DeviceRequest* pRequest;
++#ifdef MUSB_AHB_ID
++    uint32_t dwData;
++#endif
++    uint8_t reg, bType=0;
++    uint16_t wRelease, wRelMajor, wRelMinor;
++    char aInfo[78], aRevision[32], aDate[12];
++    void* pBase = pThis->pRegs;
 +
 +    DBG(2, "<==\n");
 +
-+    spin_lock(&pEnd->Lock);
-+    pUrb = MGC_GetCurrentUrb(pEnd);    
++    /* log core options */
++    MGC_SelectEnd(pBase, 0);
++    reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_CONFIGDATA, 0);
 +
-+      /* check URB */
-+#ifdef MUSB_PARANOID
-+    if( pUrb && (pUrb->hcpriv!=pEnd)) { 
-+        ERR("==> corrupt URB %p!!! from now on \"bad things will happen\"\n", 
-+                      pUrb);           
-+              spin_unlock(&pEnd->Lock);
-+              return;
-+    } 
++    strcpy(aInfo,(reg & MGC_M_CONFIGDATA_UTMIDW)?"UTMI-16":"UTMI-8");
++    if(reg & MGC_M_CONFIGDATA_DYNFIFO) {
++        strcat(aInfo, ", dyn FIFOs");
++    }
++    if(reg & MGC_M_CONFIGDATA_MPRXE) {
++        strcat(aInfo, ", bulk combine");
++    }
++    if(reg & MGC_M_CONFIGDATA_MPTXE) {
++        strcat(aInfo, ", bulk split");
++    }
++    if(reg & MGC_M_CONFIGDATA_HBRXE) {
++        strcat(aInfo, ", HB-ISO Rx");
++    }
++    if(reg & MGC_M_CONFIGDATA_HBTXE) {
++        strcat(aInfo, ", HB-ISO Tx");
++    }
++    if(reg & MGC_M_CONFIGDATA_SOFTCONE) {
++        strcat(aInfo, ", SoftConn");
++    }
++
++    INFO("ConfigData=0x%02x (%s)\n", reg, aInfo);
++
++#ifdef MUSB_AHB_ID
++    dwData = MGC_Read32(pBase, 0x404);
++    sprintf(aDate, "%04d-%02x-%02x", (dwData & 0xffff),
++      (dwData >> 16) & 0xff,
++      (dwData >> 24) & 0xff);
++    dwData = MGC_Read32(pBase, 0x408);
++    printk("ID2=%lx\n", (long unsigned)dwData);
++    dwData = MGC_Read32(pBase, 0x40c);
++    printk("ID3=%lx\n", (long unsigned)dwData);
++    bType = MGC_Read8(pBase, 0x400);
++    pThis->bIsMultipoint=('M' == bType)
++      ? TRUE : FALSE;
++#else
++    bType = 'x';
++    pThis->bIsMultipoint=(MUSB_CONTROLLER_MHDRC == wType)
++      ? TRUE : FALSE;
 +#endif
 +
-+    SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);    
-+    MGC_SelectEnd(pBase, 0);
-+    wCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0);
-+    wCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
-+    bVal = (uint8_t)wCsrVal;
++      /* log release info */
++    wRelease = MGC_Read16(pBase, 0x6c);
++    wRelMajor = (wRelease >> 10) & 0x1f;
++    wRelMinor = wRelease & 0x3ff;
++    snprintf(aRevision, 32, "%d.%d%s", wRelMajor,
++          wRelMinor, (wRelease & 0x8000) ? "RC" : "");
++    INFO("%cDRC version %s %s\n", bType, aRevision, aDate);
 +
-+    DBG(2, "<== CSR0=%04x, wCount=%04x\n", wCsrVal, wCount); 
 +
-+    /* if we just did status stage, we are done */
-+    if(MGC_END0_STATUS == pThis->bEnd0Stage) {
-+              bComplete = TRUE;
-+    }
++      /* configure ep0 */
++    pThis->aLocalEnd[0].wMaxPacketSizeTx = MGC_END0_FIFOSIZE;
++    pThis->aLocalEnd[0].wMaxPacketSizeRx = MGC_END0_FIFOSIZE;
 +
-+    /* prepare status */
-+    if((MGC_END0_START == pThis->bEnd0Stage) && !wCount &&
-+       (wCsrVal & MGC_M_CSR0_RXPKTRDY))
-+    {
-+              DBG(2, "missed data\n"); 
++      /* discover endpoint configuration */
++    pThis->bBulkTxEnd = 0;
++    pThis->bBulkRxEnd = 0;
++    pThis->bEndCount = 1;
++    pThis->wEndMask = 1;
 +
-+        /* just started and got Rx with no data, so probably missed data */
-+        status = USB_ST_SHORT_PACKET;
-+              bError = TRUE;
-+              
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
++#ifdef MUSB_C_DYNFIFO_DEF
++    if(!(reg & MGC_M_CONFIGDATA_DYNFIFO)) {
++        ERR("Dynamic FIFOs not detected in hardware; please rebuild software\n");
++              return FALSE;
 +    }
-+    
-+    if(bVal & MGC_M_CSR0_H_RXSTALL) {
-+              DBG(2, "STALLING ENDPOINT 0\n"); 
-+        status = USB_ST_STALL;
-+              bError = TRUE;          
-+    } else if(bVal & MGC_M_CSR0_H_ERROR) {
-+              DBG(3, "ep0 no response (error)\n");
-+              DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); );
++#else
++    if (reg & MGC_M_CONFIGDATA_DYNFIFO) {
++        ERR("Dynamic FIFOs detected in hardware; please rebuild\n");
++              return FALSE;
++    }
++#endif
 +
-+        status = USB_ST_NORESPONSE;
-+              bError = TRUE;
-+    } else if(bVal & MGC_M_CSR0_H_NAKTIMEOUT) {
-+              DBG(2, "ep0 NAK timeout pEnd->bRetries=%d\n", pEnd->bRetries); 
++      MGC_HdrcConfigureEps(pThis);
 +
-+        if( ++pEnd->bRetries < MUSB_MAX_RETRIES) {
-+                      /* cover it up if retries not exhausted */
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
-+              } else {
-+                      DBG(3, "no response (NAK timeout)\n");
-+                      DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, 0); );
-+                      pEnd->bRetries=0;
-+                      status = USB_ST_NORESPONSE;
-+                      bError = TRUE;
-+              }
++#ifdef MUSB_HOST
++      MGC_InitLocalEndPoints(pThis);
++#endif
++
++      /* claim the bulk tx/rx ends */
++    if(pThis->bBulkTxEnd) {
++              pThis->aLocalEnd[pThis->bBulkTxEnd].bIsClaimed = TRUE;
 +    }
 +
-+    if(USB_ST_NORESPONSE == status) {
-+              DBG(2, "ep0 aborting\n"); 
-+      
-+              /* use the proper sequence to abort the transfer */
-+              if(bVal & MGC_M_CSR0_H_REQPKT) {
-+                      bVal &= ~MGC_M_CSR0_H_REQPKT;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
-+                      bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
-+              } else {
-+                      bVal |= MGC_M_CSR0_FLUSHFIFO;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
-+                      bVal &= ~MGC_M_CSR0_H_NAKTIMEOUT;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bVal);
-+              }
-+              
-+              MGC_WriteCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0, 0);
++    if(pThis->bBulkRxEnd) {
++              pThis->aLocalEnd[pThis->bBulkRxEnd].bIsClaimed = TRUE;
 +    }
 +
-+    if(bError) {
-+              DBG(3, "ep0 handling error\n");
++    return TRUE;
++}
 +
-+        /* clear it */
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
++/**************************************************************************
++ * Linux HCD functions
++**************************************************************************/
 +
-+#ifdef MUSB_CONFIG_PROC_FS
-+        switch(pThis->bEnd0Stage) {
-+                      case MGC_END0_START:
-+                      case MGC_END0_OUT:
-+                              pEnd->dwErrorTxPackets++;
-+                              break;
-+                      case MGC_END0_IN:
-+                              pEnd->dwErrorRxPackets++;
-+                              break;
-+              }
++#ifdef MUSB_V26
++#define IS_TIMER_INITILIZED(_t) ((_t)->magic==TIMER_MAGIC)
++#else
++#define IS_TIMER_INITILIZED(_t) (1)
 +#endif
 +
++/**
++ * Generic timer creation.
++ * @param pThis instance pointer
++ * @param pfFunc timer fire callback
++ * @param pParam parameter for callback
++ * @param millisecs how many milliseconds to set
++ */
++void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long),
++      unsigned long pParam, unsigned long millisecs)
++{
++    DBG(2, "<==\n");
++
++    init_timer(&(pThis->Timer));
++    pThis->Timer.function = pfFunc;
++    pThis->Timer.data = (unsigned long)pParam;
++    pThis->Timer.expires = jiffies + (HZ * millisecs) / 1000;
++    add_timer( &(pThis->Timer) );
++}
++
++#ifdef MUSB_V26
++void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
++      unsigned iMemFlags, dma_addr_t* pDmaAddress)
++{
++    /* for now, just kmalloc it */
++    MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv);
++
++#ifdef MUSB_PARANOID
++    if ( !pThis ) {
++      ERR("cannot find the controller, cannot allocate the memory\n");
++      return 0;
 +    }
++#endif
 +
-+    if(!pUrb) {
-+              /* stop endpoint since we have no place for its data, this 
-+               * SHOULD NEVER HAPPEN! */
-+              DBG(1, "no URB for end 0\n");
++    DBG(2, "<== allocating memory on bus (%s), %d, pDmaAddress=%p\n",
++      pBus->bus_name, pBus->busnum, pDmaAddress );
++    return MGC_AllocBufferMemory(pThis, nSize, iMemFlags, pDmaAddress);
++}
 +
-+        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
-+        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO);
-+        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 0);
++void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
++                              void* address, dma_addr_t dma)
++{
++    MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv);
 +
-+              /* start next URB that might be queued for it */
-+              spin_unlock(&pEnd->Lock);
-+              DBG(2, "==>\n");
-+              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);            
++#ifdef MUSB_PARANOID
++    if ( !pThis ) {
++              KFREE(address);
++      ERR("cannot find the controller, cannot free the memory properly\n");
 +              return;
 +    }
-+    
-+    if(!bComplete && !bError) {
-+              
-+        /* call common logic and prepare response */
-+        if( mgc_hdrc_service_host_default(pThis, wCount, pUrb) ) {
-+                      /* more packets required */
-+                      bOutVal = (MGC_END0_IN == pThis->bEnd0Stage) ? 
-+                      MGC_M_CSR0_H_REQPKT : MGC_M_CSR0_TXPKTRDY;      
-+                 DBG(3, "Need more bytes bOutVal=%04x\n", bOutVal); 
-+              } else {
-+                      /* data transfer complete; perform status phase */
-+                      bOutVal = MGC_M_CSR0_H_STATUSPKT | 
-+                        (usb_pipeout(pUrb->pipe) ? MGC_M_CSR0_H_REQPKT : 
-+                         MGC_M_CSR0_TXPKTRDY);
-+                         
-+                      /* flag status stage */
-+                      pThis->bEnd0Stage = MGC_END0_STATUS;
-+                      DBG(3, "Data transfer complete, status phase bOutVal=%04x\n", \
-+                              bOutVal); 
-+              }
++#endif
++
++    MGC_FreeBufferMemory(pThis, nSize, address, dma);
++}
++#endif
++
++
++#if defined(MUSB_V26) || defined(MUSB_GADGET)
++/**
++ * Allocate memory for a buffer that might use DMA.
++ *
++ * @param pThis
++ * @param bytes
++ * @param gfp_flags
++ * @param dma NULL when DMAble memeory is not requested.
++ */
++void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma) {
++    void* addr = NULL;
++
++    if ( dma ) {
++        *dma = DMA_ADDR_INVALID;
 +    }
 +
-+    /* write CSR0 if needed */
-+    if(bOutVal) {
-+        MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, bOutVal);
++#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21)
++   {
++      KMALLOC(addr, bytes, gfp_flags);
++              if ( addr && dma ) {
++                      *dma = virt_to_phys(addr);
++      }
++              DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma);
++     }
++#else
++    {
++      KMALLOC(addr, bytes, gfp_flags);
++              if ( addr && dma ) {
++                      *dma = virt_to_phys(addr);
++      }
++
++              DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma);
++     }
++#endif
++
++    if ( addr ) {
++              memset(addr, 0, bytes);
 +    }
-+    
-+    /* call completion handler if done */
-+    if(bComplete || bError) {
-+      DBG(3, "completing cntrl URB %p, status=%d, len=%x\n", \
-+                      pUrb, status, pUrb->actual_length); 
-+      
-+              /* Hub Class not supported */
-+              if((pUrb->dev == pThis->pRootDevice))
-+              {
-+                      pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;
 +
-+                      if((USB_REQ_GET_DESCRIPTOR == pRequest->bRequest) && 
-+                              (USB_DIR_IN == pRequest->bmRequestType) && 
-+                              (USB_DT_DEVICE == pUrb->setup_packet[3]) &&
-+                              (pUrb->setup_packet[6] >= USB_DT_DEVICE_SIZE))
-+                      {
-+                              
-+                              header = (struct usb_descriptor_header*)pUrb->transfer_buffer;
-+                              if((header->bDescriptorType == USB_DT_DEVICE) &&
-+                                      (*((char*)pUrb->transfer_buffer + 4) == USB_CLASS_HUB))
-+                              {
-+                                      printk("Hub Class NOT support \n");
-+                                      /* Will pass error to upper stack */
-+                                      status = -ENODEV;
-+                              }
-+                      }
-+              }
-+              if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
-+                      spin_unlock(&pEnd->Lock);
-+                      pUrb->status = status;  
-+                      if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 )  {
-+                              mgc_linux_start_next_urb(pThis, 0);
-+                      }       
-+              } else {
-+                      ERR("*** pUrb=%p is not queued to bEnd=%d\n", pUrb,
-+                              pEnd->bEnd);
-+              }
-+    } else {
-+              spin_unlock(&pEnd->Lock);
-+      }
++    return addr;
++}
++
++/**
++ * Free memory previously allocated with AllocBufferMemory.
++ * @param pThis
++ * @param bytes
++ * @param dma
++ */
++void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma) {
++
++    DBG(2, "<== freeing bytes=%d, address=%p, dma=%p\n", bytes, address, (void*)dma);
 +
++#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21)
 +      DBG(2, "==>\n");
-+      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
++#else
++    {
++      KFREE(address);
++    }
++#endif
++    DBG(2, "==>\n");
 +}
++#endif
 +
-+/**************************************************************************
-+ * EP1-n Tx and Rx data 
-+ **************************************************************************/
++/* ------------------------------------------------------------------------ */
 +
-+static void complete_ep_urb(MGC_LinuxCd* pThis, MGC_LinuxLocalEnd* pEnd,
-+      struct urb* pUrb, int toggle)
++#ifndef MUSB_V26_POST10
++/**
++ * Private per-device allocation
++ * @param pDevice Linux USBD device pointer
++ * @return status code
++ */
++STATIC int mgc_linux_alloc_device(struct usb_device *pDevice)
 +{
 +
-+      if (pUrb->status==USB_ST_STALL) {
-+              toggle=0;
-+      }
-+      
-+      /* save data toggle */
-+      
-+      usb_settoggle(pUrb->dev, pEnd->bEnd, (pEnd->bIsTx)?1:0, toggle);
-+      /* we re-use bulk, so re-programming required */
-+      pEnd->bIsReady = FALSE;                 
-+
-+      if (pUrb->status) {
-+              DBG(1, "completing Tx URB=%p, status=%d, len=%x\n", \
-+                      pUrb, pUrb->status, pUrb->actual_length); 
-+      }               
++    DBG(2, "<==>\n");
++    return 0;
 +
-+      if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
-+              spin_unlock(&pEnd->Lock);
-+              if ( mgc_linux_complete_urb(pThis, pEnd, pUrb)==0 )  {
-+                      mgc_linux_start_next_urb(pThis, pEnd->bEnd);
-+              }       
-+      } else {
-+              ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb,
-+                      pEnd->bEnd);
-+      }
 +}
-+ 
++
 +/**
-+ * Service a Tx-Available interrupt for the given endpoint.
-+ 
-+ * @param pThis instance pointer
-+ * @param bEnd local endpoint
++ * Private per-device cleanup
++ * @param pDevice Linux USBD device pointer
++ * @return 0 (success)
 + */
-+void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd)
++STATIC int mgc_linux_free_device(struct usb_device * pDevice)
 +{
-+      int skip=0;
-+    struct urb* pUrb;
-+    unsigned long flags;
-+    uint16_t wTxCsrVal, wVal=0;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    uint32_t dev_status = 0;  
++    DBG(2, "<==>\n");
++    return 0;
++}
 +
-+    DBG(1, "<==\n");
++int MGC_LinuxHubSuspend(struct usb_bus *pBus) {
++      return 0;
++}
 +
-+    spin_lock(&pEnd->Lock);
-+    pUrb = MGC_GetCurrentUrb(pEnd);
-+      if ( !pUrb ) {
-+              MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE;
-+              spin_unlock(&pEnd->Lock);
-+              DBG(2, "==> tx ep empty\n");            
-+              return; 
-+      }
++int MGC_LinuxHubResume(struct usb_bus *pBus) {
++      return 0;
++}
 +
-+      if ( !pUrb->hcpriv ) {
-+              DBG(2, "==> kickstarting it\n");        
-+              mgc_linux_kickstart_urb(pThis, bEnd);
-+              spin_unlock(&pEnd->Lock);
-+              return;
-+      }
++#endif
 +
-+      if ( !MUSB_IS_HST(pThis) ) {
-+              complete_ep_urb(pThis, pEnd, pUrb, 0);
-+              return;
-+      }
-+      
++/* ------------------------------------------------------------------------ */
 +
-+    SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
-+    MGC_SelectEnd(pBase, bEnd);
++/**
++ * Get the current frame number.
++ * @param struct usb_hcd pointer to usb_hcd structure
++ * @return frame number
++ */
++static inline int mgc_get_frame_number(MGC_LinuxCd* pThis) {
++      uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    const int no=(int)MGC_Read16(pBase, MGC_O_HDRC_FRAME);
 +
-+    wVal = wTxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
-+      
-+#if MUSB_DEBUG > 0
-+    /* check URB */
-+    if(       pUrb && (pUrb->hcpriv != pEnd) ) {
-+              ERR("==> end %d has corrupt URB %lx!\n", bEnd, (unsigned long)pUrb);
-+              spin_unlock(&pEnd->Lock);               
-+              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);            
-+              return;
-+    }
-+#endif
++    DBG(2, "<==> %d\n", no);
++      return no;
++}
 +
-+    DBG(3, "end %d wTxCsrVal=%04x\n", bEnd, wTxCsrVal); 
-+      
-+      do {            
-+              uint32_t status = 0;
-+              
-+              /* check for errors */
-+              if(wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) {
-+                      pEnd->bStalled=TRUE;
-+                      DBG(1, "TX end %d stall\n", bEnd); 
-+                      status = USB_ST_STALL;                  
-+                      MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
-+              } else if(wTxCsrVal & MGC_M_TXCSR_H_ERROR) {
-+                      WARN("TX data error on ep=%d\n", bEnd);         
-+                      status = USB_ST_NORESPONSE;
-+                      dev_status = status;
-+                      /* do the proper sequence to abort the transfer */
-+                      wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
-+                      wVal |= MGC_M_TXCSR_FLUSHFIFO;
-+                              
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
-+      
-+#ifdef MUSB_CONFIG_PROC_FS
-+                      pEnd->dwErrorTxPackets++;
-+#endif
-+              } 
-+              else if( wTxCsrVal & MGC_M_TXCSR_H_NAKTIMEOUT ) {
-+                      /* cover it up if retries not exhausted */
-+                      if( pUrb->status==-EINPROGRESS && ++pEnd->bRetries < MUSB_MAX_RETRIES ) 
-+                      {       
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, 
-+                                      MGC_M_TXCSR_TXPKTRDY);
-+                                      
-+                              MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
-+                              DBG(2, "tx error on ep%d, mgc_slow_device_kludge_delay=%d\n", 
-+                                      bEnd, mgc_slow_device_kludge_delay);
-+                              spin_unlock(&pEnd->Lock);
-+                              DBG(2, "==> cover tx error\n");                                 
-+                              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+                              return;
-+                      }
-+                      
-+                      if ( pUrb->status==-EINPROGRESS ) {
-+                              status = -ECONNRESET;
-+                      }
++/*
++ */
++int MGC_LinuxGetFrameNumber(struct usb_device* pDevice)
++{
++      MGC_LinuxCd* pThis=hcd_to_musbstruct(pDevice->bus->hcpriv);
++      return mgc_get_frame_number( pThis );
++}
 +
-+                      WARN("device not responding on ep=%d\n", bEnd);         
 +
-+      
-+                      /* do the proper sequence to abort the transfer */
-+                      wVal &= ~MGC_M_TXCSR_FIFONOTEMPTY;
-+                      wVal |= MGC_M_TXCSR_FLUSHFIFO;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, 0);
-+      
-+#ifdef MUSB_CONFIG_PROC_FS
-+                      pEnd->dwErrorTxPackets++;
-+#endif                        
-+                      pEnd->bRetries=0;                       
-+              } else if( wTxCsrVal & MGC_M_TXCSR_FIFONOTEMPTY ) {
-+                      /* whopps, dbould buffering better be enabled */
-+#ifdef MUSB_PARANOID
-+      /* guess what?? */
++/**************************************************************************
++ * Linux driver hooks
++**************************************************************************/
++
++/**
++ * Generic Interrupt Service Routine.
++ * @param pThis the controller
++ */
++static irqreturn_t mgc_linux_isr(MGC_LinuxCd* pThis)
++{
++    uint32_t nSource;
++#if MUSB_DEBUG > 0
++    uint16_t wIntrTxCheck, wIntrRxCheck;
 +#endif
-+                      skip=TRUE;
-+                      break;
-+              }
-+      
-+              if ( status ) { 
-+                              
-+                      pUrb->status=status; /* */
++    const void* pBase = pThis->pRegs;
++    uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +
-+                      if ( USB_ST_STALL!=status ) {
-+                              DBG(1, "Tx error on bEnd=%d, pUrb=%p, status=%d, proto=%s\n", 
-+                                      bEnd, pUrb, status, decode_urb_protocol(pUrb)); 
-+                              DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); );
-+                      }
-+                      
-+                      /* reset error bits */
-+                      wVal &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
-+                              MGC_M_TXCSR_H_NAKTIMEOUT);
-+                      wVal |= MGC_M_TXCSR_FRCDATATOG;         
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wVal);
-+              }
-+              
-+      } while (0);
++    uint8_t power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
 +
++    uint8_t bIntrUsbValue=MGC_Read8(pBase, MGC_O_HDRC_INTRUSB);
++    uint16_t wIntrTxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
++      uint16_t wIntrRxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRRX);
 +
-+      if ( !skip && pUrb->status==-EINPROGRESS ) {
-+              mgc_linux_packet_tx(pThis, bEnd);
-+      
++              nSource = bIntrUsbValue | wIntrTxValue | wIntrRxValue;
++      DEBUG_CODE(10,  if (!nSource) { \
++                      INFO("IRQ [mode=%s] nSource=%d\n", MUSB_MODE(pThis), nSource); } );
 +
-+    /* complete the current request or start next tx transaction */
-+    if ( pUrb->status!=-EINPROGRESS ) {
-+              int toggle=(pUrb->status==USB_ST_STALL) 
-+                      ? 0
-+                      : ((wVal & MGC_M_TXCSR_H_DATATOGGLE) ? 1 : 0);          
-+              pUrb->actual_length = pEnd->dwOffset;   
-+              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+              complete_ep_urb(pThis, pEnd, pUrb, toggle);
-+    } else {
-+              spin_unlock(&pEnd->Lock);
-+              if ( !skip ) {          
 +
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, 
-+                              MGC_M_TXCSR_TXPKTRDY);
-+              } 
-+              DBG(1, "==>\n");
-+              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+    }
-+}
++    if (!nSource) {
++              RETURN_IRQ_NONE;
++      }
 +
-+/**
-+ * Service an Rx-Ready interrupt for the given endpoint; see section 18.2.1
-+ * of the manual for details.
-+ * @param pThis instance pointer
-+ * @param bEnd local endpoint
-+ */
-+void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
-+{
-+    struct urb* pUrb;
-+    unsigned long flags;
-+    uint16_t wRxCount, wRxCsrVal, wVal=0;     
-+    uint8_t bIsochError = FALSE;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bEnd]);
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++      DBG(2, "<== [%ld]: IRQ RECEIVED [devmode=%s, hwmode=%s] IntrUSB=%02x, IntrUSBE=%02x, IntrTx=%04x, IntrRx=%04x\n",
++              jiffies, MUSB_MODE(pThis), (devctl & MGC_M_DEVCTL_HM)?"host":"function",
++              bIntrUsbValue, MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE),
++              wIntrTxValue, wIntrRxValue);
 +
-+      DBG(2, "<== end%d\n", bEnd); 
-+    spin_lock(&pEnd->Lock);   
-+      DBG(3, "locked end%d, pUrb=%p\n", bEnd, MGC_GetCurrentUrb(pEnd));
-+      
-+    pUrb = MGC_GetCurrentUrb(pEnd);
-+      if ( !pUrb ) {
-+              /* THIS SHOULD NEVER HAPPEN */
-+              /* stop endpoint since we have no place for its data */
-+              MGC_SLOW_DEVICE_KLUDGE_DELAY_DECREASE;
-+              spin_unlock(&pEnd->Lock);                       
-+              DBG(1, "==> no RX URB on end %d!\n", bEnd);             
-+              return; 
-+      }
 +
-+      if ( !pUrb->hcpriv ) {
-+              DBG(1, "==> kickstarting it\n");        
-+              mgc_linux_kickstart_urb(pThis, bEnd);
-+              spin_unlock(&pEnd->Lock);
-+              return;
-+      }
++      /* Recent IPs return the right values (not the masked one) */
++      bIntrUsbValue &= MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE);
++
 +
++    /* corruption check */
 +#ifdef MUSB_PARANOID
-+    /* check URB */
-+    if ( pUrb->hcpriv!=pEnd ) {
-+        ERR("==> pUrb=%p on bEnd=%d (hcpriv=%p) is corrupt!\n", pUrb, bEnd, pUrb->hcpriv);            
-+              /* about the urb? */
-+              spin_unlock(&pEnd->Lock);
-+              return;         
++    if ( MGC_ISCORRUPT(pThis) ) {
++              INFO("stopping before ISR, the controller structure is corrupted\n");
++              MGC_HdrcStop(pThis);
++              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
++
++      RETURN_IRQ_HANDLED;
 +    }
 +#endif
 +
-+      if ( !MUSB_IS_HST(pThis) ) {
-+              complete_ep_urb(pThis, pEnd, pUrb, 0);
-+              return;
-+      }       
++#ifdef MUSB_DMA
++      /* ### DMA intr handler added */
++      if ( pThis->pDmaController->pfDmaControllerIsr(pThis->pDmaController->pPrivateData) ) {
++              DBG(1, "%s: ******** DMA interrupt *************\n",__FUNCTION__);
++              nSource |= 1;
++      }
++#endif
 +
-+      SPIN_LOCK_IRQSAVE(&pThis->Lock, flags);
-+    MGC_SelectEnd(pBase, bEnd);
-+    wVal = wRxCsrVal = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd);
-+      wRxCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
 +
-+      DBG(3, "end %d wRxCsrVal=%04x, wRxCount=%d, pUrb->actual_length=%d\n", bEnd, 
-+              wRxCsrVal, wRxCount, pUrb->actual_length); 
++   /* the core can interrupt us for multiple reasons, I.E. more than an
++    * interrupt line can be asserted; service the globa interrupt first.
++    * Global interrups are used to signal connect/disconnect/vbuserr
++      * etc. processed in two phase */
++    if ( bIntrUsbValue ) {
++              DBG(3, "** IRQ [mode=%s] nSource=%d | DEVCTL :0x%x | IntrUsb:0x%x \n", \
++              MUSB_MODE(pThis), nSource, MGC_Read8(pBase, MGC_O_HDRC_DEVCTL), bIntrUsbValue);
++      mgc_hdrc_service_usb_stage0(pThis, bIntrUsbValue, devctl, power);
++    }
++
++#ifdef MUSB_PARANOID
++      if ( wIntrTxValue || wIntrRxValue ) { /* got data! */
++              if ( ((devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_HST(pThis)))
++                      || (!(devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_DEV(pThis))) )
++              {
++                      if ( bIntrUsbValue ) {
++                              mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
++                      } else {
++                              WARN("early interrupt while in hm=%d: otg machine hasn't done yet\n",
++                                      devctl & MGC_M_DEVCTL_HM);
++                      }
 +
-+      do {            
-+              uint32_t status = 0;
-+              
-+              /* check for errors, concurrent stall & unlink is not really
-+               * handled yet! */
-+              if ( wRxCsrVal & MGC_M_RXCSR_H_RXSTALL ) {
-+                      pEnd->bStalled=TRUE;
-+                      DBG(1, "RX end %d STALL\n", bEnd); 
-+                      status = USB_ST_STALL;
-+              } else if(wRxCsrVal & MGC_M_RXCSR_H_ERROR) {
-+                      DBG(1, "end %d Rx error\n", bEnd); 
-+                      DEBUG_CODE(1, MGC_HDRC_DUMPREGS(pThis, bEnd); );
-+                      status=-ECONNRESET;                     
-+              
-+                      /* do the proper sequence to abort the transfer */
-+                      wVal &= ~MGC_M_RXCSR_H_REQPKT;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0);
-+      
-+#ifdef MUSB_CONFIG_PROC_FS
-+                      pEnd->dwErrorRxPackets++;
++                      RETURN_IRQ_HANDLED;
++              }
++      }
 +#endif
-+              } else if(wRxCsrVal & MGC_M_RXCSR_DATAERROR) {
 +
-+                      if (PIPE_BULK == pEnd->bTrafficType) {
-+                              /* cover it up if retries not exhausted, slow devices might  
-+                               * not answer quickly enough: I was expecting a packet but the 
-+                               * packet didn't come. The interrupt is generated after 3 failed
-+                               * attempts, it make MUSB_MAX_RETRIESx3 attempts total..
-+                               */
-+                              if ( pUrb->status==-EINPROGRESS &&  
-+                                      ++pEnd->bRetries < MUSB_MAX_RETRIES) 
-+                              {
-+                                      /* silently ignore it */
-+                                      wRxCsrVal &= ~ MGC_M_RXCSR_DATAERROR;
-+                                      wRxCsrVal &= ~MGC_M_RXCSR_RXPKTRDY;
-+                                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd,
-+                                                 wRxCsrVal | MGC_M_RXCSR_H_REQPKT);
-+                                                 
-+                                      MGC_SLOW_DEVICE_KLUDGE_DELAY_INCREASE;
-+                                      DBG(1, "rx error on ep%d, mgc_slow_device_kludge_delay=%d\n", 
-+                                              bEnd, mgc_slow_device_kludge_delay);
-+                                      spin_unlock(&pEnd->Lock);
-+                                      DBG(2, "==> cover rx error\n"); 
-+                                      SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+                                      return;
-+                              } 
-+                              
-+                              if ( pUrb->status==-EINPROGRESS ) {
-+                                      DBG(-1, "urb=%p, protocol=%s timed out\n", pUrb,  
-+                                              decode_urb_protocol(pUrb));
-+                                      status=-ECONNRESET;
-+                              }
-+                              
-+                              wVal &= ~MGC_M_RXCSR_H_REQPKT;                  
-+                              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
-+                              MGC_WriteCsr8(pBase, MGC_O_HDRC_RXINTERVAL, bEnd, 0);                   
-+                              pEnd->bRetries=0;
-+                              
-+                              /* do the proper sequence to abort the transfer; 
-+                               * am I dealing with a slow device maybe? */
-+                              DBG(3, "end=%d device not responding\n", bEnd);                 
-+                              
-+                      } else if(PIPE_ISOCHRONOUS == pEnd->bTrafficType) {
-+                              DBG(3, "bEnd=%d Isochronous error\n", bEnd); 
-+                              bIsochError = TRUE;
-+                      }
-+                      
++    /* ignore requests when in error */
++    if( MUSB_IS_ERR(pThis) ) {
++              if ( bIntrUsbValue) {
++                      mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
++              } else {
++                      ERR("Error mode, please ZAP the driver!\n");
++                      mgc_hdrc_disable(pThis);
++              }
++
++              RETURN_IRQ_HANDLED;
++    }
++
++      /* handle tx/rx on endpoints; each bit of wIntrTxValue is an endpoint,
++       * endpoint 0 first (p35 of the manual) bc is "SPECIAL" treatment;
++       * WARNING: when operating as device you might start receving traffic
++       * to ep0 before anything else happens so be ready for it */
++      do {
++              uint8_t bShift=0;
++              uint32_t reg=wIntrTxValue;
++
++              if(reg & 1 ) {  /* EP0 */
++                      if (devctl & MGC_M_DEVCTL_HM) {
 +#ifdef MUSB_CONFIG_PROC_FS
-+                      pEnd->dwErrorRxPackets++;
++                              if(pThis->pfDefaultEndHandler) {
++                                      pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam);
++                              } else
 +#endif
-+              }
-+              
-+              /* an error won't process the data */
-+              if ( status ) {
-+                      pUrb->status=status;            
-+      
-+                      /* data errors are signaled */
-+                      if ( USB_ST_STALL!=status ) {
-+                              DBG(3, "end %d Rx error, status=%d\n", bEnd, status); 
-+                              DEBUG_CODE(3, MGC_HDRC_DUMPREGS(pThis, bEnd); );
++                              MGC_HdrcServiceDefaultEnd(pThis);
 +                      } else {
-+                              mgc_hdrc_flush_fifo(pThis, bEnd, 1);                            
-+                      }
-+                      
-+                      DBG(3, "clearing all error bits, right away\n"); 
-+                      wVal &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_DATAERROR | 
-+                              MGC_M_RXCSR_H_RXSTALL );
-+                      wVal &= ~MGC_M_RXCSR_RXPKTRDY;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);            
-+              } 
-+              
-+    } while (0);
-+      
-+      /* no errors, unload... */
-+      if ( pUrb->status==-EINPROGRESS ) {
-+              
-+              /* be sure a packet is ready for unloading */
-+              if( !wRxCsrVal & MGC_M_RXCSR_RXPKTRDY ) {
-+                      pUrb->status = USB_ST_INTERNALERROR;
-+                      /* do the proper sequence to abort the transfer */
-+                      wVal &= ~MGC_M_RXCSR_H_REQPKT;
-+                      MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
-+                      DBG(3, "Rx interrupt with no errors or packet!\n");     
-+              } else {
-+                      /* we are expecting traffic */
-+#ifdef MUSB_DMA
-+                      if(pEnd->pDmaChannel) {
-+                              if(MGC_DMA_STATUS_FREE==
-+                                      pThis->pDmaController->pfDmaGetChannelStatus(pEnd->pDmaChannel))
-+                              {
-+                                      pEnd->dwOffset += pEnd->pDmaChannel->dwActualLength;
-+                              }
++                              udc_ep0_irq();
 +                      }
-+#endif
-+                      mgc_linux_packet_rx(pThis, bEnd, wRxCount, bIsochError);                        
 +              }
-+    }
-+      
-+      /* complete the current request or start next one clearing RxPktRdy 
-+       * and setting ReqPkt */
-+    if ( pUrb->status!=-EINPROGRESS ) {
-+              int toggle=(pUrb->status==USB_ST_STALL) 
-+                      ? 0
-+                      : ((wVal & MGC_M_RXCSR_H_DATATOGGLE) ? 1 : 0);
-+              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+              complete_ep_urb(pThis, pEnd, pUrb, toggle);
-+              DBG(2, "==>\n"); 
-+    } else {
-+              spin_unlock(&pEnd->Lock);
-+              wVal |= MGC_M_RXCSR_H_REQPKT;
-+              wVal &= ~MGC_M_RXCSR_RXPKTRDY;
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);    
-+              DBG(2, "==>\n"); 
-+              SPIN_UNLOCK_IRQRESTORE(&pThis->Lock, flags);
-+    } 
-+}
 +
-+/* *************************************************************************
-+ *  
-+ **************************************************************************/
++#ifdef MUSB_PARANOID
++              if( MGC_ISCORRUPT(pThis) ) {
++                      INFO("after servicing Ep0 interrupt\n");
++                      break;
++              }
++#endif
 +
-+/**
-+ * Find a local endpoint suitable for transmitting the given urb minimizing 
-+ * the reconfigurations. The best localendpoint is selceted using the following 
-+ * criterion:
-+ * - ep0 is used for control Urbs
-+ * - for bulk Urbs only (when available) choose the Tx or Rx reserved end
-+ * - determine direction, size and traffic type 
-+ *
-+ * @param pThis instance pointer
-+ * @param pURB URB pointer
-+ * @return suitable local endpoint
-+ * @return -1 if nothing appropriate
-+ */
-+int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb)
-+{
-+    MGC_LinuxLocalEnd* pEnd;
-+    int32_t dwDiff;
-+    uint16_t wBestDiff = 0xffff;
-+    uint16_t wBestExactDiff = 0xffff;
-+    uint8_t bDirOk, bTrafficOk, bSizeOk, bExact;
-+    int nEnd=-1, nBestEnd = -1, nBestExactEnd = -1;
-+    unsigned int nOut = usb_pipeout( pUrb->pipe );
-+    uint16_t wPacketSize = usb_maxpacket(pUrb->dev, pUrb->pipe, nOut);
-+    uint8_t bRemoteEnd = usb_pipeendpoint(pUrb->pipe);
-+    uint8_t bIsBulk = usb_pipebulk(pUrb->pipe);
-+    uint8_t bRemoteAddress = (uint8_t)usb_pipedevice(pUrb->pipe);
-+    
-+    DBG(2, "<== pUrb=%p\n", pUrb);
++              /* TX on endpoints 1-15 */
++              bShift = 1;
++              reg >>= 1;
++              while(reg) {
++                      if(reg & 1) {
++                              if(devctl & MGC_M_DEVCTL_HM) {
++                                      MGC_HdrcServiceTxAvail(pThis, bShift);
++                              } else {
++                                      udc_ep_tx_irq(bShift) ;
++                              }
++                      }
++                      reg >>= 1;
++                      bShift++;
++              }
 +
-+    /* control is always EP0, and can always be queued */
-+    if ( usb_pipecontrol(pUrb->pipe) ) {
-+      DBG(2, "==> is a control pipe use ep0\n");
-+        return 0;
-+    }
++              DEBUG_CODE(10, wIntrTxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRTX); \
++                      if(wIntrTxCheck && (wIntrTxCheck == wIntrTxValue)) { \
++                              ERR("Unhandled TX interrupt, wIntrTx=%04x wIntrTxCheck=%04x; DRC stopped\n",\
++                                      wIntrTxValue, wIntrTxCheck); \
++                                      for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \
++                                              MGC_HdrcDumpRegs(pThis->pRegs, \
++                                              MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \
++                                      } \
++                                      MGC_HdrcStop(pThis); \
++                                      MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \
++                                      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \
++                                      pThis->pRootDevice = NULL; \
++                      } );
 +
-+    /* use a reserved one for bulk if any */
-+    if (bIsBulk) {    
-+              if (nOut && pThis->bBulkTxEnd) {                        
-+                      DBG(3, "==> use the bulk tx end (%d)\n",  pThis->bBulkTxEnd);
-+                      return pThis->bBulkTxEnd;
-+              } else if(!nOut && pThis->bBulkRxEnd) {
-+                      DBG(3, "==> use the bulk rx end (%d)\n", pThis->bBulkRxEnd);
-+                      return pThis->bBulkRxEnd;
-+              }               
-+    }
++#ifdef MUSB_PARANOID
++              if( MGC_ISCORRUPT(pThis) ) {
++                      INFO("after servicing Tx interrupt\n");
++                      break;
++              }
++#endif
 +
-+    /* scan, remembering exact match and best match */
-+    for(nEnd = 1; nEnd < pThis->bEndCount; nEnd++) {
-+        pEnd = &(pThis->aLocalEnd[nEnd]);
-+              
-+              /* consider only if direction is possible  */
-+              bDirOk = (nOut && pEnd->wMaxPacketSizeTx) || 
-+                (!nOut && pEnd->wMaxPacketSizeRx);
-+              /* consider only if size is possible (in the given direction) */
-+              bSizeOk = (nOut && (pEnd->wMaxPacketSizeTx >= wPacketSize)) ||
-+                (!nOut && (pEnd->wMaxPacketSizeRx >= wPacketSize));
-+              /* consider only traffic type */
-+              bTrafficOk = (usb_pipetype(pUrb->pipe) == pEnd->bTrafficType);
-+              
-+              if (bDirOk && bSizeOk) {
-+                      /* convenient computations */
-+                      dwDiff = nOut ? (pEnd->wMaxPacketSizeTx - wPacketSize) : 
-+                        (pEnd->wMaxPacketSizeRx - wPacketSize);
-+                      bExact = bTrafficOk && (pEnd->bRemoteEnd == bRemoteEnd) &&
-+                      (pEnd->bRemoteAddress == bRemoteAddress);
-+      
-+                      /* bulk: best size match not claimed (we only claim periodic) */
-+                      if(bIsBulk && !pEnd->bIsClaimed && (wBestDiff > dwDiff)) {
-+                              wBestDiff = (uint16_t)dwDiff;
-+                              nBestEnd = nEnd;
-+                              
-+                              /* prefer end already in right direction (to avoid flush) */
-+                              if((wBestExactDiff > dwDiff) && (nOut == (int)pEnd->bIsTx)) {
-+                                      wBestExactDiff = (uint16_t)dwDiff;
-+                                      nBestExactEnd = nEnd;
-+                              }
-+                              
-+                      } else if(!bIsBulk && (nEnd != pThis->bBulkTxEnd) &&
-+                              (nEnd != pThis->bBulkRxEnd))
-+                      {
-+                              /* periodic: exact match if present; otherwise best unclaimed */
-+                              if (bExact) {
-+                                      nBestExactEnd = nEnd;
-+                                      break;
-+                              } else if(!pEnd->bIsClaimed && (wBestDiff > dwDiff)) {
-+                                      wBestDiff = (uint16_t)dwDiff;
-+                                      nBestEnd = nEnd;
++              /* RX on endpoints 1-15 */
++              reg = wIntrRxValue;
++              bShift = 1;
++              reg >>= 1;
++              while(reg) {
++                      if(reg & 1) {
++                              if(devctl & MGC_M_DEVCTL_HM) {
++                                      MGC_HdrcServiceRxReady(pThis, bShift);
++                              } else {
++                                      udc_ep_rx_irq(bShift) ;
 +                              }
 +                      }
++
++                      reg >>= 1;
++                      bShift++;
 +              }
-+      
-+    }
 +
-+    return (nBestExactEnd >= 0) ? nBestExactEnd : nBestEnd;
-+}
++              DEBUG_CODE(10,  wIntrRxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRRX); \
++              if(wIntrRxCheck && (wIntrRxCheck == wIntrRxValue)) { \
++                      DBG(1, "Unhandled RX interrupt, IntrRx=%04x; IntrRxCheck=%04x DRC stopped\n", \
++                                 wIntrRxValue, wIntrRxCheck); \
++                      for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \
++                              MGC_HdrcDumpRegs(pThis->pRegs, \
++                              MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \
++                      } \
++                      MGC_HdrcStop(pThis); \
++                              MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \
++                      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \
++                      pThis->pRootDevice = NULL; \
++                      });
++
++              /* Global interrups are used to signal connect/disconnect/vbuserr
++              * etc. processed in two phase */
++              if (bIntrUsbValue) {
++                      mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
++              }
 +
-+static int mgc_check_bandwidth(struct urb* pUrb) {
-+    unsigned int pipe = pUrb ? pUrb->pipe : 0;
-+#ifdef MUSB_V24
-+    struct urb* pNextUrb;
++#ifdef MUSB_PARANOID
++              if( MGC_ISCORRUPT(pThis) ) {
++                      INFO("stopping after servicing Rx interrupt\n");
++              }
 +#endif
++      } while (0);
 +
-+          /* some drivers try to confuse us by linking periodic URBs BOTH ways */
-+    if(!pUrb->bandwidth && (usb_pipeisoc(pipe) || usb_pipeint(pipe))) {
-+              int bustime = usb_check_bandwidth(pUrb->dev, pUrb);
-+              if(bustime < 0) {
-+                      return bustime;
-+              }
-+              
-+              usb_claim_bandwidth(pUrb->dev, pUrb, bustime, 
-+                      usb_pipeisoc(pipe) ? 1 : 0);
-+      
-+#ifdef MUSB_V24
-+              /* propagate through linked URBs */
-+              pNextUrb = pUrb->next;
-+              while(pNextUrb && (0 == pNextUrb->bandwidth)) {
-+                      pNextUrb->bandwidth = bustime;
-+                      pNextUrb = pNextUrb->next;
++#ifdef MUSB_PARANOID
++              if( MGC_ISCORRUPT(pThis) ) {
++                      MGC_HdrcStop(pThis);
++                      MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
 +              }
-+#endif        
-+    }
-+      
-+      return 0;
++#endif
++
++    DBG(2, "==> IRQ HANDLED [devmode=%s]\n", MUSB_MODE(pThis));
++    RETURN_IRQ_HANDLED;
 +}
 +
++
 +/**
-+ * Schedule an urb on an endpoint. Assumes the ep locked.
-+ * @param pThis the conotroller
-+ * @param pEnd the endpoint the urb shoudl be queued to
-+ * @param pUrb the urb to queue
++ * Interrupt service routine.
++ * @param irq interrupt line associated with the controller
++ * @param hci data structure for the host controller
++ * @param r holds the snapshot of the processor's context before
++ *             the processor entered interrupt code. (not used here)
 + */
-+int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd, 
-+      struct urb* pUrb)
++#ifndef MUSB_USE_HCD_DRIVER
++irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r)
 +{
-+    DBG(2, "<== pUrb=%p ep=%d\n", pUrb, pEnd->bEnd);
-+
-+      /* increment urb's reference count, we now control it. */       
-+      pUrb = usb_get_urb(pUrb);       
-+      pUrb->hcpriv = NULL; /* paranoid */
-+      
-+      /* async unlink?? */
-+      if( pUrb->status!=-EINPROGRESS ) {
 +
-+              mgc_linux_complete_urb(pThis, pEnd, pUrb);              
-+              return 0;               
-+    } 
-+
-+      DEBUG_CODE(3, if(pEnd->bEnd==0) { \
-+              MUSB_DeviceRequest* pRequest = (MUSB_DeviceRequest*)pUrb->setup_packet;\
-+              INFO("ctl-request: bmRequestType=%02x, bRequest=%02x, wLength=%04x\n",\
-+            pRequest->bmRequestType, pRequest->bRequest,\
-+            le16_to_cpu(pRequest->wLength));\
-+    } );
++    MGC_LinuxCd* pThis = (MGC_LinuxCd*)__hci;
++      return mgc_linux_isr(pThis);
++}
++#endif
 +
-+      {       
-+              const int bustime=mgc_check_bandwidth(pUrb);
-+              if ( bustime<0 ) {
-+                      ERR("==> not enough bustime for it\n"); 
-+                      return bustime;
-+              }
-+      }               
-+      
-+      /* claim the urb for periodic transfers */      
-+      pEnd->bIsClaimed=mgc_urb_is_periodic(pUrb);
-+      if ( pEnd->bIsClaimed ) {
-+              DBG(3, "end %d claimed for proto %s\n", pEnd->bEnd, 
-+                      decode_urb_protocol(pUrb) );
-+      }
++/*****************************************************/
 +
-+      { /* queue the urb and start it */
-+              int idle=mgc_ep_is_idle(pEnd);
-+              
-+              if ( mgc_ep_enqueue_urb(pEnd, pUrb)!=0 ) {
-+                      ERR("**>cannot queue pUrb=%p to pEnd=%p! this is bad (TM)\n", pUrb, pEnd); 
-+                      return -EBUSY;
-+              }
++void goto_host_mode(MGC_LinuxCd* pThis) {
++      /* TODO: graceful Gadget shutdown */
++      MUSB_HST_MODE(pThis);
++#ifdef MUSB_USE_HCD_DRIVER
 +
-+              DBG(3, "queued URB %p (current %p) to end %d (bRemoteAddress=%d, bRemoteEnd=%d proto=%d) (idle=%d) pEnd->bBusyCompleting=%d\n", 
-+                      pUrb, MGC_GetCurrentUrb(pEnd), pEnd->bEnd, (uint8_t)usb_pipedevice(pUrb->pipe), 
-+                      (uint8_t)usb_pipeendpoint(pUrb->pipe), usb_pipetype(pUrb->pipe), idle, pEnd->bBusyCompleting);             
++#else
 +
-+              /* when using the HCD driver, idle BETTER be 1 :)) */
-+              if ( idle ) {                   
-+                      mgc_linux_kickstart_urb(pThis, pEnd->bEnd);
-+              }
-+      }
-+      
-+#ifdef MUSB_PARANOID
-+      DEBUG_CODE(5, dump_urb(pUrb); );
-+      if ( MGC_ISCORRUPT(pThis) ) { 
-+              ERR("stopping after submit\n");
-+              MGC_HdrcStop(pThis); 
-+              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
-+              DBG(2, "==> -ENOENT\n");
-+              return -ENODEV; /* like a disconect */ 
-+      }                       
 +#endif
++}
 +
-+    DBG(2, "==>\n");
-+      return 0;
++void goto_device_mode(MGC_LinuxCd* pThis) {
++      /* TODO: graceful host shutdown */
++      MUSB_DEV_MODE(pThis);
 +}
 +
-+/**
-+ * Submit an URB, either to the virtual root hut or to a real device;
-+ * it also checks the URB to make sure it's valid.
-+ * This is called by the Linux USB core. TSubmit Urb lock pThis
-+ * and the End to use, so make sure the caller releases its locks.
-+ *
-+ * @param pThis the controller
-+ * @param pUrb URB pointer (urb = USB request block data structure)
-+ * @param iMemFlags memeory flags (see kernel docs)
-+ * @return status code (0 succes)
-+ */ 
-+int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb, 
-+      MUSB_MEMFLAG_TYPE iMemFlags)
-+{
-+      int nEnd=0, rc;
-+    
-+    DBG(2, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s\n", 
-+              pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb));
 +
-+#ifdef MUSB_PARANOID
-+      if( MGC_ISCORRUPT(pThis) ) { 
-+              ERR("==> pThis corrupted: stopping before submit\n"); 
-+              MGC_HdrcStop(pThis); 
-+              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); 
-+              return -ENOENT; 
-+      }
-+#endif
++/* --------------------------------------------------------------------------
++ * Init function
++ *
++ */
 +
 +#ifndef MUSB_USE_HCD_DRIVER
-+    /* if it is a request to the virtual root hub, delegate */
-+    /* if( usb_pipedevice(pipe) == pThis->RootHub.bAddress) */
-+    
-+    /* pUrb->dev->parent==null means that the device is the root hub,
-+     this should be fine on every platform. */
-+    if( !pUrb->dev->parent ) {
-+/*
-+      if(pThis->bDelayPortPowerOff)
-+      {
-+          return -ENODEV;    
-+      }
-+*/
-+              const int rc=MGC_VirtualHubSubmitUrb(&(pThis->RootHub), pUrb);
-+              DBG(2, "==> sbmitted to vhub rc=%d\n", rc);
-+              return rc;
-+    }
-+#endif
-+
-+      /* find appropriate local endpoint to do it */
-+    nEnd=mgc_linux_find_end(pThis, pUrb);
-+    DBG(3, "pUrb=%p, end=%d, bufsize=%x\n", pUrb, \
-+      nEnd, pUrb->transfer_buffer_length);
++/** attach to the IRQ and update the controller structure.
++ * @param nIrq the Irq number
++ * @param pThis the controller
++ * @return 0 if success (pThis is also update), negative is error
++ */
++static int mgc_request_irq(int nIrq, MGC_LinuxCd* pThis) {
++      int rc=-ENODEV;
 +
-+#ifdef MUSB_PARANOID
-+    if (nEnd < 0) {
-+              unsigned int pipe = pUrb ? pUrb->pipe : 0;
-+              pUrb->status = USB_ST_URB_REQUEST_ERROR;
-+              ERR("==> no resource for proto=%d, addr=%d, end=%d\n", \
-+             usb_pipetype(pipe), usb_pipedevice(pipe), \
-+             usb_pipeendpoint(pipe)); 
-+               return USB_ST_URB_REQUEST_ERROR;
-+    }
-+#endif
-+      
-+    /* if no root device, assume this must be it */
-+    if ( !pThis->pRootDevice ) {
-+              pThis->pRootDevice = pUrb->dev;
-+    }
++      pThis->nIrq = nIrq;
++      /* the hcd driver will take care of that */
++      do {
 +
-+      { /* queue */           
-+              unsigned long flags=0;
-+              MGC_LinuxLocalEnd *pEnd=&pThis->aLocalEnd[nEnd];
-+              
-+              if ( !pEnd->bBusyCompleting ) {
-+                      SPIN_LOCK_IRQSAVE(&pEnd->Lock, flags);
++#ifdef MUSB_HARD_IRQ
++              if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_INTERRUPT,
++                      pThis->aName, pThis))
++              {
++                      rc=0;
++                      pThis->nIrqType=SA_INTERRUPT;
++                      break;
 +              }
-+      
-+              pUrb->status=-EINPROGRESS;
-+              rc=mgc_schedule_urb(pThis, pEnd, pUrb);
-+              
-+              if ( ! pEnd->bBusyCompleting ) {
-+                      SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags);
++#endif
++              if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_SHIRQ,
++                      pThis->aName, pThis))
++              {
++                      rc=0;
++                      pThis->nIrqType=SA_SHIRQ;
++                      break;
 +              }
-+      }
-+      
++      } while (0);
++
 +      return rc;
 +}
 +
 +/**
-+ * Generic v26 version (pre10).
++ * release in irq previously allocated with mgc_request_irq().
++* @param pTHis the controller the IRQ was allocated for
 + */
-+static inline int 
-+      mgc_linux_submit_urb_common(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags)
++static void mgc_free_irq(MGC_LinuxCd* pThis) {
++      free_irq(pThis->nIrq, pThis);
++}
++#endif
++
++#ifdef MUSB_VIRTHUB
++#ifndef MUSB_USE_HCD_DRIVER
++static int mgc_init_bus(MGC_LinuxCd *pThis, void* pDevice)
 +{
-+    MGC_LinuxCd* pThis;
-+    
-+    DBG(2, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s\n", 
-+              pUrb, pUrb->hcpriv, decode_urb_protocol(pUrb));
++      int rc=0;
 +
-+#ifdef MUSB_PARANOID
-+    if (!pUrb || !pUrb->dev || !pUrb->dev->bus ) {
-+              DBG(2, "==> invalid URB"); 
-+              return -EINVAL;
++    /* allocate and register bus */
++    pThis->pBus=usb_alloc_bus(  &MGC_LinuxOperations );
++    if (!pThis->pBus ) {
++              return -ENODEV;
 +    }
++
++#ifdef MUSB_V26
++    pThis->pBus->controller =(struct device*)pDevice;
 +#endif
 +
-+    pThis = (MGC_LinuxCd*)pUrb->hcpriv;               
-+    if ( !pThis ) {
-+              DBG(2, "==> invalid URB: pThis is null"); 
-+              return -EINVAL;
++#ifdef MUSB_HAS_BUSNAME
++    pThis->pBus->bus_name = pThis->aName;
++#endif
++
++      /* when using the HCD driver (USE_HCD_DRIVER)
++         pThis->pBus->hcpriv points to the hcd driver
++      */
++    pThis->pBus->hcpriv = (void *)pThis;
++
++      usb_register_bus(pThis->pBus);
++      INFO("Registered new bus @%p\n", pThis->pBus);
++
++      rc=mgc_init_root_hub(pThis);
++      if ( rc!=0 ) {
++              usb_deregister_bus(pThis->pBus);
++      } else {
++              pThis->pBus->root_hub = pThis->RootHub.pDevice;
 +      }
 +
-+      return mgc_submit_urb(pThis, pUrb, iMemFlags);
++      return rc;
++}
++
++static void mgc_free_bus(struct usb_bus *bus) {
++#ifdef MUSB_V26
++    usb_deregister_bus(bus);
++#endif
 +}
 +
++#endif
++#endif
 +
++/* disable an endpoint */
 +#ifdef MUSB_V26
-+int MGC_LinuxSubmitUrb26(struct urb *pUrb, MUSB_MEMFLAG_TYPE iMemFlags) 
++void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress)
 +{
-+      return mgc_linux_submit_urb_common(pUrb, iMemFlags);
++    /* to do */
 +}
 +#endif
 +
-+#ifdef MUSB_V24
-+int MGC_LinuxSubmitUrb24(struct urb* pUrb)
++
++/* --------------------------------------------------------------------------
++ * HOST DMA related code
++ *
++ */
++
++#ifdef MUSB_DMA
++/**
++ * used ONLY in host mode, I'll be moved to musb_host
++ * @param pPrivateData
++ * @param bLocalEnd
++ * @param bTransmit
++ */
++STATIC uint8_t MGC_LinuxDmaChannelStatusChanged(
++    void* pPrivateData, uint8_t bLocalEnd, uint8_t bTransmit)
 +{
-+      return mgc_linux_submit_urb_common(pUrb, GFP_ATOMIC);
++    MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
++    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bLocalEnd]);
++    struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
++    const void* pBase = pThis->pRegs;
++    uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++
++    if(!bLocalEnd) {
++              /* endpoint 0 */
++              if(devctl & MGC_M_DEVCTL_HM) {
++#ifdef MUSB_CONFIG_PROC_FS
++                      if(pThis->pfDefaultEndHandler) {
++                              pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam);
++                      } else
++#endif
++                      MGC_HdrcServiceDefaultEnd(pThis);
++              } else {
++                      MGC_HdrcServiceDeviceDefaultEnd(pThis);
++              }
++    } else {
++              /* endpoints 1..15 */
++              if(bTransmit) {
++                      if(devctl & MGC_M_DEVCTL_HM) {
++                              MGC_HdrcServiceTxAvail(pThis, bLocalEnd);
++                      } else {
++                              MGC_HdrcServiceDeviceTxAvail(pThis, bLocalEnd);
++                      }
++              } else {
++              /* receive */
++              if(devctl & MGC_M_DEVCTL_HM) {
++                      MGC_HdrcServiceRxReady(pThis, bLocalEnd);
++                  } else {
++                              MGC_HdrcServiceDeviceRxReady(pThis, bLocalEnd);
++                  }
++              }
++    }
++
++    /* trick: if end's URB changed; previous one completed;
++       * probably not needed now... */
++    return (pUrb == MGC_GetCurrentUrb(pEnd)) ? FALSE : TRUE;
 +}
 +#endif
 +
-+/* --------------------------------------------------------------------- */
++/*-------------------------------------------------------------------------*/
++
++#ifdef MUSB_USE_HCD_DRIVER
++#include "musb_hcd.c"
++#endif
 +
 +/**
-+ * Cross version unlink
++ * Perform generic per-controller initialization.
 + *
-+ * @param pThis the controller
-+ * @param pUrb the Urb to  unlink
-+ * @return 
++ * @param pDevice
++ * @param nIrq IRQ (interpretation is system-dependent)
++ * @param pRegs pointer to controller registers,
++ *  assumed already mapped into kernel space
++ * @param pName name for bus
 + */
-+int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb) 
++
++MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType,
++      int nIrq, void* pRegs, u64 len, const char* pName)
 +{
-+      unsigned long flags;
++    uint8_t bEnd;
++    MGC_LinuxCd* pThis;
++#ifdef MUSB_USE_HCD_DRIVER
++      struct usb_hcd *hcd = NULL;
++#endif
 +    MGC_LinuxLocalEnd* pEnd;
++    uint16_t temp;
++      DBG(2, "<==\n");
 +
-+      DBG(-1, "<== pUrb=%p, pUrb->hcpriv=%p proto=%s \n", pUrb, pUrb->hcpriv,
-+              decode_urb_protocol(pUrb));
-+      
-+#ifdef MUSB_PARANOID
-+    if(MGC_ISCORRUPT(pThis)) {
-+              ERR("pThis corrupted: stopping before unlink\n");
-+              MGC_HdrcStop(pThis);
-+              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); 
-+              DBG(2, "==>\n");
-+              return -EINVAL;
++    /* allocate */
++      INFO("MUSB Driver [Base Address(PA)=0x%p] [IRQ = %d] [pDevice=%p]\n",
++              pRegs , nIrq, pDevice);
++
++#ifdef MUSB_USE_HCD_DRIVER
++      ///////////////////////////////////////////////////////////////////////////////
++    /* allocate */
++
++
++      hcd = usb_create_hcd(&musb_ahb_hc_driver, (struct device*)pDevice,
++              ((struct device*)pDevice)->bus_id);
++      hcd1=hcd;
++      if ( !hcd ) {
++              return NULL;
++      }
++
++      hcd->rsrc_len = len;
++      /* register Base address (VA)*/
++      hcd->regs = pRegs;
++      ///////////////////////////////////////////////////////////////////////////////
++
++      pThis=hcd_to_musbstruct(hcd);
++      udc_address=pThis;
++      spin_lock_init(&pThis->LocalQueue.urb_queue_lock);
++      init_waitqueue_head(&pThis->waitqh);
++#else
++      KMALLOC(pThis, sizeof(MGC_LinuxCd), GFP_ATOMIC);
++    if(!pThis) {
++        ERR("kmalloc driver instance data failed\n");
++              return NULL;
 +    }
++      memset (pThis, 0, sizeof(MGC_LinuxCd));
 +#endif
-+      
-+#ifndef MUSB_USE_HCD_DRIVER
-+    /* if it is a request to the virtual root hub, delegate */
-+    /* if (usb_pipedevice (pUrb->pipe) == pThis->RootHub.bAddress) */
-+    if( !pUrb->dev->parent ) {
-+              int rc=MGC_VirtualHubUnlinkUrb(&(pThis->RootHub), pUrb);
-+              DBG(2, "==> VirtualHub rc=%d\n", rc);
-+              return rc;
++
++
++
++      pThis->pRegs = pRegs;
++
++    strcpy(pThis->aName, pName);
++      spin_lock_init(&pThis->Lock);
++
++#if MUSB_DEBUG > 0
++    pThis->dwPadFront = MGC_PAD_FRONT;
++    pThis->dwPadBack = MGC_PAD_BACK;
++#endif
++
++#ifdef MUSB_DMA
++    pThis->pDmaController = MGC_HdrcDmaControllerFactory
++              .pfNewDmaController(MGC_LinuxDmaChannelStatusChanged, pThis, (uint8_t*)pRegs);
++    if(pThis->pDmaController) {
++              DBG(2, "DMA initialized&enabled Address: 0x%p\n", pThis->pDmaController);
++      pThis->pDmaController->pfDmaStartController(
++              pThis->pDmaController->pPrivateData);
 +    }
 +#endif
-+      
-+      /* which end was the urb queued? */
-+    pEnd=(MGC_LinuxLocalEnd*)pUrb->hcpriv;
-+      if ( pEnd )
 +
-+      /* somehow, we got passed a dangling URB pointer */
-+    if((pEnd < &(pThis->aLocalEnd[0])) ||
-+              (pEnd > &(pThis->aLocalEnd[MUSB_C_NUM_EPS-1])))
-+    {
++
++    mgc_reset(pThis);
++
++    /* be sure interrupts are disabled before connecting ISR */
++    mgc_hdrc_disable(pThis);
++
++      // Reset the device, otherwise the controller
++      // can be in unknown state.
++      temp = MGC_Read16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL);
++
++      MGC_Write16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL, (temp |MGC_M_TOPCTRL_MODE_SRST));
++
++    /* discover configuration */
++    if ( !MGC_HdrcInit(wType, pThis) ) {
 +#ifdef MUSB_USE_HCD_DRIVER
-+              DBG(-1, "==> cannot unlink pUrb=%p, pEnd=%p is invalid\n", pUrb, 
-+                      pEnd);
-+        return -EINVAL;
++              /* free memory ? */
++#else
++              /* free memory ? */
 +#endif
++              return NULL;
 +    }
-+      
-+      if (  MUSB_IS_HST(pThis) && pUrb->transfer_flags & USB_ASYNC_UNLINK ) {
-+              DBG(-1, "Asyncronous unlink of pUrb=%p (pUrb->status=%d)\n", 
-+                      pUrb, pUrb->status);
-+      } else {                
-+              DBG(-1, "Syncronous unlink of pUrb=%p (pUrb->status=%d)\n", pUrb, 
-+                      pUrb->status);
-+                      
-+              SPIN_LOCK_IRQSAVE(&pEnd->Lock, flags);                  
-+              if ( mgc_ep_dequeue_urb(pEnd, pUrb,pThis)==0 ) {
-+                      int status;             
++      /*for nhk15 this a must for powering up the STULPI
++       */
++      /*power up the STULPI tranceiver*/
++      MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);
 +
-+                      SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags);     
-+                      status=mgc_linux_complete_urb(pThis, pEnd, pUrb);
-+                      if ( status==-EINVAL ) {
-+                              ERR("*** cannot unlink pUrb=%p from bEnd=%d (current=%p)\n", pUrb, 
-+                                      pEnd->bEnd, MGC_GetCurrentUrb(pEnd));
-+                      }                       
++    /* print config */
++    for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++        pEnd = &(pThis->aLocalEnd[bEnd]);
++              if(pEnd->wMaxPacketSizeTx || pEnd->wMaxPacketSizeRx) {
++                      INFO("End %02d: %sFIFO TxSize=%04x/RxSize=%04x\n",
++                              bEnd, pEnd->bIsSharedFifo ? "Shared " : "",
++                              pEnd->wMaxPacketSizeTx, pEnd->wMaxPacketSizeRx);
 +              } else {
-+                      SPIN_UNLOCK_IRQRESTORE(&pEnd->Lock, flags);                     
-+                      ERR("*** pUrb=%p is not queued to bEnd=%d, this is BAD!\n", pUrb,
-+                              pEnd->bEnd);
++                      INFO("End %02d: not configured\n", bEnd);
 +              }
-+      }
-+
-+#ifdef MUSB_PARANOID
-+    if(MGC_ISCORRUPT(pThis)) {
-+              ERR("stopping after unlink\n");
-+              MGC_HdrcStop(pThis);
-+              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); 
-+              return -EINVAL;
 +    }
++
++      /* procfs and testing interface */
++    MGC_LinuxCreateProcFs(pThis->aName, pThis);
++
++#ifdef MUSB_PROC_TESTMUSB
++    MGC_LinuxCreateTestProcFs(pThis->aName, pThis);
 +#endif
 +
-+    DBG(-1, "==> rc=0\n");
-+    return 0;
-+}
++    MUSB_B_IDLE_MODE(pThis);
++    DBG(1, "MUSB_B_IDLE mode \n");
++    temp = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL  );
 +
-+/**
-+ * unlink an urb, common code.
-+ * @param pUrb the urb to unlink
-+ */
-+static int mgc_linux_unlink_urb(struct urb* pUrb, int status)
-+{
-+    MGC_LinuxCd* pThis;
-+      
-+    DBG(2, "<== pUrb=%p\n", pUrb);
-+      
-+    /* sanity */
-+    if (!pUrb || !pUrb->hcpriv) {
-+              DBG(2, "==> invalid urb%p, pUrb->hcpriv=%p\n", pUrb, 
-+                      (pUrb)?pUrb->hcpriv:NULL);
-+              return -EINVAL;
-+    }
++    /* connect ISR */
 +
-+    if (!pUrb->dev || !pUrb->dev->bus) {
-+              DBG(2, "==>\n");
-+              return -ENODEV;
-+    }
 +
-+    pThis = (MGC_LinuxCd*)pUrb->hcpriv; 
-+    if(!pThis) {
-+              ERR("==> pThis is null: stopping before unlink\n");
-+              return -ENODEV;
-+    }
++#ifdef MUSB_USE_HCD_DRIVER
++      /* by default allocate shared IRQ */
++      pThis->nIrq=nIrq;
++      pThis->nIrqType=MUSB_DEFAULT_IRQTYPE;
++#else
 +
-+      pUrb->status =status;
-+      return mgc_unlink_urb(pThis, pUrb);
-+}
 +
-+/**
-+ * Cancel URB.
-+ * @param pUrb URB pointer
-+ */
-+#ifdef MUSB_V26
-+int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status) {
-+      return mgc_linux_unlink_urb(pUrb, status);
-+}
++      if ( mgc_request_irq(nIrq, pThis)!=0 ) {
++        err("request_irq %d failed!", nIrq);
++        return NULL;
++      }
 +#endif
 +
-+#ifdef MUSB_V24
-+ /* ENOENT=kill ECONNRESET=unlink */
-+int MGC_LinuxUnlinkUrb24(struct urb* pUrb) {
-+      return mgc_linux_unlink_urb(pUrb, -ENOENT);
++
++
++if(udcinitmonitorflag_init==0){
++nomadik_udc_init(udc_address);
 +}
-+#endif
 +
++#ifdef MUSB_VIRTHUB
++#ifdef MUSB_USE_HCD_DRIVER
++      if ( usb_add_hcd(hcd, pThis->nIrq, pThis->nIrqType)!=0 ) {
++              DBG(2, "==> Usb_add_hcd failed \n");
++              return NULL;
++      }
++#else
++    if( 0!=mgc_init_bus(pThis, pDevice) ) {
++        dbg("usb_alloc_bus fail");
++              mgc_free_irq(pThis);
++              return NULL;
++    }
 +
-+/* --------------------------------------------------------------------- */
++#endif
++#endif
++udcinitmonitorflag_isr=1;
++init_timer(&notify_timer);
++notify_timer.expires = jiffies + msecs_to_jiffies(1000);
++notify_timer.function = funct_host_notify_timer;
++notify_timer.data = (unsigned long)pThis;
++add_timer(&notify_timer);
 +
-+/**
-+ * Initialize the local end points; pThis->bEndCount must be initialized.
-+ * @param pThis the controller
-+ */
-+void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis) {
-+    uint8_t bEnd;
-+    MGC_LinuxLocalEnd* pEnd;
++      return pThis;
++}
 +
-+#ifdef MUSB_PARANOID
-+      if ( !pThis ) {
-+              ERR("Controller not initialized\n");
-+              return;
-+      }       
++static void funct_host_notify_timer(unsigned long uContext)
++{
++      MGC_LinuxCd *pThis = (MGC_LinuxCd*) uContext;
++      uint8_t* pBase = (uint8_t*)pThis->pRegs;
++      uint8_t devctl = 0;
++      uint8_t power = 0;
 +
-+      if ( !pThis->bEndCount ) {
-+              WARN("pThis->bEndCount=%d might be wrong\n", pThis->bEndCount);
-+      }       
-+#endif
-+      
-+    for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+              pEnd = &(pThis->aLocalEnd[bEnd]);       
-+              pEnd->bEnd=bEnd;
-+              
-+#ifdef MUSB_PARANOID
-+              if ( bEnd ) {
-+                      if ( spin_is_locked(&pEnd->Lock) ) {
-+                              WARN("End=%d is locked\n", bEnd);
++      if(MUSB_IS_B_IDLE(pThis)) {
++              MGC_HdrcReadUlpiReg(pThis, 0x13, &temp);
++              if (!(temp & 0x10))
++              {
++                      MUSB_A_IDLE_MODE(pThis);
++                      if(host_a_idle==0)
++                      {
++                              devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1);
++                              power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF );
 +                      }
-+                      
-+                      if ( !mgc_ep_is_idle( pEnd ) ){
-+                              WARN("pEnd=%d pEnd->urb_list=%p: not idle\n", pEnd->bEnd,
-+                                      MGC_GetCurrentUrb(pEnd));
++                      else{
++                              power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF );
 +                      }
 +              }
-+#endif                
++              mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
++      }
++      else if (MUSB_IS_A_IDLE(pThis)) {
++              MGC_HdrcReadUlpiReg(pThis, 0x13, &temp);
++              if(temp==0x08){
 +
-+              mgc_ep_idle( pEnd );
-+              spin_lock_init( &pEnd->Lock );                          
-+              
-+              /* restore the pads */
-+#if MUSB_DEBUG > 0
-+              pEnd->dwPadFront = MGC_PAD_FRONT;
-+              pEnd->dwPadBack = MGC_PAD_BACK;
-+#endif
++                      devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1);
++              }
++              else
++              {
++                      MUSB_B_IDLE_MODE(pThis);
++                      devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl &0xFE);
++                      power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
++                      MGC_Write8(pBase, MGC_O_HDRC_POWER,power | MGC_M_POWER_SOFTCONN );
++              }
++              mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
++      }
++      else if (MUSB_IS_DEV(pThis)) {
++              del_timer(&notify_timer);
++      }
++      else if (MUSB_IS_HST(pThis)) {
 +
-+              /* reset the counters */
-+#ifdef MUSB_CONFIG_PROC_FS
-+              pEnd->dwTotalRxBytes = 0;
-+              pEnd->dwTotalRxPackets = 0;
-+              pEnd->dwErrorRxPackets = 0;
-+              pEnd->dwTotalTxBytes = 0;
-+              pEnd->dwTotalTxPackets = 0;
-+              pEnd->dwErrorTxPackets = 0;
-+              pEnd->dwWaitFrame = 0;
-+#endif
++              del_timer(&notify_timer);
++      }
++}
 +
-+              /* reset the softstate */
-+              pThis->aLocalEnd[bEnd].bIsClaimed=FALSE;
-+              pEnd->wPacketSize = 0;
-+              pEnd->bRemoteAddress = 0;       
-+              pEnd->bRemoteEnd = 0;   
-+              pEnd->bTrafficType = 0;
-+              pEnd->bIsTx=0;
++
++void del_timer_func(void)
++{
++      del_timer(&notify_timer);
++}
++
++void otg_disconnect(MGC_LinuxCd* pThis)
++{
++      uint8_t bEnd, devctl = 0;
++
++      devctl &= ~MGC_M_DEVCTL_SESSION;
++
++      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
++
++      /* flush endpoints */
++      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++              MGC_HdrcStopEnd(pThis, bEnd);
 +      }
 +
-+      mgc_slow_device_kludge_delay=MGC_SLOW_DEVICE_KLUDGE_DELAY;
++      mgc_hcd_flush(pThis);
++
++      pThis->pRootDevice = NULL;
++
++      MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, devctl);
 +}
 +
++/* A couple of hooks to enable HSET */
++#ifdef MUSB_CONFIG_PROC_FS
 +/**
-+ * initialize the root hub.
-+ * @param pThis the controller.
-+ * @return 0 for success, <0 for error
-+ * @warning I will move this to virthub.c
++ * Set a listener for disconnect interrupts.
++ * @param pfListener listener, or NULL for none
++ * @param pParam parameter to pass listener
 + */
-+int mgc_init_root_hub(MGC_LinuxCd *pThis) {
-+      int rc=0;
-+      
-+    pThis->PortServices.pPrivateData = pThis;
-+    pThis->PortServices.pfSetPortPower = MGC_LinuxSetPortPower;
-+    pThis->PortServices.pfSetPortEnable = MGC_LinuxSetPortEnable;
-+    pThis->PortServices.pfSetPortSuspend = MGC_LinuxSetPortSuspend;
-+    pThis->PortServices.pfSetPortReset = MGC_LinuxSetPortReset;               
-+      
-+      rc=MGC_VirtualHubInit(&(pThis->RootHub), pThis->pBus, 1, 
-+              &(pThis->PortServices));
++void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
++      MGC_pfDisconnectListener pfListener, void* pParam)
++{
++    pCd->pfDisconnectListener = pfListener;
++    pCd->pDisconnectListenerParam = pParam;
++}
 +
-+      return rc;
++/**
++ * Set a new handler for the default endpoint interrupt.
++ * @param pfHandler new handler, or NULL to restore default handler
++ * @param pParam parameter to pass handler
++ */
++void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
++      MGC_pfDefaultEndHandler pfHandler, void* pParam)
++{
++    pCd->pfDefaultEndHandler = pfHandler;
++    pCd->pDefaultEndHandlerParam = pParam;
 +}
++#endif
++
 +
 +
-+#if 0
-+#if MUSB_DEBUG > 0
 +/*
-+ * Test endpoint FIFO (only endpoint 0 until the others have a way)
++ * Release resources acquired by driver
 + */
-+static uint8_t MGC_HdrcTestFifo(uint8_t* pBase, uint8_t bEnd,
-+      uint8_t bDatum, uint16_t wCount)
++void MGC_LinuxCdFree(MGC_LinuxCd* pThis)
 +{
-+    uint8_t aTest[64];
-+    uint16_t wReg, wIndex, wReadCount;
-+    uint8_t bReadVal, bReg;
-+    uint8_t bResult = TRUE;
++    DBG(2, "<==\n");
 +
-+    INFO("Testing FIFO on endpoint %d...\n", bEnd);
++    MGC_HdrcStop(pThis);
++    MUSB_ERR_MODE(pThis, MUSB_ERR_SHUTDOWN);
 +
-+    for(wIndex = 0; wIndex < min(wCount, (uint16_t)64); wIndex++) {
-+              aTest[wIndex] = bDatum;
-+    }
++#ifdef MUSB_CONFIG_PROC_FS
++    MGC_LinuxDeleteProcFs(pThis);
++#endif
 +
-+    wReg = MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRTX, wReg & ~1);
-+    MGC_SelectEnd(pBase, bEnd);
-+    if(bEnd) {
-+    } else {
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0,
-+                      MGC_M_CSR0_FLUSHFIFO);
-+    }
-+    MGC_HdrcLoadFifo(pBase, bEnd, wCount, aTest);
-+    MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, MGC_M_TEST_FIFO_ACCESS);
-+    memset(aTest, 0, 64);
-+    do {
-+              bReg = MGC_Read8(pBase, MGC_O_HDRC_TESTMODE);
-+    } while(bReg & MGC_M_TEST_FIFO_ACCESS);
++#ifdef MUSB_PROC_TESTMUSB
++    MGC_LinuxDeleteTestProcFs(pThis->aName, pThis);
++#endif
 +
-+    if(bEnd) {
-+              wReadCount = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd);
-+    } else {
-+              wReadCount = MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0);
-+    }
-+    
-+      if(wReadCount != wCount) {
-+              ERR("Error: loaded FIFO with %04x bytes, RxCount=%04x\n",
-+              wCount, wReadCount);
-+                      bResult = FALSE;
++#ifdef MUSB_DMA
++    if(pThis->pDmaController) {
++      pThis->pDmaController->pfDmaStopController(
++              pThis->pDmaController->pPrivateData);
++      MGC_HdrcDmaControllerFactory.pfDestroyDmaController(
++              pThis->pDmaController);
 +    }
-+    wReadCount = min(wReadCount, (uint16_t)64);
-+    MGC_HdrcUnloadFifo(pBase, bEnd, wReadCount, aTest);
-+    if(bEnd) {
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, 0);
-+    } else {
-+              MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_P_SVDRXPKTRDY);
++#endif
++
++    MGC_VirtualHubStop(&pThis->RootHub);
++    MGC_VirtualHubDestroy(&pThis->RootHub);
++
++#ifndef MUSB_USE_HCD_DRIVER
++    if (pThis->pBus->root_hub) {
++        usb_disconnect(&(pThis->pBus->root_hub));
 +    }
-+    
-+      MGC_Write16(pBase, MGC_O_HDRC_INTRTX, wReg);
-+    for(wIndex = 0; wIndex < wReadCount; wIndex++) {
-+              if(bDatum != aTest[wIndex]) {
-+                      ERR("Error: FIFO Tx data=%02x, Rx data=%02x\n", bDatum, 
-+                              aTest[wIndex]);
-+                      bResult = FALSE;
-+              }
++
++    WAIT_MS(1);
++
++    if(pThis->nIrq) {
++        mgc_free_irq(pThis);
 +    }
-+    return bResult;
-+}
-+#endif
++
++    mgc_free_bus(pThis->pBus);
++    KFREE(pThis);
 +#endif
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.h
---- linux-2.6.20/drivers/usb/nomadik/musb_host.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_host.h        2008-07-28 15:20:59.000000000 +0530
-@@ -0,0 +1,101 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_host.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 
++    DBG(2, "==>\n");
++}
++
++
++
++/**
++ * Initialize the driver.
 + */
++int MGC_DriverInit(void)
++{
++    int rc=-ENODEV;
++      int result;
++    DBG(2, "<==\n");
 +
-+#ifndef _MUSB_HOST_H
-+#define _MUSB_HOST_H
++    nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
 +
-+extern int mgc_slow_device_kludge_delay;
++      /* the driver  was already initialized, no need to repeat this */
++      if ( MGC_nIndex ) {
++              DBG(2, "==>\n");
++              return 0;
++      }
 +
-+#define SPIN_LOCK_IRQSAVE(l, f) do { spin_lock_irqsave(l, f); if ( mgc_slow_device_kludge_delay) { udelay(mgc_slow_device_kludge_delay*2); } DBG(3, "IRQ DISABLED\n"); } while (0)
-+#define SPIN_UNLOCK_IRQRESTORE(l,f) do { DBG(3, "IRQ ENABLED\n"); spin_unlock_irqrestore(l, f); } while (0)
++      if ( !usb_disabled() ) {
++              do {
 +
-+struct urb;
++                      int direct_bus=-ENODEV;
 +
-+int mgc_init_root_hub(MGC_LinuxCd *pThis);
-+int mgc_ep_is_idle(MGC_LinuxLocalEnd* pEnd);
-+MGC_LinuxLocalEnd* mgc_ep_find_end(MGC_LinuxCd *pThis, struct urb *pUrb);
++                      direct_bus=direct_bus_init();
 +
-+int mgc_linux_find_end(MGC_LinuxCd* pThis, struct urb* pUrb);
-+int mgc_schedule_urb(MGC_LinuxCd *pThis, MGC_LinuxLocalEnd* pEnd, 
-+      struct urb* pUrb);
++                      if ( direct_bus<0 ) {
 +
-+static inline int mgc_urb_is_periodic(struct urb *pUrb) {
-+      return (usb_pipeint(pUrb->pipe) || usb_pipeisoc(pUrb->pipe));
-+}
++                              ERR("Error initializing controller on the direct bus\n");
++                              rc=-ENODEV; break;
++                      }
 +
-+extern char* decode_urb_protocol(struct urb* pUrb);
++                      rc = 0;
++
++              } while (0);
++      } else {
++              DBG(2, "USB Disabled , exiting\n");
++      }
 +
++      result = register_chrdev (MAJOR_NUMBER_OTG, "st-otg", &otg_fops);
 +
-+#ifdef MUSB_USE_HCD_DRIVER    
-+int mgc_hcd_schedule_urb(MGC_LinuxCd* pThis);
-+#endif
++      if (result <0){
 +
-+#ifdef MUSB_HOST
-+extern int mgc_unlink_urb(MGC_LinuxCd* pThis, struct urb* pUrb);
-+extern int mgc_submit_urb(MGC_LinuxCd* pThis, struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
++              printk (KERN_WARNING "host can't get major %d\n", MAJOR_NUMBER_OTG);
++              return result;
++      }
 +
-+#ifdef MUSB_V26
-+extern int MGC_LinuxSubmitUrb26(struct urb* pUrb, MUSB_MEMFLAG_TYPE iMemFlags);
-+extern int MGC_LinuxUnlinkUrb26(struct urb* pUrb, int status);
-+#endif
++      DBG(2, "==> rc=%d\n", rc);
++      return rc;
++}
 +
-+#ifdef MUSB_V24
-+extern int MGC_LinuxSubmitUrb24(struct urb* pUrb);
-+extern int MGC_LinuxUnlinkUrb24(struct urb* pUrb);
-+#endif
++EXPORT_SYMBOL(MGC_DriverInit);
 +
-+extern void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
-+extern void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd);
-+extern void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd);
-+extern void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
-+extern void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis);
++/**
++ * release everything...
++ */
++void MGC_DriverCleanup(void)
++{
++      int chr = 0;
 +
++      DBG(2, "<==\n");
 +
-+#else /* host not defined */
++      if ( MGC_nIndex ) {
 +
-+#ifdef MUSB_V26_POST10
-+extern int MGC_LinuxHubSuspend(struct usb_bus *pBus);
-+extern int MGC_LinuxHubResume(struct usb_bus *pBus);
-+#endif
++        chr  = unregister_chrdev (MAJOR_NUMBER_OTG, "st-otg");
++        if (chr < 0)
++                      printk (KERN_INFO"OTG Device cannot unregister %d %d\n", MAJOR_NUMBER_OTG, chr);
 +
-+inline void MGC_HdrcStartTx(MGC_LinuxCd* pThis, uint8_t bEnd) {
-+      DBG(3, "#HOST DISABLED\n");                                              
-+}
++              usb_remove_hcd(hcd1);
++        direct_bus_shutdown();
++        free_irq(udc_address->nIrq,udc_address);
++        MGC_LinuxDeleteProcFs(udc_address);
++              nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG, "OTG");
++        iounmap(udc_address->pRegs);
++        del_timer(&notify_timer);
++        usb_put_hcd(hcd1);
 +
-+inline void MGC_HdrcStopEnd(MGC_LinuxCd* pThis, uint8_t bEnd) {
-+      DBG(3, "#HOST DISABLED\n"); 
-+}
++      }
 +
-+inline void MGC_HdrcServiceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd) { 
-+      DBG(3, "#HOST DISABLED\n");
++      MGC_nIndex=0;
++      DBG(2, "==>\n");
 +}
++EXPORT_SYMBOL(MGC_DriverCleanup);
 +
-+inline void MGC_HdrcServiceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd) {
-+      DBG(3, "#HOST DISABLED\n"); 
-+}
++/*-------------------------------------------------------------------------*/
 +
-+inline void MGC_HdrcServiceDefaultEnd(MGC_LinuxCd* pThis) {
-+      DBG(3, "#HOST DISABLED\n"); 
++/* gstorage is liked to the driver: the init code lives there */
++/* When compiled in the kernel, the init function is needed only when gadget
++ * gadget API is not compiled (usb_register_driver takes care of the init
++ * using MGC_DriverInit & MGC_DriverCleanup)
++ */
++#ifndef MUSB_SKIP_INIT
++
++/**
++ * Required initialization for any module.
++ */
++int __init MGC_ModuleInit (void)
++{
++      return MGC_DriverInit();
 +}
-+#endif
 +
++/**
++ * Required cleanup for any module
++ */
++void __exit MGC_ModuleCleanup (void)
++{
++
++      MGC_DriverCleanup();
++}
 +
-+#endif /* _MUSB_HOST_H */
++module_init(MGC_ModuleInit);
++module_exit(MGC_ModuleCleanup);
++#endif
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbhsfc.h ../new/linux-2.6.20/drivers/usb/nomadik/musbhsfc.h
---- linux-2.6.20/drivers/usb/nomadik/musbhsfc.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musbhsfc.h 2008-08-08 19:15:31.000000000 +0530
-@@ -0,0 +1,150 @@
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_procfs.c
+@@ -0,0 +1,413 @@
 +/*
-+ * linux/drivers/usb/nomadik/musbhsfc.h
++ * linux/drivers/usb/nomadik/musb_procfs.c
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -198312,506 +200972,407 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musbhsfc.h ../new/linux-2.6.20/dri
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+#ifndef __MUSB_HSFC_DEFS_H__
-+#define __MUSB_HSFC_DEFS_H__
++#include <asm/uaccess.h>
 +
-+#define MGC_MAX_USB_ENDS      16
++#include <linux/kernel.h>
++#include <linux/proc_fs.h>
 +
-+#define MGC_END0_FIFOSIZE    64      /* this is non-configurable */
++#include <linux/usb.h>
++#include "musbdefs.h"
++#include "musb_ioctl.h"
 +
-+#define MGC_M_FIFO_EP0     0x20
++/* ----------------------------------------------------------------------- */
 +
-+/*
-+ *     MUSBHSFC Register map 
-+ */
++#if MUSB_DEBUG > 0
++static int atoi(char* buffer, int base, int len) {
++    int result=0, digit=0;
 +
-+/* Common USB registers */
++    while ( len-->0 && (*buffer) ) {
++              digit=((*buffer>='0') && (*buffer<='9'))
++                      ? *buffer-'0'
++                      : ((*buffer>='a') && (*buffer<='f'))
++                      ? *buffer-'a'
++                      : -1;
 +
-+#define MGC_O_HSFC_FADDR      0x00    /* 8-bit */
-+#define MGC_O_HSFC_POWER      0x01    /* 8-bit */
++              if ( digit<0 ) {
++                      break;
++              }
 +
-+#define MGC_O_HSFC_INTRIN     0x02    /* 16-bit */
-+#define MGC_O_HSFC_INTROUT      0x04
-+#define MGC_O_HSFC_INTRINE      0x06  
-+#define MGC_O_HSFC_INTROUTE     0x08  
-+#define MGC_O_HSFC_INTRUSB      0x0A   /* 8 bit */
-+#define MGC_O_HSFC_INTRUSBE     0x0B   /* 8 bit */
-+#define MGC_O_HSFC_FRAME        0x0C  
-+#define MGC_O_HSFC_INDEX        0x0E   /* 8 bit */
-+#define MGC_O_HSFC_TESTMODE     0x0F   /* 8 bit */
++              buffer++;
++              result=result*base+digit;
++    }
 +
-+/* These are actually indexed: */
-+#define MGC_O_HSFC_TXFIFOSZ   0x1a    /* 8-bit (see masks) */
-+#define MGC_O_HSFC_RXFIFOSZ   0x1b    /* 8-bit (see masks) */
-+#define MGC_O_HSFC_TXFIFOADD  0x1c    /* 16-bit offset shifted right 3 */
-+#define MGC_O_HSFC_RXFIFOADD  0x1e    /* 16-bit offset shifted right 3 */
++    return result;
++}
 +
-+/* Endpoint registers */
-+#define MGC_O_HSFC_TXMAXP     0x00
-+#define MGC_O_HSFC_TXCSR      0x02
-+#define MGC_O_HSFC_CSR0               MGC_O_HSFC_TXCSR        /* re-used for EP0 */
-+#define MGC_O_HSFC_RXMAXP     0x04
-+#define MGC_O_HSFC_RXCSR      0x06
-+#define MGC_O_HSFC_RXCOUNT    0x08
-+#define MGC_O_HSFC_COUNT0     MGC_O_HSFC_RXCOUNT      /* re-used for EP0 */
++static int atoi_from_user(const char* buffer, int count) {
++      char digits[8];
++      int len=min(count, 8);
++      copy_from_user(&digits, buffer, len);
++      return atoi(digits, 10, len);
++}
 +
-+/*
-+ *     MUSBHSFC Register bit masks
-+ */
 +
-+/* POWER */
++static const char* decode_address(int index) {
++    static const char* COMMON_REGISTER_MAP[] = {
++      "FAddr", "Power", "IntrTx", "IntrRx",
++      "IntrTxE", "IntrRxE", "IntrUSB", "IntrUSBE",
++      "Frame", "Index","TestMode" };
++    return (index<11) ? COMMON_REGISTER_MAP[index]:NULL;
++}
++#endif
 +
-+#define MGC_M_POWER_ISOUPDATE   0x80 
-+#define       MGC_M_POWER_SOFTCONN    0x40
-+#define       MGC_M_POWER_HSENAB      0x20
-+#define       MGC_M_POWER_HSMODE      0x10
-+#define MGC_M_POWER_RESET       0x08
-+#define MGC_M_POWER_RESUME      0x04
-+#define MGC_M_POWER_SUSPENDM    0x02
-+#define MGC_M_POWER_ENSUSPEND   0x01
++/* ----------------------------------------------------------------------- */
 +
-+/* Interrupt register bit masks */
-+#define MGC_M_INTR_SUSPEND    0x01
-+#define MGC_M_INTR_RESUME     0x02
-+#define MGC_M_INTR_RESET      0x04
-+#define MGC_M_INTR_SOF        0x08 
 +
-+/* TESTMODE */
++/* Write to ProcFS
++ *
++ * C soft-connect
++ * c soft-disconnect
++ * I enable HS
++ * i disable HS
++ * R resume bus
++ * S start session (OTG-friendly when OTG-compiled)
++ * s stop session
++ * F force session (OTG-unfriendly)
++ * E rElinquish bus (OTG)
++ * H request host mode
++ * h cancel host request
++ * P disable the low-power mode that kills us in peripheral mode
++ * D<num> set/query the debug level
++ * Z zap
++ */
++static int MGC_ProcWrite(struct file *file, const char *buffer,
++                                               unsigned long count, void *data)
++{
++    char cmd;
++    uint8_t bReg;
++    uint8_t* pBase=((MGC_LinuxCd*)data)->pRegs;
 +
-+#define MGC_M_TEST_FORCEFS      0x20
-+#define MGC_M_TEST_FORCEHS      0x10
-+#define MGC_M_TEST_PACKET       0x08
-+#define MGC_M_TEST_K            0x04
-+#define MGC_M_TEST_J            0x02
-+#define MGC_M_TEST_SE0_NAK      0x01
++    /* MOD_INC_USE_COUNT; */
++
++    if(copy_from_user(&cmd, buffer, 1) == 0){
++              switch(cmd) {
++              case 'C':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_SOFTCONN;
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++                      }
++                      break;
++
++              case 'c':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_SOFTCONN;
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++                      }
++                      break;
++
++              case 'I':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_HSENAB;
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++                      }
++                      break;
 +
-+/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
-+#define MGC_M_FIFOSZ_DPB      0x10
-+/* allocation size (8, 16, 32, ... 4096) */
-+#define MGC_M_FIFOSZ_SIZE     0x0f
++              case 'i':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_HSENAB;
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++                      }
++                      break;
 +
-+/* CSR0 */
++              case 'R':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER);
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg | MGC_M_POWER_RESUME);
++                              WAIT_MS(10);
++                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
++                              WARN("Power Resumed\n");
++                      } break;
 +
-+#define MGC_M_CSR0_P_SVDSETUPEND  0x0080
-+#define MGC_M_CSR0_P_SVDRXPKTRDY  0x0040
-+#define MGC_M_CSR0_P_SENDSTALL    0x0020
-+#define MGC_M_CSR0_P_SETUPEND     0x0010
-+#define MGC_M_CSR0_P_DATAEND      0x0008
-+#define MGC_M_CSR0_P_SENTSTALL    0x0004
-+#define MGC_M_CSR0_TXPKTRDY       0x0002
-+#define MGC_M_CSR0_RXPKTRDY       0x0001
++              case 'S':
++                      MGC_Session((MGC_LinuxCd*)data);
++                      break;
 +
-+/* TXCSR */
 +
-+#define MGC_M_TXCSR_AUTOSET       0x8000
-+#define MGC_M_TXCSR_ISO           0x4000
-+#define MGC_M_TXCSR_MODE          0x2000
-+#define MGC_M_TXCSR_DMAENAB       0x1000
-+#define MGC_M_TXCSR_FRCDATATOG    0x0800
-+#define MGC_M_TXCSR_P_INCOMPTX    0x0080
-+#define MGC_M_TXCSR_CLRDATATOG    0x0040
-+#define MGC_M_TXCSR_P_SENTSTALL   0x0020
-+#define MGC_M_TXCSR_P_SENDSTALL   0x0010
-+#define MGC_M_TXCSR_FLUSHFIFO     0x0008
-+#define MGC_M_TXCSR_P_UNDERRUN    0x0004
-+#define MGC_M_TXCSR_FIFONOTEMPTY  0x0002
-+#define MGC_M_TXCSR_TXPKTRDY      0x0001
++              case 's':
++                      bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                      bReg &= ~MGC_M_DEVCTL_SESSION;
++                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++                      break;
 +
-+/* RXCSR */
++              case 'F':
++                      bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                      bReg |= MGC_M_DEVCTL_SESSION;
++                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++                      break;
 +
-+#define MGC_M_RXCSR_AUTOCLEAR     0x8000
-+#define MGC_M_RXCSR_P_ISO         0x4000
-+#define MGC_M_RXCSR_DMAENAB       0x2000
-+#define MGC_M_RXCSR_DISNYET       0x1000
-+#define MGC_M_RXCSR_DMAMODE       0x0800
-+#define MGC_M_RXCSR_INCOMPRX      0x0100
-+#define MGC_M_RXCSR_CLRDATATOG    0x0080
-+#define MGC_M_RXCSR_P_SENTSTALL   0x0040
-+#define MGC_M_RXCSR_P_SENDSTALL   0x0020
-+#define MGC_M_RXCSR_FLUSHFIFO     0x0010
-+#define MGC_M_RXCSR_DATAERR       0x0008
-+#define MGC_M_RXCSR_P_OVERRUN     0x0004
-+#define MGC_M_RXCSR_FIFOFULL      0x0002
-+#define MGC_M_RXCSR_RXPKTRDY      0x0001
++              case 'H':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                              bReg |= MGC_M_DEVCTL_HR;
++                              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++                      }
++                      break;
 +
-+/* 
-+ *  register access macros
-+ */
++              case 'h':
++                      if ( pBase ) {
++                              bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++                              bReg &= ~MGC_M_DEVCTL_HR;
++                              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
++                      }
++                      break;
 +
-+/* Get offset for a given FIFO */
-+#define MGC_FIFO_OFFSET(_bEnd) (MGC_M_FIFO_EP0 + (_bEnd * 4))
++                      /* Xap the controller */
++              case 'Z':
++                      MGC_Zap((MGC_LinuxCd*)data);
++                      break;
 +
-+#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c
---- linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.c       2008-08-08 19:15:27.000000000 +0530
-@@ -0,0 +1,321 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_ioctl.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 <asm/uaccess.h>
-+#include <linux/kernel.h>
++#if (MUSB_DEBUG>0)
++                      /* read & write registers */
++              case 'r':
++              case 'w': {
++                      uint8_t index=0;
++                      uint32_t value=0;
++                      char command[64];
 +
-+#include <linux/usb.h>
++                      memset(command, 0, sizeof(command));
++                      copy_from_user(command, buffer, min(count, (unsigned long)63));
 +
-+#include "musbdefs.h"
-+#include "musb_host.h"
++                      /* detrermine the index,
++                      * only the adrress now */
++                      index=atoi(&command[2], 16, count-2);
++                      if ( index>0 && pBase ) {
++                              const char *address=decode_address(index);
 +
-+#ifdef MUSB_DEBUG
-+extern int mgc_slow_device_kludge_delay;
-+#endif
++                              if ( buffer[0]=='r' ) {
++                                      value=(command[1]=='8')
++                                              ? MGC_Read8(pBase, index)
++                                              : (command[1]=='f')
++                                              ? MGC_Read16(pBase, index)
++                                              : 0;
++                              } else {
++                                      /* not write, not yet... */
++                                      index=-1;
++                              }
 +
-+/**
-+ * Zap the driver (warm start)
-+ * @param pThis the controller
-+ */
-+void MGC_Zap(MGC_LinuxCd* pThis) { 
++                              if ( address ) {
++                                      INFO("%s=0x%x\n", address, value);
++                              } else {
++                                      INFO("0x%x=0x%x\n", index, value);
++                              }
++                      }
++                                } break;
 +
-+#ifdef MUSB_PARANOID
-+      if ( !pThis ) {
-+              ERR("Controller not initialized\n");
-+              return;
-+      }
-+#endif
++                      /* set/read debug level */
++              case 'D': {
++                      if ( count>1 ) {
++                              int level=0;
++                              level=atoi_from_user(&buffer[1], count-1);
++                              MGC_SetDebugLevel(level);
++                      } else {
++                              INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel);
++                              /* & dump the status to syslog */
++                      }
++                                } break;
 +
-+      MGC_HdrcStop(pThis);
++                      /* display queue status */
++              case 'Q': {
++                      int index=-1;
++                      char endb[256];
++                      MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
 +
-+#ifdef MUSB_VIRTHUB           
-+      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
-+      pThis->pRootDevice = NULL;
-+      mgc_hcd_flush(pThis);
-+#endif
-+      
-+      WARN("Controller Stopped\n");               
++                      if (count>2) {
++                              index=atoi_from_user(&buffer[1], count-1);
++                      }
 +
++                      if ( dump_header_stats(pThis, endb)>0 ) {
++                              printk(KERN_INFO"%s", endb);
++                      }
 +
 +#ifdef MUSB_HOST
-+      MGC_InitLocalEndPoints(pThis);
-+#endif
++                      if( MUSB_IS_HST(pThis) ) {
++                              if ( index<0 ) {
++                                      uint8_t bEnd;
 +
-+#ifdef MUSB_GADGET
++                                      /* generate the report for the end points */
++                                      for (bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++                                              if ( dump_end_stats(pThis, bEnd, endb)>0 ) {
++                                                      printk(KERN_INFO"%s", endb);
++                                              }
++                                      }
 +
++                              } else {
++                                      if ( dump_end_stats(pThis, index, endb)>0 ) {
++                                              printk(KERN_INFO"%s", endb);
++                                      }
++                              }
++                      }
 +#endif
 +
-+      WAIT_MS(1000);  
-+      MGC_HdrcStart( pThis );
-+      WARN("Controller Restarted\n");             
-+}
 +
-+/**
-+ * Start a session. Depeing on the controller mode (cable end) it will
-+ * pwer VBUS/initiate SRP and/or it will behave like a gadget.
-+ * @param pThis the controller
-+ *
-+ */
-+void MGC_Session(MGC_LinuxCd* pThis) {
-+      uint8_t bReg, sesn=0;
-+      
-+#ifdef MUSB_PARANOID
-+      if ( !pThis ) {
-+              ERR("Controller not initialized\n");
-+              return;
-+      }
-+#endif
-+      
-+      if ( MUSB_IS_ERR(pThis) ) {
-+              WARN("Error mode, zap the driver first\n");
-+      }
++                                } break;
 +
++              case 'd': {
++                      if ( count>1 ) {
++                              int delay=atoi_from_user(&buffer[1], count-1);
++                              MGC_SetDeviceDelay(delay);
++                      }
++                      INFO("mgc_slow_device_kludge_delay=%d\n",
++                              MGC_SetDeviceDelay(-1));
++                                } break;
 +
-+      if ( sesn ) {
-+              ERR("A %s session is active; terminate it first\n",
-+                      MUSB_MODE(pThis));
-+              return;
++                      /* flush */
++              case '?':
++                      INFO("?: you are seeing it\n");
++                      INFO("C/c: soft connect enable/disable\n");
++                      INFO("I/i: hispeed enable/disable\n");
++                      INFO("S/s: session set/clear\n");
++                      INFO("F: \n");
++                      INFO("H: host mode\n");
++                      INFO("r/w: read write register\n");
++                      INFO("Z: zap\n");
++                      INFO("D: set/read dbug level\n");
++                      INFO("Q: show queue status\n");
++                      break;
++#endif
++
++              default:
++                      ERR("Command %c not implemented\n", cmd);
++                      break;
++    }
 +      }
-+      
 +
-+      /* WHY!?!?! this looks like a race condition to me */
-+      bReg = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL);
-+      MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, bReg | MGC_M_DEVCTL_SESSION);
++    return count;
 +}
 +
 +
 +/**
-+ * Change the debug level.
-+ * @param level the new level
-+ */
-+void MGC_SetDebugLevel(int level) {
-+#if MUSB_DEBUG > 0
-+      MGC_DebugLevel=level;
-+      INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel); 
-+#endif        
-+}
-+
-+/**
-+ * Change the slow device delay.
-+ * @param delay the new delay
++ * Read from /proc filesystem.
++ * @param
++ * @param
++ * @param
++ * @param
++ * @param
++ * @param
 + */
-+int MGC_SetDeviceDelay(int delay) {
-+      if ( delay>0 ) {
-+              mgc_slow_device_kludge_delay=delay;
-+      }
-+      return mgc_slow_device_kludge_delay;
-+}
++static int MGC_ProcRead(char *page, char **start,
++      off_t off, int count, int *eof, void *data)
++{
++    off_t len=0;
++    char *buffer;
++    int rc=0, code=0;
++    unsigned long flags;
++    MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
 +
-+/** Dump the current status and compile options.
-+ * @param pThis the device driver instance  
-+ * @param buffer where to dump the status; it must be big enough hold the
-+ * result otherwise "BAD THINGS HAPPENS(TM)".
-+ */
-+int dump_header_stats(MGC_LinuxCd* pThis, char *buffer) {
-+    int code, count=0;
-+    const uint8_t* pBase=pThis->pRegs;
-+      
-+    *buffer=0;
++    spin_lock_irqsave(&pThis->Lock, flags);
 +
-+      code=sprintf(&buffer[count],  
-+              "Compile Options: [debug=%d][dma=%s][gadget=%s][otg=%s][eps=%d]\n", 
-+#if MUSB_DEBUG>0 
-+          MGC_DebugLevel
-+#else
-+              -1
-+#endif    
-+      ,       
-+#ifdef MUSB_DMA
-+              "yes"
-+#else
-+              "no"
-+#endif
-+      ,       
-+#ifdef MUSB_GADGET
-+              "yes"
-+#else
-+              "no"
-+#endif
-+      ,
-+#ifdef MUSB_OTG
-+              "yes"
-+#else
-+              "no"
-+#endif        
-+      ,pThis->bEndCount);
-+      if ( code<0 ) {
-+              ERR("A problem generating the report\n");
-+              return count;
-+      } else {
-+              count+=code;    
++      buffer=kmalloc(4*1024, GFP_USER);
++      if ( !buffer ) {
++              ERR("Out of memory\n");
++              return -1;
 +      }
 +
-+    code=sprintf(&buffer[count], 
-+              "Current Status: %sDRC, Mode=%s (%s=%d) (Power=%02x, DevCtl=%02x)\n",
-+              ( pThis->bIsMultipoint ? "MH" : "H"),
-+              MUSB_MODE(pThis), 
-+#ifdef MUSB_GADGET
-+              "address",
-+              (MUSB_IS_DEV(pThis)?pThis->bAddress:0,
-+#else
-+              "delay",
-+              mgc_slow_device_kludge_delay,
-+#endif                                
-+              MGC_Read8(pBase, MGC_O_HDRC_POWER),
-+              MGC_Read8(pBase, MGC_O_HDRC_DEVCTL));
-+    if ( code<0 ) {
-+              ERR("A problem generating the report\n");
-+              return count;
-+      } else {
-+              count+=code;    
++      /* generate the report for the end points */
++      code=dump_header_stats(pThis, buffer);
++      if ( code>0 ) {
++              len+=code;
 +      }
 +
-+#ifdef MUSB_USE_HCD_DRIVER
-+      {
-+              int i=0;
-+              mgc_hcd_urb_queue *pQueue=mgc_hcd_get_urb_queue(pThis);
++#ifdef MUSB_HOST
++      if( MUSB_IS_HST(pThis) ) {
 +
-+              code=sprintf(&buffer[count], 
-+                      "HCD: urb_queue_count=%d urb_exec_count=%d\n",
-+                      pQueue->urb_queue_count, pQueue->urb_exec_count);
-+              if ( code<0 ) {
-+                      ERR("A problem generating the report\n");
-+                      return count;
-+              } else {
-+                      count+=code;    
-+              }
-+                      
-+              for (i=0; i<pThis->bEndCount; i++) {
-+                      if ( !mgc_ep_is_idle( &pThis->aLocalEnd[i] ) ) {
-+                              code=sprintf(&buffer[count], "ep%d, current=%p\n", 
-+                                      i, MGC_GetCurrentUrb(&pThis->aLocalEnd[i]));
-+                              if ( code<0 ) {
-+                                      ERR("A problem generating the report\n");
-+                                      return count;
-+                              } else {
-+                                      count+=code;    
-+                              }
++              uint8_t bEnd;
++
++              for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++                      code=dump_end_stats(pThis, bEnd, &buffer[len]);
++                      if ( code>0 ) {
++                              len+=code;
 +                      }
 +              }
 +      }
 +#endif
-+      
-+      return count;
++
++    if ( off<len ) {
++              int i=0, togo=len-off;
++              char *s=&buffer[off],*d=page;
++
++              if ( togo>count ) {
++                      togo=count;
++              }
++
++              while ( i++<togo ) {
++                      *d++=*s++;
++              }
++
++              rc=togo;
++    } else {
++              *buffer=0;
++              *eof=1;
++    }
++
++      kfree(buffer);
++    spin_unlock_irqrestore(&pThis->Lock, flags);
++    return rc;
 +}
 +
 +
 +/**
-+ * decode (convert to a name) the protocol used on an endpoint.
-+ * @param pThis the controller
-+ * @param bEnd the endpoint 
++ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
++ * @param data the controller instance
 + */
-+static char* decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd) {
-+    char* pProto = "Err ";
-+      
-+      if ( MUSB_IS_DEV(pThis) ) {
-+#ifdef MUSB_GAGDET            
-+              pProto=decode_dev_ep_protocol(pThis, bEnd);
-+#endif                
-+      } else if ( MUSB_IS_HST(pThis) ) {
-+#ifdef MUSB_HOST              
-+              pProto=decode_hst_ep_protocol(pThis, bEnd);
-+#endif                
-+      }
-+      
-+      return pProto;
++void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data) {
++    remove_proc_entry(data->pProcEntry->name, NULL);
 +}
 +
-+#ifdef MUSB_HOST
++/**
++ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
++ * @param data the controller instance
++ */
++void MGC_LinuxRemoveProcFs(MGC_LinuxCd* data) {
++    remove_proc_entry(data->pProcEntry->name, NULL);
++}
 +
 +/**
-+ * Dump statistics for a local end (driver operaiting in host mode).
-+ * @param pThis the device driver instance  
-+ * @param bEnd
-+ * @param aBuffer the buffer to print the report to
++ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
++ * @param name
++ * @param data the controller instance
 + */
-+int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer) {
-+      int code, count=0;
-+      MGC_LinuxLocalEnd* pEnd=&pThis->aLocalEnd[bEnd];        
++struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, MGC_LinuxCd* data) {
++    if ( !name ) {
++      name=data->aName;
++    }
 +
-+      spin_lock(&pEnd->Lock); 
++    data->pProcEntry=create_proc_entry(name,
++      S_IFREG | S_IRUGO | S_IWUSR, NULL);
++    if( data->pProcEntry )
++    {
++      data->pProcEntry->data = data;
++#ifdef MUSB_V26
++      data->pProcEntry->owner=THIS_MODULE;
++#endif
 +
-+      do { 
-+              
-+              if ( mgc_ep_is_idle(pEnd) ) {
-+                      code=snprintf(aBuffer, 256-count, 
-+                              "End-%01x: Idle (%s, proto=%s, pktsize=%04x, address=%02x, end=%02x\n", 
-+                              bEnd, ( pEnd->bIsTx ? "Tx" : "Rx" ), decode_protocol(pThis, bEnd), 
-+                              pEnd->wPacketSize, pEnd->bRemoteAddress, pEnd->bRemoteEnd);
-+              } else {
-+                      code=snprintf(aBuffer, 256-count, 
-+                              "End-%01x: %s (urb=%p), %s, proto=%s, pkt size=%04x, address=%02x, end=%02x\n", 
-+                              bEnd, "Busy", MGC_GetCurrentUrb(pEnd),
-+                              ( pEnd->bIsTx ? "Tx" : "Rx" ),
-+                              decode_protocol(pThis, bEnd), 
-+                              pEnd->wPacketSize, 
-+                              pEnd->bRemoteAddress, 
-+                              pEnd->bRemoteEnd);              
-+              }
-+              
-+              if ( code<0 ) {
-+                      break;
-+              } else {
-+                      count+=code;    
-+              }
-+      
-+              if ( MUSB_IS_HST(pThis) ) {             
-+                      code = snprintf(&aBuffer[count], 256-count, 
-+                              "  %10ld bytes Rx in %10ld pkts; %10ld errs, %10ld overruns\n",
-+                              pEnd->dwTotalRxBytes, 
-+                              pEnd->dwTotalRxPackets,
-+                              pEnd->dwErrorRxPackets, 
-+                              pEnd->dwMissedRxPackets);
-+                      if ( code<0 ) {
-+                              break;
-+                      } else {
-+                              count+=code;    
-+                      }
-+              
-+                      code=snprintf(&aBuffer[count], 256-count,
-+                              "  %10ld bytes Tx in %10ld pkts; %10ld errs, %10ld underruns\n",
-+                              pEnd->dwTotalTxBytes, 
-+                              pEnd->dwTotalTxPackets,
-+                              pEnd->dwErrorTxPackets, 
-+                              pEnd->dwMissedTxPackets);
-+                      if ( code<0 ) {
-+                              break;
-+                      } else {
-+                              count+=code;    
-+                      }
-+              } else {
-+                      /* no stats for gadget, yet! */
-+              }
-+      } while(0);
++      data->pProcEntry->read_proc = MGC_ProcRead;
++      data->pProcEntry->write_proc = MGC_ProcWrite;
 +
-+      spin_unlock(&pEnd->Lock);       
-+      if ( code<0 ) {
-+              ERR("An error generating the report");
-+              return code;
-+      }
-+      
-+      return count;
-+}
-+#endif
++      data->pProcEntry->size = 0;
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h
---- linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_ioctl.h       2008-07-28 15:21:00.000000000 +0530
-@@ -0,0 +1,32 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_ioctl.h
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 
-+ */
++      dbg("Registered /proc/%s\n", name);
++    } else {
++        dbg ("Cannot create a valid proc file entry");
++    }
 +
-+#include "musbdefs.h"
-+ 
-+void MGC_Zap(MGC_LinuxCd* pThis);
-+void MGC_Session(MGC_LinuxCd* pThis);
-+void MGC_SetDebugLevel(int level);
-+int MGC_SetDeviceDelay(int delay);
-+int dump_header_stats(MGC_LinuxCd* pThis, char *buffer);
-+char*decode_protocol(MGC_LinuxCd* pThis, unsigned bEnd);    
-+#ifdef MUSB_HOST
-+int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
-+#endif
++    return data->pProcEntry;
++}
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c
---- linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c    2008-09-17 13:23:34.000000000 +0530
-@@ -0,0 +1,2306 @@
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_virthub.c
+@@ -0,0 +1,840 @@
 +/*
-+ * linux/drivers/usb/nomadik/musb_plat_uds.c
++ * linux/drivers/usb/nomadik/musb_virthub.c
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -198827,2718 +201388,1908 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_plat_uds.c ../new/linux-2.6.2
 + *
 + * 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 
-+ */
-+
-+/*
-+ * Introduction.
-+ * The ICD works like the other Linux HCDs/Gadgets: it is threadless,
-+ * so it does everything either in response to an interrupt, 
-+ * or during a call from an upper layer.
-+ * It implements a virtual root hub, so as to make uniform use
-+ * of the Linux hub driver.Linux
-+ 
-+ * 
-+ * The Linux (host-side) USB core has no concept of binding (the authors
-+ * apparently missed the point of the pipe discussion in the USB spec).
-+ * Instead, class drivers simply submit URBs, and an HCD may reject
-+ * or defer them if sufficient resources are not available.
-+ * This means class drivers have no way to know if their requirements 
-+ * can possibly be fulfilled, and may be blocked indefinitely by others,
-+ * without the end-user knowing why.
-+ * Therefore, whether things will work depends on the order of URB submissions
-+ * (which is dictated by the order of device insertion and/or driver loading
-+ * and thread scheduling).
-+ * 
-+ * The URB encodes pipe information in an integer, 
-+ * requiring table searches (hurting performance).
-+ * 
-+ * For the HDRC, local endpoint 0 is the only choice for control traffic,
-+ * so it is reprogrammed as needed, and locked during transfers.
-+ * Bulk transfers are queued to the available local endpoint with 
-+ * the smallest possible FIFO in the given direction
-+ * that will accomodate the transactions.
-+ * 
-+ * A typical response to the completion of a periodic URB is immediate
-+ * submission of another one, so the HCD does not assume it can reprogram
-+ * a local periodic-targetted endpoint for another purpose.
-+ * Instead, submission of a periodic URB is taken as a permanent situation,
-+ * so that endpoint is untouched.
-+ * One could imagine reprogramming periodic endpoints for other uses
-+ * between their polling intervals, effectively interleaving traffic on them.
-+ * Unfortunately, this assumes no device would ever NAK periodic tokens.
-+ * This is because the core no notification to software when an attempted
-+ * periodic transaction is NAKed (its NAKlimit feature is only for 
-+ * control/bulk).
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+/*
-+ * Optional macros:
-+ * 
-+ * MUSB_FLAT_REG      if defined, use the core's flag register model
-+ * 
-+ * MUSB_DEBUG         0 => absolutely no diagnostics
-+ *                    1 => minimal diagnostics (basic operational states)
-+ *                    2 => 1 + detailed debugging of interface with USB core
-+ *                    3 => 2 + internal debugging (e.g. every register write)
-+ *                    4 => 3 + shared-IRQ-related checking
-+ * 
-+ * MUSB_DMA           if defined, include DMA support.  
-+ *                    The DMA code to use is included below,
-+ *                    so may need to be edited if a non-Inventra DMA 
-+ *                    controller is used with the Inventra core.
-+ *
-+ * MUSB_AHB_ID                if defined, the core's identity is read from offset 0x400
-+ *                    to verify that the expected core is present
-+ *
-+ * MUSB_CONFIG_PROC_FS        enables statistics/state info in /proc/musbhdrc<n> 
-+ *                    where 0 <= n < number of instances of driver
-+ * 
-+ *
-+ * MUSB_HARD_IRQ try SA_INTERRUPT first when acquiring the irq (fallback to
-+ *                             SA_SHIRQ when that fails.
-+ *
-+ * 
-+ * Options taken from linux/config.h:
-+ * CONFIG_PM          enables power-management
-+ */
 +
++//#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/kernel.h>
 +#include <linux/delay.h>
 +#include <linux/sched.h>
 +#include <linux/slab.h>
++#include <linux/errno.h>
 +#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/usb.h>
++#include <linux/time.h>
++#include <linux/timer.h>
 +
-+#include <asm/uaccess.h>
++#include <linux/usb.h>
 +
-+#ifdef CONFIG_USB_DEBUG
-+#define DEBUG 
++#ifndef MUSB_LINUX_MV21
++#include "../core/hcd.h"
++#define HAS_USB_TT_MULTI
 +#else
-+#undef DEBUG
++#include <hub.h>
 +#endif
 +
-+
 +#include "musbdefs.h"
-+#include "musb_host.h"
-+#include "../core/hcd.h"
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/i2c.h>
-+/********************** RETURN TYPES FOR IRQ ********************************/
-+
-+#ifdef MUSB_V26
-+#define RETURN_IRQ_HANDLED return(IRQ_HANDLED)
-+#define RETURN_IRQ_NONE return(IRQ_NONE)
-+#endif
-+
-+#ifdef MUSB_V24
-+typedef void irqreturn_t;
-+#define RETURN_IRQ_HANDLED return
-+#define RETURN_IRQ_NONE return
-+#endif
-+
-+
-+/* define this on command line */
-+#ifndef MUSB_DEFAULT_IRQTYPE
-+#define MUSB_DEFAULT_IRQTYPE  SA_SHIRQ 
-+#endif
-+
-+/****************************** CONSTANTS ********************************/
-+
-+#define DRIVER_AUTHOR "STMicroelectronics"
-+#define DRIVER_DESC "Nomadik USB Driver"
-+
-+#ifndef MUSB_VERSION
-+#define MUSB_VERSION "x.x"
-+#endif
-+
-+#define DRIVER_INFO DRIVER_DESC "v" MUSB_VERSION 
-+#define DRIVER_NAME "HCD_NAME" 
-+
-+static const char longname[] = DRIVER_INFO;
-+static const char shortname[] = DRIVER_NAME;
-+
-+/* this module is always GPL, the gadget might not... */
-+MODULE_DESCRIPTION (DRIVER_INFO);
-+MODULE_AUTHOR (DRIVER_AUTHOR);
-+MODULE_LICENSE ("GPL");
-+
-+/* time (millseconds) to wait before a restart */
-+#define MUSB_RESTART_TIME       5000
-+/* how many babbles to allow before giving up */
-+#define MUSB_MAX_BABBLE_COUNT 10
-+/* how many buss errors before stopping the operations */
-+#define MUSB_MAX_VBUS_ERRORS  3
-+
-+/* WEIRD KLUDGE! */
-+#define IS_INVALID_ADDRESS(_x) (((unsigned long)_x)<(unsigned long)1024)
-+
-+#define A_IDLE          1
-+#define B_IDLE          2
-+#define PERIPHERAL      3
-+#define HOST            4
-+
-+#define MAJOR_NUMBER_OTG        0x0
-+#define OTG_DEEP_SLEEP          0x1
-+#define OTG_WAKEUP              0x2
-+#define SRP_TEST                0x3
-+#define HNP_TEST                0x4
-+#define PRINT_REG               0x5
-+#define HOST_A_IDLE             0x6
-+#define OTG_SUSPEND             0x7
-+#define OTG_RESUME              0x8
-+
-+#define SUSPEND                 0x0
-+#define RESUME                  0x1
-+
 +
 +/******************************* FORWARDS ********************************/
-+MGC_LinuxCd *udc_address;
-+struct usb_hcd *hcd1;
-+int udcinitmonitorflag_isr=0,udcinitmonitorflag_init=0;
-+extern void driver_change_mode_handler(uint8_t role);
-+void otg_disconnect(MGC_LinuxCd *pThis);
-+int dev_safe_remove=0;
-+extern int Urb_status;
-+struct urb *Urb_struct;
-+uint8_t temp;
-+uint8_t b_hnp_suspend=0;
-+uint8_t b_hnp_init=0;
-+void  del_timer_func(void);
-+extern int udc_setup(void);
-+extern void  udc_reset(void);
-+extern void udc_resume(void);
-+extern void udc_suspend(void);
-+extern void  udc_intr_disable(void);
-+extern uint8_t host_a_idle;
-+static void funct_host_notify_timer(unsigned long pThis);
-+static struct timer_list notify_timer;
-+extern int nomadik_udc_init(MGC_LinuxCd *pThis);
-+extern void musb_reset_isr(void);
-+extern void udc_disconnect_isr(void);
-+extern uint8_t udc_ep0_irq(void);
-+extern void udc_ep_tx_irq(uint8_t bEnd) ;
-+extern void udc_ep_rx_irq(uint8_t bEnd) ;
-+
-+#ifndef MUSB_USE_HCD_DRIVER
-+#ifdef MUSB_VIRTHUB
-+#ifndef MUSB_V26_POST10
-+/* Linux USBD glue */
-+STATIC int mgc_linux_alloc_device(struct usb_device* pDevice);
-+STATIC int mgc_linux_free_device(struct usb_device* pDevice);
-+#endif
-+STATIC int MGC_LinuxGetFrameNumber(struct usb_device* pDevice);
-+#endif
-+#endif
-+
-+STATIC void mgc_reset(MGC_LinuxCd* pThis);
-+uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData);
-+/* Interrupt service routine */
-+#ifndef MUSB_USE_HCD_DRIVER
-+STATIC irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r);
-+#endif
-+
-+#ifdef MUSB_USE_HCD_DRIVER
-+void mgc_hcd_flush(MGC_LinuxCd* pThis);
-+#endif
-+
-+/* HDRC functions */
-+STATIC void MGC_HdrcDropResume(unsigned long pParam);
-+STATIC void MGC_HdrcRestart(unsigned long pParam);
-+
-+STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis);
-+
-+#ifdef MUSB_V26
-+void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
-+      unsigned iMemFlags, dma_addr_t* pDmaAddress);
-+void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
-+      void* address, dma_addr_t DmaAddress);
-+#endif
 +
-+STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis);
++static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub,
++      void (*pfExpired)(unsigned long), unsigned long timeout);
++static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb);
++static void MGC_VirtualHubTimerExpired(unsigned long ptr);
 +
-+#ifdef MUSB_V26_POST10
-+struct usb_bus;
-+int MGC_LinuxHubSuspend(struct usb_bus *pBus);
-+int MGC_LinuxHubResume(struct usb_bus *pBus);
-+#endif
++/******************************* GLOBALS *********************************/
 +
-+#ifdef MUSB_V26
-+void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress);
-+#endif
++/** device descriptor */
++static uint8_t MGC_aVirtualHubDeviceDesc[] =
++{
++    USB_DT_DEVICE_SIZE,
++    USB_DT_DEVICE,
++    0x00, 0x02,                       /* bcdUSB */
++    USB_CLASS_HUB,            /* bDeviceClass */
++    0,                                /* bDeviceSubClass */
++    1,                                /* bDeviceProtocol (single TT) */
++    64,                               /* bMaxPacketSize0 */
++    0xd6, 0x4,                        /* idVendor */
++    0, 0,                     /* idProduct */
++    0, 0,                     /* bcdDevice */
++    0,                                /* iManufacturer */
++    0,                                /* iProduct */
++    0,                                /* iSerialNumber */
++    1                         /* bNumConfigurations */
++};
 +
++/** device qualifier */
++static uint8_t MGC_aVirtualHubQualifierDesc[] =
++{
++    USB_DT_DEVICE_QUALIFIER_SIZE,
++    USB_DT_DEVICE_QUALIFIER,
++    0x00, 0x02,                       /* bcdUSB */
++    USB_CLASS_HUB,            /* bDeviceClass */
++    0,                                /* bDeviceSubClass */
++    0,                                /* bDeviceProtocol */
++    64,                               /* bMaxPacketSize0 */
++    0xd6, 0x4,                        /* idVendor */
++    0, 0,                     /* idProduct */
++    0, 0,                     /* bcdDevice */
++    0,                                /* iManufacturer */
++    0,                                /* iProduct */
++    0,                                /* iSerialNumber */
++    1                         /* bNumConfigurations */
++};
 +
-+/******************************* GLOBALS *********************************/
++/** Configuration descriptor */
++static uint8_t MGC_VirtualHubConfigDesc[] =
++{
++    USB_DT_CONFIG_SIZE,
++    USB_DT_CONFIG,
++    USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
++    0x01,                     /* bNumInterfaces */
++    0x01,                     /* bConfigurationValue */
++    0x00,                     /* iConfiguration */
++    0xE0,                     /* bmAttributes (self-powered, remote wake) */
++    0x00,                     /* MaxPower */
 +
++    /* interface */
++    USB_DT_INTERFACE_SIZE,
++    USB_DT_INTERFACE,
++    0x00,                     /* bInterfaceNumber */
++    0x00,                     /* bAlternateSetting */
++    0x01,                     /* bNumEndpoints */
++    USB_CLASS_HUB,            /* bInterfaceClass */
++    0x00,                     /* bInterfaceSubClass */
++    0x00,                     /* bInterfaceProtocol */
++    0x00,                     /* iInterface */
 +
-+MGC_LinuxCd *hcd_to_musbstruct(void *ptr)  
-+{
-+#ifdef MUSB_USE_HCD_DRIVER
-+      return (MGC_LinuxCd*)((struct usb_hcd *)ptr)->hcd_priv;
-+#else
-+      return (MGC_LinuxCd*)ptr;
-+#endif
-+}
++    /* endpoint */
++    USB_DT_ENDPOINT_SIZE,
++    USB_DT_ENDPOINT,
++    USB_DIR_IN | 1,           /* bEndpointAddress: IN Endpoint 1 */
++    USB_ENDPOINT_XFER_INT,    /* bmAttributes: Interrupt */
++    (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0,            /* wMaxPacketSize */
++    12                        /* bInterval: 256 ms */
++};
 +
-+struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis) 
++/** other-speed Configuration descriptor */
++static uint8_t MGC_VirtualHubOtherConfigDesc[] =
 +{
-+#ifdef MUSB_USE_HCD_DRIVER
-+      return container_of((void*)pThis, struct usb_hcd, hcd_priv);
-+#else
-+      return NULL;
-+#endif
-+}
++    USB_DT_CONFIG_SIZE,
++    USB_DT_OTHER_SPEED,
++    USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
++    0x01,                     /* bNumInterfaces */
++    0x01,                     /* bConfigurationValue */
++    0x00,                     /* iConfiguration */
++    0xE0,                     /* bmAttributes (self-powered, remote wake) */
++    0x00,                     /* MaxPower */
 +
-+/******************************* GLOBALS *********************************/
++    /* interface */
++    USB_DT_INTERFACE_SIZE,
++    USB_DT_INTERFACE,
++    0x00,                     /* bInterfaceNumber */
++    0x00,                     /* bAlternateSetting */
++    0x01,                     /* bNumEndpoints */
++    USB_CLASS_HUB,            /* bInterfaceClass */
++    0x00,                     /* bInterfaceSubClass */
++    0x00,                     /* bInterfaceProtocol */
++    0x00,                     /* iInterface */
 +
-+unsigned int MGC_nIndex = 0;
++    /* endpoint */
++    USB_DT_ENDPOINT_SIZE,
++    USB_DT_ENDPOINT,
++    USB_DIR_IN | 1,           /* bEndpointAddress: IN Endpoint 1 */
++    USB_ENDPOINT_XFER_INT,    /* bmAttributes: Interrupt */
++    (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0,            /* wMaxPacketSize */
++    0xff                      /* bInterval: 255 ms */
++};
 +
-+static const char MGC_HcdName [] = "musb-hcd";
++/****************************** FUNCTIONS ********************************/
 +
-+#ifndef MUSB_USE_HCD_DRIVER
 +/**
-+ * Virtual hub functions: Linux USBD calls these 
++ * Generic timer activation helper. Requires the hub structure to
++ * be locked.
++ *
++ * @param pHub pointer to hub struct
++ * @param pfExpired callback function
++ * @param timeout millisecs
++ * @requires spin_lock(pHub->Lock)
 + */
-+#ifdef MUSB_VIRTHUB
-+static struct usb_operations MGC_LinuxOperations = 
++static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub,
++      void (*pfExpired)(unsigned long), unsigned long timeout)
 +{
-+#ifndef MUSB_V26_POST10
-+      .allocate       =               mgc_linux_alloc_device,
-+      .deallocate =           mgc_linux_free_device,
-+#endif
-+
-+      .get_frame_number =     MGC_LinuxGetFrameNumber,
-+
-+#ifdef MUSB_V24 
-+      .submit_urb =           MGC_LinuxSubmitUrb24,
-+#endif
-+
-+#ifdef MUSB_V26
-+      .submit_urb =           MGC_LinuxSubmitUrb26,
-+#endif
++      DBG(2, "<== pHub=%p, pHub->pUrb=%p\n", pHub, pHub->pUrb);
++    del_timer(&pHub->Timer); /* make sure another timer is not running */
++    init_timer(&(pHub->Timer));
++    pHub->Timer.function = pfExpired;
++    pHub->Timer.data = (unsigned long)pHub;
++    pHub->Timer.expires = jiffies + timeout * HZ / 1000;
++    add_timer( &(pHub->Timer) );
++}
 +
-+#ifdef MUSB_V24 
-+      .unlink_urb =           MGC_LinuxUnlinkUrb24,
-+#endif
-+#ifdef MUSB_V26
-+      .unlink_urb =           MGC_LinuxUnlinkUrb26,
-+#endif
++/**
++ * Report the VHUB status bits. Assumes that pData has enough
++ * storage for all of them.
++ * @param pHub the hub
++ * @param pData the data buffer status shoudl be written to
++ * @return
++ */
++int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData) {
++    int nPort, length=1;
++    uint8_t bData=0, bBit=1;
 +
-+#ifdef MUSB_V26
-+      .buffer_alloc =         MGC_LinuxBufferAlloc,
-+      .buffer_free =          MGC_LinuxBufferFree,    
-+      .disable =                      mgc_linux_disable,
-+#endif
++    /* count 1..N to accomodate hub status bit */
++    for(nPort = 1; nPort <= pHub->bPortCount + 1; nPort++) {
++              if(pHub->aPortStatusChange[nPort-1].wChange & 1) {
++                      bData |= 1 << bBit;
++              }
 +
-+#ifdef MUSB_V26_POST10
-+      .hub_suspend =          MGC_LinuxHubSuspend,
-+      .hub_resume =           MGC_LinuxHubResume,
-+#endif
-+};
-+#endif
-+#endif
++              if(++bBit > 7) {
++                      *pData++ = bData;
++                      bData = bBit = 0;
++                      length++;
++              }
++    }
 +
-+const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE] = {
-+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+    0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+    0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
-+    0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf,
-+    0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf,
-+    0xef, 0xf7, 0xfb, 0xfd, 0x7e
-+};
++    if(bBit) {
++              *pData++ = bData;
++    }
 +
++      return length;
++}
 +
++/*
++ * assumes pHub to be locked!
++ * @requires spin_lock(pHub->Lock)
++ */
++static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb)
++{
++    pHub->bIsChanged = FALSE;
 +
-+int  otg_ioctl                          (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
-+int  otg_open                           (struct inode *inode, struct file *file);
-+int  otg_close                          (struct inode *inode, struct file *file);
-+extern void  otg_deep_sleep(void);
-+extern void  otg_wakeup(void);
-+extern void set_host_a_idle(void);
-+extern void hnp_initiate(void);
-+extern void srp_initiate(void);
++    pUrb->actual_length=mgc_rh_port_status(pHub, (uint8_t*)pUrb->transfer_buffer);
++      if (pUrb->actual_length && pUrb->complete) {
++        COMPLETE_URB(pUrb, NULL);
++    }
++}
 +
-+static struct file_operations otg_fops = {
-+        owner:                 THIS_MODULE,
-+        read:                  NULL,
-+        write:                 NULL,
-+        ioctl:                 otg_ioctl,
-+        open:                  otg_open,
-+        flush:                 NULL,
-+        release:               otg_close,
-+};
++/**
++ * Timer expiration function to complete the interrupt URB on changes
++ * @param ptr standard expiration param (hub pointer)
++ */
++static void MGC_VirtualHubTimerExpired(unsigned long ptr)
++{
++    struct urb* pUrb;
++    MGC_VirtualHub* pHub = (MGC_VirtualHub*)ptr;
 +
++      DBG(2, "<== pHub=%p, pHub->pUrb=%p, pUrb->hcpriv=%p\n", pHub,
++              pHub->pUrb, (pHub->pUrb)?((struct urb*)pHub->pUrb)->hcpriv:NULL);
 +
-+/******************************* GLOBALS *********************************/
++    spin_lock(&pHub->Lock);
++    pUrb=pHub->pUrb;
++    if(pUrb && (pUrb->hcpriv == pHub)) {
++      uint8_t bPort;
 +
-+int otg_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+      /* to prevent compiler warnings */
-+      inode=inode;
-+      filp=filp;
-+      arg=arg;
++              for(bPort = 0; bPort < pHub->bPortCount; bPort++) {
++                      if ( pHub->aPortStatusChange[bPort].wChange ) {
++                              pUrb->status=0;
++                              MGC_VirtualHubCompleteIrq(pHub, pUrb);
++                              break;
++                      }
++              }
 +
-+      switch(cmd) {
-+              
-+      case OTG_DEEP_SLEEP:
-+              del_timer(&notify_timer);               
-+              otg_deep_sleep();
-+              break ;
-+              
-+      case OTG_WAKEUP:
-+              otg_wakeup();
-+              break ;
-+              
-+      case HOST_A_IDLE:
-+              set_host_a_idle ();
-+              break;
-+              
-+      case SRP_TEST:
-+              srp_initiate();
-+              break ;
-+              
-+      case HNP_TEST:
-+              hnp_initiate();
-+              break ;
-+              
-+      case PRINT_REG:
-+              break;
-+              
-+      case OTG_SUSPEND:
-+              break ;
-+              
-+      case OTG_RESUME:
-+              break ;
++              /* re-activate timer only when the urb is still mine; pUrb->hcpriv is
++               * set to NULL on port disconnect */
++              MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired,
++                      pHub->wInterval);
++    } else {
++              DBG(3, "pUrb=%p, for me =%d\n", pUrb, (pUrb)?((pUrb->hcpriv)?1:0):-1 );
 +      }
-+      
-+      return 0;
++    spin_unlock(&pHub->Lock);
 +}
 +
-+
-+int otg_open (struct inode *inode, struct file *file)
++/**
++ * Initialize the virtual hub.
++ * @param pHub
++ * @param pBus
++ * @param bPortCount
++ * @param pPortServices
++ * @return 0 success, <0 when errror
++ */
++int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus,
++    uint8_t bPortCount, MGC_PortServices* pPortServices)
 +{
-+        /* to prevent compiler warnings */
-+        inode=inode;
-+        file=file;
-+
-+        return 0;
-+}
-+
++    uint8_t bPort;
 +
-+int otg_close (struct inode *inode, struct file *file)
-+{
-+        /* to prevent compiler warnings */
-+        inode = inode;
-+        file  = file;
++    if(bPortCount > MGC_VIRTUALHUB_MAX_PORTS) {
++              ERR("Cannot allocate a %d-port device (too many ports)", bPortCount);
++              return -EINVAL;
++    }
 +
-+        return 0;
-+}
++#if defined(MUSB_REGISTER_ROOT_HUB) || !defined(MUSB_USE_HCD_DRIVER)
++    /* allocate device, the hcd driver allocate */
++    pHub->pDevice=USB_ALLOC_DEV(NULL, pBus, 0);
++    if(!pHub->pDevice) {
++              ERR("Cannot allocate a %d-port device", bPortCount);
++              return -ENODEV;
++    }
 +
++    pHub->pDevice->speed=USB_SPEED_HIGH;
++#endif
 +
++    DBG(3, "New device (%d-port virtual hub) @%#lx allocated\n", \
++              bPortCount, (unsigned long)pHub->pDevice);
 +
++    pHub->pBus = pBus;
 +
++      spin_lock_init(&pHub->Lock);
++    pHub->pUrb = NULL;
++    pHub->pPortServices = pPortServices;
++    pHub->bPortCount = bPortCount;
++    pHub->bIsChanged = FALSE;
++    init_timer(&(pHub->Timer)); /* I will need this later */
 +
-+/**************************************************************************
-+ * HDRC functions
-+**************************************************************************/
++    for(bPort = 0; bPort < bPortCount; bPort++) {
++      pHub->aPortStatusChange[bPort].wStatus = 0;
++      pHub->aPortStatusChange[bPort].wChange = 0;
++    }
 +
-+/**
-+ * Timer completion callback to finish resume handling started in ISR
-+ * @param pParam the driver instance
-+ */
-+STATIC void MGC_HdrcDropResume(unsigned long pParam) 
-+{
-+      uint8_t power;
-+      MGC_LinuxCd* pThis = (MGC_LinuxCd*)pParam;
-+      void* pBase = pThis->pRegs;
-+      
-+      DBG(2, "<==\n");
-+      
-+      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME);
-+      
-+#ifdef MUSB_VIRTHUB   
-+      MGC_VirtualHubPortResumed(&(pThis->RootHub), 0);
++#ifdef MUSB_V24
++    usb_connect(pHub->pDevice);
 +#endif
-+}
 +
-+/**
-+ * Timer completion callback to request session again
-+ * (to avoid self-connecting)
-+ * @param pParam the driver instance
-+ */
-+STATIC void MGC_HdrcRestart(unsigned long pParam)
-+{
-+      MGC_HdrcStart((MGC_LinuxCd*)pParam);
++    return 0; /* OK */
 +}
 +
-+/* -------------------------------------------------------------------------
-+ *
-+ * ------------------------------------------------------------------------ */
-+
 +/**
-+ * Load an HDRC FIFO
-+ *
-+ * @param pBase base address of HDRC
-+ * @param bEnd local endpoint
-+ * @param wCount how many bytes to load
-+ * @param pSource data buffer
++ * Destroy a virtual hub
++ * @param pHub the vhub to destroy
 + */
-+void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd, 
-+                    uint16_t wCount, const uint8_t* pSource)
++void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub)
 +{
-+      uint16_t wIndex, wIndex32;
-+      uint16_t wCount32 = wCount >> 2;
-+      uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd);
-+      DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pSrc=%p\n",
-+              pBase, bEnd, wCount, pSource);
-+      
-+#ifdef MUSB_PARANOID
-+      if ( IS_INVALID_ADDRESS(pSource) ) {
-+              ERR("loading fifo from a null buffer; why did u do that????\n");
-+              return;
-+      }
++#ifdef MUSB_USE_HCD_DRIVER
++      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
 +#endif
-+      
-+      /* doublewords when possible */
-+      for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) {
-+              MGC_Write32(pBase, bFifoOffset, *((uint32_t*)&(pSource[wIndex])));
-+      }
-+      
-+      for(; wIndex < wCount; wIndex++) {
-+              MGC_Write8(pBase, bFifoOffset, pSource[wIndex]);
-+      }
 +}
 +
 +/**
-+ * Unload an HDRC FIFO
-+ *
-+ * @param pBase base address of HDRC
-+ * @param bEnd local endpoint
-+ * @param wCount how many bytes to unload
-+ * @param pDest data buffer
++ * Start a virtual hub. Set the address and create a new device for it.
++ * @param pHub the vhub to start.
 + */
-+void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd, 
-+                      uint16_t wCount, uint8_t* pDest)
++void MGC_VirtualHubStart(MGC_VirtualHub* pHub)
 +{
-+      uint16_t wIndex=0, wIndex32;
-+      uint16_t wCount32 = wCount >> 2;
-+      uint8_t bFifoOffset = MGC_FIFO_OFFSET(bEnd);
-+      
-+#ifdef MUSB_PARANOID
-+      if ( IS_INVALID_ADDRESS(pDest) ) {
-+              ERR("unloading fifo from a null buffer\n");
-+              return;
-+      }
++    DBG(2, "<== announcing pHub=%p to usbcore\n", pHub);
++      pHub->bAddress=1;
++
++#ifdef MUSB_REGISTER_ROOT_HUB
++#ifndef MUSB_USE_HCD_DRIVER
++      if ( USB_NEW_DEVICE(pHub) ) {
++        ERR("usb_new_device failed\n");
++    }
++#endif
 +#endif
-+      
-+      DBG(2, "pBase=%p, bEnd=%d, wCount=0x%04x, pDest=%p\n", pBase, bEnd,
-+              wCount, pDest);
-+      
-+      /* doublewords when possible */
-+      for(wIndex = wIndex32 = 0; wIndex32 < wCount32; wIndex32++, wIndex += 4) {
-+              *((uint32_t*)&(pDest[wIndex])) = MGC_Read32(pBase, bFifoOffset);
-+      }
-+      
-+      while(wIndex < wCount) {
-+              pDest[wIndex++]=MGC_Read8(pBase, bFifoOffset);
-+      }
-+}
 +
-+/* -------------------------------------------------------------------------
-+ *
-+ * ------------------------------------------------------------------------ */
++      DBG(2, "==>\n");
++}
 +
 +/**
-+ * Stop the host controller driver. Stop the controller and disconnect the
-+ * virtual hub.
-+ * @param pThis the controller
-+ * @param vberr !=0 if a VBUs error was discovered.
++ * Stop a virtual hub.
++ * @param pHub the vhub to stop
 + */
-+static void hdrc_stop_host(MGC_LinuxCd* pThis, int vberr) 
++void MGC_VirtualHubStop(MGC_VirtualHub* pHub)
 +{
-+      MGC_HdrcStop(pThis);
-+      
-+#ifdef MUSB_VIRTHUB   
-+      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
-+      pThis->pRootDevice = NULL;
-+      mgc_hcd_flush(pThis);
++#ifndef MUSB_USE_HCD_DRIVER
++    /* stop interrupt timer */
++    del_timer_sync(&pHub->Timer);
 +#endif
-+      
 +}
 +
-+/**
-+ * Interrupt Service Routine to record USB "global" interrupts.
-+ * Since these do not happen often and signify things of 
-+ * paramount importance, it seems OK to check them individually;
-+ * there is an ORDER to perform the tests check p35 of the MUSBHDRC 
-+ * manual.
++/** Submit an URB to the virtual hub.
++ *  bRequest:
++ *            00
++ *            01
++ *            03
 + *
-+ * @param pThis instance pointer
-+ * @param bIntrUSB register contents
-+ * @param devctl
-+ * @param power
++ *    bmRequestType:
++ *            0x23
++ *            0xa3
++ *
++ * @param pHub the hub urb should be submitted to
++ * @param pUrb the urb to submit
 + */
-+static int mgc_hdrc_service_usb_stage0(MGC_LinuxCd* pThis, uint8_t bIntrUSB,
-+                                     uint8_t devctl, uint8_t power)
++int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb)
 +{
-+      int handled=0;
-+#ifdef MUSB_HOST
-+      uint8_t bSpeed = 1;
-+      uint8_t bHubSpeed = 2;
-+#endif
-+      uint8_t bResetBabble = FALSE;
-+      uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+      
-+      /* in host mode when a device resume me (from power save)
-+       * in device mode when the host resume me; it shold not change 
-+       * "identity".
-+       */
-+      if (bIntrUSB & MGC_M_INTR_RESUME) {
-+              handled++;
-+              DBG(2, "RESUME\n");
-+              
-+              if (devctl & MGC_M_DEVCTL_HM) {
-+#ifdef MUSB_HOST
-+                      printk("Host Mode : resume\n");
-+                      power &= ~MGC_M_POWER_SUSPENDM;
-+                      MGC_Write8(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
-+                      MGC_LinuxSetTimer(pThis, MGC_HdrcDropResume, 
-+                              (unsigned long)pThis, 40);
-+#endif
-+              }
-+              else {
-+                      udc_resume();
-+                      printk("Device Mode : resume\n");
-+              }
-+      }
-+      
-+      /* p35 MUSBHDRC manual for the order of the tests */    
-+      if (bIntrUSB & MGC_M_INTR_SESSREQ) {
-+              DBG(2, "SESSION_REQUEST\n");
-+              
-+              /* NOTE i might get a sesison request WHILE switchign between B and A 
-+               * device investigatge about that; check p35 of the manual 
-+               */
-+#ifdef MUSB_PARANOID          
-+              if ( HDRC_IS_DEV(pThis) ) {
-+                      ERR("Received a SESSION_REQUEST when connected to the B end; am I switching?!\n");                       
-+              }
-+#endif
-+              
-+              /* time critical code (turn on VBUS); inherent race condition */
-+              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
-+              pThis->bEnd0Stage = MGC_END0_START;
-+              
-+              handled++;
-+              
-+      }
-+      
-+      /* VBUSError is bad, shutdown &  go to error mode and ignore 
-+      * the other interrups; p35 MUSBHDRC manual for the order 
-+      of the tests */ 
-+      if (bIntrUSB & MGC_M_INTR_VBUSERROR) {
-+              handled++;
-+              
-+#ifdef MUSB_PARANOID          
-+              if ( !(devctl & MGC_M_DEVCTL_HM) ) {
-+                      ERR("Received a MGC_M_INTR_VBUSERROR when connected to the B end!\n");
-+                      hdrc_stop_host(pThis, FALSE); 
-+                      return handled;                          
-+              }
-+#endif
-+              
-+              DBG(2, "V_BUS ERROR??? this is bad (TM)\n");
-+              if ( pThis->bVbusErrors++ > MUSB_MAX_VBUS_ERRORS ) {
-+                      printk("Vbus Error\n");
-+                      hdrc_stop_host(pThis, TRUE);    
-+                      MUSB_ERR_MODE(pThis, MUSB_ERR_VBUS);
-+              }
-+      }
-+      
-+      /* connect is valid only when in host mode; ignore it if in device mode;
-+      p35 MUSBHDRC manual for the order of the tests */       
-+      
-+      
-+      if(bIntrUSB & MGC_M_INTR_CONNECT) {
-+              handled++;
-+              Urb_status=0;
-+              
-+              if(host_a_idle==1){
-+                      host_a_idle=0;
-+              }
-+              DBG(2, "RECEIVED A CONNECT (goto host mode)\n");
-+              printk("connect interrupt\n");
-+#ifdef MUSB_PARANOID          
-+              if ( !(devctl & MGC_M_DEVCTL_HM) ) {
-+                      ERR("Received a CONNECT when connected to the B end!\n");
-+              }
-+#endif
-+              MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
-+              MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
-+              
-+#ifdef MUSB_HOST
-+              pThis->pRootDevice = NULL;
-+              pThis->bEnd0Stage = MGC_END0_START;
-+              
-+              /* reset the addres... probably not needed*/
-+              MGC_Write8(pThis->pRegs, MGC_O_HDRC_FADDR, 0);
-+              /* flush endpoints when transitioning from Device Mode*/
-+              if ( MUSB_IS_A_IDLE(pThis) ) {
-+                      uint8_t bEnd;
-+                      
-+                      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+                              MGC_HdrcStopEnd(pThis, bEnd);
-+                      }
-+              }
-+              
-+              
-+              if(devctl & MGC_M_DEVCTL_LSDEV) {
-+                      bSpeed = 3;
-+                      bHubSpeed = 0;
-+              } else if(devctl & MGC_M_DEVCTL_FSDEV) {
-+                      /* NOTE: full-speed is "speculative" until reset */
-+                      bSpeed = 2;
-+                      bHubSpeed = 1;
-+              }
-+              
-+              pThis->bRootSpeed = bSpeed;
-+              if(pThis->bIsMultipoint) {
-+                      /* set speed for EP0 */
-+                      MGC_SelectEnd(pBase, 0);
-+                      MGC_WriteCsr8(pBase, MGC_O_HDRC_TYPE0, 0, 
-+                              (bSpeed << 6));
-+              }
-+              
-+              MUSB_HST_MODE(pThis);
-+              
-+              /* indicate new connection to OTG machine */
-+              MGC_VirtualHubPortConnected(&(pThis->RootHub), 0, 
-+                      bHubSpeed);
-+#endif                                        
-+      }
-+      
-+      /* saved one bit: bus reset and babble share the same bit;
-+      * If I am host is a babble! i must be the only one allowed
-+      * to reset the bus; when in otg mode it means that I have 
-+      * to switch to device
-+      */
-+      if (bIntrUSB & MGC_M_INTR_RESET) {
-+              
-+#ifndef MUSB_OTG
-+              
-+              /* This is added since, Mentor IP same bit is shared for RESET and BABBLE. 
-+               * In host mode if this bit is set to indicate BABBLE, but when this bit 
-+               * get set the controller clears the session bit and the host mode bit in
-+               * device control register and driver reads it as RESET and tries to enter 
-+               * in device mode. So if OTG is not set we will check the driver status and
-+               * the appropriate action.
-+               */
++    uint8_t bRecip;           /* from standard request */
++    uint8_t bReqType;         /* from standard request */
++    uint8_t bType;            /* requested descriptor type */
++    uint16_t wValue;          /* from standard request */
++    uint16_t wIndex;          /* from standard request */
++    uint16_t wLength;         /* from standard request */
++    uint8_t bPort;
++    const MUSB_DeviceRequest* pRequest;
++    uint16_t wSize = 0xffff;
++    uint8_t* pData = (uint8_t*)pUrb->transfer_buffer;
++    unsigned int pipe = pUrb->pipe;
 +
-+              if(MUSB_IS_HST(pThis)){
-+                      bResetBabble = TRUE;
-+              }
-+#else
-+              bResetBabble = devctl & MGC_M_DEVCTL_HM;
++      DBG(-1, "<== pUrb=%p\n", pUrb);
++
++#ifdef MUSB_USE_HCD_DRIVER
++      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
 +#endif
-+              DBG(2, "BUS RESET\n");
 +
-+              if (bResetBabble) {
-+                      printk("Host Mode : reset\n");
-+                      hdrc_stop_host(pThis, FALSE);
-+                      /* restart session after cooldown unless threshold reached */ 
-+                      if( pThis->nBabbleCount++ < MUSB_MAX_BABBLE_COUNT) {
-+                              MGC_LinuxSetTimer(pThis, MGC_HdrcRestart, 
-+                                      (unsigned long)pThis, MUSB_RESTART_TIME);
-+                      }
-+              } else {
-+                      
-+                      del_timer(&notify_timer);
-+                      pThis->bEnd0Stage = MGC_END0_START;     
-+                      MUSB_DEV_MODE(pThis);
-+                      printk("Device Mode : reset\n");
-+                      
-+                      if(b_hnp_init == 1){
-+                              otg_disconnect(udc_address);
-+                              driver_change_mode_handler(2);
-+                              devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                              
-+                      }
++    spin_lock(&pHub->Lock);
++    usb_get_urb(pUrb);
 +
-+                      if(udcinitmonitorflag_isr==0){
-+                              nomadik_udc_init(udc_address);
-+                      }
-+                      udcinitmonitorflag_init=1;
-+                      power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+                      musb_reset_isr(); 
-+                      dev_safe_remove=1;      
-+              }
-+              handled++;
-+      }
-+      
-+      return handled;
-+}
++    pUrb->hcpriv = pHub;
++    pUrb->status = -EINPROGRESS;
 +
++    if ( usb_pipeint(pipe) ) {
++      DBG(-1, "pUrb=%p is periodic status/change event\n", pUrb );
 +
-+/**
-+ * Interrupt Service Routine to record USB "global" interrupts.
-+ * Since these do not happen often and signify things of 
-+ * paramount importance, it seems OK to check them individually;
-+ * there is an ORDER to perform the tests check p35 of the MUSBHDRC 
-+ * manual.
-+ *
-+ * @param pThis instance pointer
-+ * @param bIntrUSB register contents
-+ * @param devctl
-+ * @param power
-+ */
-+static int mgc_hdrc_service_usb_stage1(MGC_LinuxCd* pThis, uint8_t bIntrUSB,
-+      uint8_t devctl, uint8_t power)
++        /* this is the one for periodic status/change events */
++        pHub->pUrb = pUrb;
++              pHub->wInterval = (pUrb->interval < 16) ? (1 << (pUrb->interval - 1)) :
++              pUrb->interval;
++        spin_unlock(&pHub->Lock);
++              return 0;
++    }
 +
-+{
-+      int handled=0;
-+    uint8_t bEnd;
-+    uint16_t wFrame;
-+      uint8_t state;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+      /* p35 MUSBHDRC manual for the order of the tests */
-+    if(bIntrUSB & MGC_M_INTR_SOF) {
-+              DBG(2, "START_OF_FRAME\n");
-+              handled++;
++    /* handle hub requests/commands */
++    pRequest = (const MUSB_DeviceRequest*)pUrb->setup_packet;
++    bReqType = pRequest->bmRequestType & USB_TYPE_MASK;
++    bRecip = pRequest->bmRequestType & USB_RECIP_MASK;
++    wValue = le16_to_cpu(pRequest->wValue);
++    wIndex = le16_to_cpu(pRequest->wIndex);
++    wLength = le16_to_cpu(pRequest->wLength);
 +
-+        /* start any periodic Tx transfers waiting for current frame */
-+        wFrame = MGC_Read16(pBase, MGC_O_HDRC_FRAME);
-+              for(bEnd = 1; 
-+              (bEnd < pThis->bEndCount) && (pThis->wEndMask >= (1 << bEnd)); 
-+                      bEnd++)
-+              {                       
-+                      if(pThis->aLocalEnd[bEnd].dwWaitFrame &&
-+                              pThis->aLocalEnd[bEnd].dwWaitFrame >= wFrame)
++    DBG(3, "pRequest->bRequest=%02x, pRequest->bmRequestType=%02x, wLength=%04x\n",
++      pRequest->bRequest, pRequest->bmRequestType, wLength);
++
++    switch (pRequest->bRequest) {
++              case USB_REQ_GET_STATUS:
++                      DBG(3, "GET_STATUS(), bType=%02x, bRecip=%02x, wIndex=%04x\n", \
++                              bReqType, bRecip, wIndex);
++
++                      if(USB_TYPE_STANDARD == bReqType) {
++                              /* self-powered */
++                              pData[0] = (USB_RECIP_DEVICE == bRecip) ? 1 : 0;
++                              pData[1] = 0;
++                              wSize = 2;
++                      } else if(USB_TYPE_CLASS == bReqType) {
++                              if((USB_RECIP_OTHER == bRecip) && (wIndex <= pHub->bPortCount)) {
++                                      /* port status/change report */
++                                      memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2);
++                                      memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange),
++                                              2);
++
++                                      /* reset change (TODO: lock) */
++                                      pHub->aPortStatusChange[wIndex-1].wChange = 0;
++                                      wSize = 4;
++                              } else {
++                                      /* hub status */
++                                      memset(pData, 0, 4);
++                                      wSize = 4;
++                              }
++
++                              DBG(2, "status report=%02x%02x%02x%02x\n", \
++                              pData[0], pData[1], pData[2], pData[3]);
++                      }
++              break;
++
++              case USB_REQ_CLEAR_FEATURE:
++                      bPort = (uint8_t)(wIndex & 0xff) - 1;
++                      DBG(3, "CLR_FEAT bReqType=0x%x, wValue=0x%x, wIndex=0x%x\n",
++                              bReqType, wValue, (wIndex & 0xff) );
++              if((USB_TYPE_STANDARD == bReqType) && (USB_RECIP_ENDPOINT == bRecip))
++              {
++                      wSize = 0;
++                      DBG(3, "END POINT FEATURE!\n");
++              } else if(USB_TYPE_CLASS == bReqType) {
++
++                      if(USB_RECIP_OTHER == bRecip)
 +                      {
-+                              pThis->aLocalEnd[bEnd].dwWaitFrame = 0;
-+                              MGC_HdrcStartTx(pThis, bEnd);
++                              bPort = (uint8_t)(wIndex & 0xff) - 1;
++                              DBG(3, "CLEAR_PORT_FEATURE(%d), port %d\n", \
++                                      wValue, bPort);
++                              switch(wValue) {
++                                      case USB_PORT_FEAT_CONNECTION:
++                                      case USB_PORT_FEAT_OVER_CURRENT:
++                                      case USB_PORT_FEAT_POWER:
++                                      case USB_PORT_FEAT_LOWSPEED:
++                                      case USB_PORT_FEAT_HIGHSPEED:
++                                      case USB_PORT_FEAT_TEST:
++                                      case USB_PORT_FEAT_INDICATOR:
++                                              DBG(3, "feat 0x%02x, wIndex=%d\n", wValue, bPort);
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_ENABLE:
++                                              DBG(4, "enable port %d\n", bPort);
++                                              pHub->pPortServices->pfSetPortEnable(
++                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_SUSPEND:
++                                              DBG(3, "suspend port %d\n", bPort);
++                                              pHub->pPortServices->pfSetPortSuspend(
++                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_RESET:
++                                              DBG(4, "reset port %d\n", bPort);
++                                              pHub->pPortServices->pfSetPortReset(
++                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
++                                              wSize = 0;
++                                              break;
++
++                                      /* acknowledge changes: */
++                                      case USB_PORT_FEAT_C_CONNECTION:
++                                              DBG(3, "ack connection port %d\n", bPort);
++                                              pHub->aPortStatusChange[bPort].wChange &= ~1;
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_C_ENABLE:
++                                              DBG(3, "ack enable port %d\n", bPort);
++                                              pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE;
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_C_SUSPEND:
++                                              DBG(3, "ack suspend port %d\n", bPort);
++
++                                              pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND;
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_C_RESET:
++                                              DBG(3, "ack reset port %d\n", bPort);
++                                              pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET;
++                                              wSize = 0;
++                                              break;
++                                      case USB_PORT_FEAT_C_OVER_CURRENT:
++                                              DBG(3, "ack over current port %d\n", bPort);
++                                              wSize = 0;
++                                              break;
++
++                                      default:
++                                              INFO("clear feature 0x%02x on port=%d unknown\n", wValue, bPort);
++                                              break;
++                              }
++                      } else {
++                              DBG(3, "clear wValue=%d on port=%d\n", wValue, bPort);
++                              switch(wValue) {
++                                      case C_HUB_LOCAL_POWER:
++                                      case C_HUB_OVER_CURRENT:
++                                              wSize = 0;
++                                              break;
++                              }
 +                      }
++                      pHub->bIsChanged = TRUE;
 +              }
-+      }
++              break;
 +
-+      /* p35 MUSBHDRC manual for the order of the tests */
-+      if((bIntrUSB & MGC_M_INTR_DISCONNECT) && !pThis->bIgnoreDisconnect) {
-+              DBG(2, "DISCONNECT()\n");
-+              
-+              mdelay(500);    
-+              handled++;
-+              /* need to check it against pThis, because the devctl is going 
-+               * low as soon as the device gets disconnected */
-+              if ( MUSB_IS_HST(pThis) ) {
-+                      printk("Host Disconnect\n");
-+                      DBG(3, "Disconnecting a port of VirtualHub\n");
-+                      
-+#ifdef MUSB_VIRTHUB   
-+                      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
-+                      pThis->pRootDevice = NULL;
-+                      
-+                      Urb_status=1;
-+                      /* flush endpoints */
-+                      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+                              MGC_HdrcStopEnd(pThis, bEnd);
-+                      }
++              case USB_REQ_SET_FEATURE:
++                      if((USB_TYPE_CLASS == bReqType) && (USB_RECIP_OTHER == bRecip))
++              {
++                      bPort = (uint8_t)(wIndex & 0xff) - 1;
++                      DBG(3, "SET_PORT_FEATURE(0x%02x), port %d\n", wValue, bPort);
++                      switch(wValue) {
++                              case USB_PORT_FEAT_SUSPEND:
++                                      DBG(3, "suspend port %d\n", bPort);
++                                              pHub->pPortServices->pfSetPortSuspend(
++                                              pHub->pPortServices->pPrivateData, bPort, TRUE);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND;
++                                      pHub->bIsChanged = TRUE;
++                                      wSize = 0;
++                                      break;
 +
-+                      mgc_hcd_flush(pThis);
++                              case USB_PORT_FEAT_RESET:
++                                      DBG(3, "reset port %d\n", bPort);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET;
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
++                                      pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET;
++                                      pHub->bIsChanged = TRUE;
++                                      pHub->pPortServices->pfSetPortReset(pHub->pPortServices->pPrivateData,
++                                              bPort, TRUE);
++                                      wSize = 0;
++                                      break;
 +
-+                      MUSB_A_IDLE_MODE(pThis);
-+            mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
++                              case USB_PORT_FEAT_POWER:
++                                      DBG(3, "power port %d\n", bPort);
++                                      pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData,
++                                              bPort, TRUE);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER;
++                                      wSize = 0;
++                                      break;
 +
-+#endif
-+      
-+#ifdef MUSB_CONFIG_PROC_FS
-+                      if(pThis->pfDisconnectListener) {
-+                              pThis->pfDisconnectListener(pThis->pDisconnectListenerParam);
++                              case USB_PORT_FEAT_ENABLE:
++                                      DBG(3, "enable port %d\n", bPort);
++                                      pHub->pPortServices->pfSetPortEnable(pHub->pPortServices->pPrivateData,
++                                              bPort, TRUE);
++                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
++                                      wSize = 0;
++                                      break;
 +                      }
-+#endif
++              } else {
++                      DBG(3, "SET_FEATURE(%04x), but feature unknown\n", wValue);
 +              }
-+               else if (MUSB_IS_DEV(pThis) ){
++              break;
 +
-+               if(b_hnp_init == 1){
-+                      del_timer(&notify_timer);
-+                      b_hnp_init=0;
-+              }
++              case USB_REQ_SET_ADDRESS:
++                      pHub->bAddress = (wValue & 0x7f);
++                      DBG(3, "SET_ADDRESS(%x) \n", pHub->bAddress);
++                              wSize = 0;
++              break;
 +
-+               else {
-+                      printk("Device Disconnect\n");  
-+                      udc_disconnect_isr();
-+                      MUSB_B_IDLE_MODE(pThis);
-+                      mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
++              case USB_REQ_GET_DESCRIPTOR:
++                      if(USB_TYPE_CLASS == bReqType) {
++                              DBG(3, "GET_CLASS_DESCRIPTOR()\n");
++
++                              pData[0] = 9;
++                              pData[1] = 0x29;
++                              pData[2] = pHub->bPortCount;
++                              /* min characteristics */
++                              pData[3] = 1;  /* invidual port power switching */
++                              pData[4] = 0;
++                              /* PowerOn2PowerGood */
++                              pData[5] = 50;
++                              /* no current */
++                              pData[6] = 0;
++                              /* removable ports */
++                              pData[7] = 0;
++                              /* reserved */
++                              pData[8] = 0xff;
++                              wSize = pData[0];
++                      } else {
++                              bType = (uint8_t)(wValue >> 8);
++                              DBG(3, "GET_DESCRIPTOR(%d)\n", bType);
++                              switch(bType) {
++                                      case USB_DT_DEVICE: /* 1 */
++                                              wSize = min(wLength, (uint16_t)MGC_aVirtualHubDeviceDesc[0]);
++                                      memcpy(pData, MGC_aVirtualHubDeviceDesc, wSize);
++                                      break;
++                                      case USB_DT_DEVICE_QUALIFIER:
++                                              wSize = min(wLength, (uint16_t)MGC_aVirtualHubQualifierDesc[0]);
++                                      memcpy(pData, MGC_aVirtualHubQualifierDesc, wSize);
++                                      break;
++                                      case USB_DT_CONFIG: /* 2 */
++                                              wSize = min(wLength, (uint16_t)MGC_VirtualHubConfigDesc[2]);
++                                      memcpy(pData, MGC_VirtualHubConfigDesc, wSize);
++                                      break;
++                                      case USB_DT_OTHER_SPEED:
++                                              wSize = min(wLength, (uint16_t)MGC_VirtualHubOtherConfigDesc[2]);
++                                      memcpy(pData, MGC_VirtualHubOtherConfigDesc, wSize);
++                                      break;
++                              }
 +                      }
-+                }
++              break;
 +
-+              /* KLUDGE: race condition, doing this right away might prevent 
-+               * the virtual hub/usbcore to process the last urbs. As a matter 
-+               * of facts this code should be called after the "disconnect" */
++              case USB_REQ_GET_CONFIGURATION:
++              DBG(3, "GET_CONFIG() => 1\n");
++                      pData[0] = 1;
++              wSize = 1;
++              break;
++
++              case USB_REQ_SET_CONFIGURATION:
++              DBG(3, "SET_CONFIG(%04x)\n", wValue);
++                      wSize = 0;
++              break;
++
++    }   /* END: switch on request type */
++
++    if(0xffff == wSize) {
++        pUrb->status = USB_ST_STALL;
++    } else {
++              pUrb->actual_length = wSize;
++              pUrb->status = 0;
 +    }
 +
-+      /* I cannot get suspend while in host mode! go to error mode and ignore 
-+       * the other signals; need to be last (see manual p35)s  */
-+      if (bIntrUSB & MGC_M_INTR_SUSPEND) {            
-+              DBG(2, "RECEIVED SUSPEND\n");
-+              if( b_hnp_suspend ==1)
-+                {
-+                      uint8_t linestate;
-+                      MGC_HdrcReadUlpiReg(pThis, 0x15, &linestate);
-+                      b_hnp_suspend = 0;
-+                      driver_change_mode_handler(1);  
-+              }
-+              handled++;
-+              
-+              if(devctl & MGC_M_DEVCTL_HM) {
-+                      hdrc_stop_host(pThis, FALSE);
-+              } 
-+              if(dev_safe_remove==1)
-+              {
-+                      udc_suspend();
-+                      printk("Device Removed Safely \n");
-+                      dev_safe_remove=0;
-+                      state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);      
-+                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
-+              }
++    spin_unlock(&pHub->Lock);
++    if (pUrb->complete) {
++              DBG(3, "completing URB status=%d\n", pUrb->status );
++               COMPLETE_URB(pUrb, NULL);
++              pUrb->hcpriv = NULL;
++              usb_put_urb(pUrb);
++              DBG(4, "URB completed\n");
 +    }
 +
-+      return handled;
-+}
++    DBG(2, "==> pUrb->status=%d %s, length=%d, completed=%s\n", pUrb->status, \
++      (pUrb->status)?"(STALL)":"", pUrb->actual_length,
++              (pUrb->complete)?"yes":"no");
 +
++    return 0;
++}
 +
 +/**
-+* Program the HDRC to start (enable interrupts, etc.).
-+ * @param pThis the controller
-+*/
-+void MGC_HdrcStart(MGC_LinuxCd* pThis)
++ * Unlink an URB from a virtual hub.
++ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
++ * @param pUrb URB pointer
++ * @return Linux status code
++ * @see #MGC_VirtualHubInit
++ */
++int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb)
 +{
-+    uint8_t bEnd=1;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    DBG(2, "<== pUrb=%p\n", pUrb);
 +
-+    DBG(2, "<==\n");
-+      
-+    /* init the local ends */
-+#ifdef MUSB_CONFIG_PROC_FS
-+    pThis->aLocalEnd[0].dwTotalRxBytes = 0;
-+    pThis->aLocalEnd[0].dwTotalRxPackets = 0;
-+    pThis->aLocalEnd[0].dwErrorRxPackets = 0;
-+    pThis->aLocalEnd[0].dwTotalTxBytes = 0;
-+    pThis->aLocalEnd[0].dwTotalTxPackets = 0;
-+    pThis->aLocalEnd[0].dwErrorTxPackets = 0;
++#ifdef MUSB_USE_HCD_DRIVER
++      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
 +#endif
 +
-+      /* init counters and local data */
-+    for(bEnd=1; bEnd < pThis->bEndCount; bEnd++) {    
-+      spin_lock( &pThis->aLocalEnd[bEnd].Lock );
-+#ifdef MUSB_CONFIG_PROC_FS
-+              pThis->aLocalEnd[bEnd].dwTotalRxBytes = 0;
-+              pThis->aLocalEnd[bEnd].dwTotalRxPackets = 0;
-+              pThis->aLocalEnd[bEnd].dwErrorRxPackets = 0;
-+              pThis->aLocalEnd[bEnd].dwTotalTxBytes = 0;
-+              pThis->aLocalEnd[bEnd].dwTotalTxPackets = 0;
-+              pThis->aLocalEnd[bEnd].dwErrorTxPackets = 0;
-+#endif
-+#ifndef MUSB_USE_HCD_DRIVER
-+      INIT_LIST_HEAD( &(pThis->aLocalEnd[bEnd].urb_list) );
-+#endif                
-+              pThis->aLocalEnd[bEnd].bIsClaimed=FALSE;
-+      spin_unlock( &pThis->aLocalEnd[bEnd].Lock );            
-+    }
++    spin_lock(&pHub->Lock);
++    if(pUrb && (pHub->pUrb == pUrb) && (pUrb->hcpriv == pHub)) {
++        pHub->bIsChanged = FALSE;
 +
-+      /* reset the counters */
-+      pThis->bVbusErrors=0;
++              if (pUrb->transfer_flags & USB_ASYNC_UNLINK) {
++                      pUrb->status = -ECONNRESET;
++                      if (pUrb->complete) {
++                        COMPLETE_URB(pUrb, NULL);
++                      }
++              } else {
++                      pUrb->status = -ENOENT;
++              }
 +
-+    /*  Set INT enable registers, enable interrupts */
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
-+      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xf7); /* don't enable suspend! */
++        pUrb->hcpriv = NULL;
++              pHub->pUrb = NULL;
++      }
 +
-+    DBG(1, "INTRUSBE reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE));
-+      DBG(1, "INTRTXE  reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRTXE));
-+      DBG(1, "INTRRXE  reg:0x%x \n", MGC_Read8(pBase, MGC_O_HDRC_INTRRXE));
++      spin_unlock(&pHub->Lock);
++    usb_put_urb(pUrb);
 +
-+    /* TODO: always set ISOUPDATE in POWER (periph mode) and leave it on! */
-+    MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 0);
++    DBG(2, "==>\n");
++    return 0;
++}
 +
-+    /* enable high-speed/low-power and start session */
-+   MGC_Write8(pBase, MGC_O_HDRC_POWER, 
-+              MGC_M_POWER_SOFTCONN | MGC_M_POWER_HSENAB);
 +
++/**
++ * assumes bPortIndex < MGC_VIRTUALHUB_MAX_PORTS
++ * AND pHub->Lock to be... locked :)
++ */
++STATIC void MGC_SetVirtualHubPortSpeed(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex, uint8_t bSpeed
++) {
++    uint16_t wSpeedMask = 0;
++
++    DBG(2, "<== bPortIndex=%d, bSpeed=%d\n", bPortIndex, bSpeed);
 +
-+#ifndef MUSB_GADGET
-+    /* enable high-speed/low-power and start session & suspend IM host*/
-+    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
-+#else
-+    {
-+              uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);      
-+              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
++    switch(bSpeed) {
++              case 0:
++                      wSpeedMask = USB_PORT_STAT_LOW_SPEED;
++              break;
++              case 2:
++                      wSpeedMask = USB_PORT_STAT_HIGH_SPEED;
++              break;
 +    }
-+#endif
 +
++    pHub->aPortStatusChange[bPortIndex].wStatus &=
++      ~(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
++    pHub->aPortStatusChange[bPortIndex].wStatus |= 1 | wSpeedMask;
++    pHub->bIsChanged = TRUE;
 +    DBG(2, "==>\n");
 +}
 +
 +/**
-+ * Disable the HDRC (disable & flush interrupts); 
-+ * @param pThis the controller to disable
++ * A port reset is complete
++ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
++ * @param bPortIndex 0-based index of port
++ * @see #MGC_VirtualHubInit
 + */
-+STATIC void mgc_hdrc_disable(MGC_LinuxCd* pThis)
++void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, uint8_t bPortIndex,
++      uint8_t bHubSpeed)
 +{
-+    uint16_t temp;
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++    DBG(2, "<==port %d reset complete\n", bPortIndex);
 +
-+    DBG(2, "<==\n");
-+      
-+    /* disable interrupts */
-+    MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0);
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, 0);
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, 0);
++    if(bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) {
++      MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bHubSpeed);
 +
-+    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 0);
-+    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1);
++        pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_RESET;
++        pHub->aPortStatusChange[bPortIndex].wStatus |= USB_PORT_STAT_ENABLE;
++              pHub->aPortStatusChange[bPortIndex].wChange = USB_PORT_STAT_RESET |
++                      USB_PORT_STAT_ENABLE;
++              pHub->bIsChanged = TRUE;
++    }
++    DBG(2, "==>\n");
++}
 +
-+    /*  flush pending interrupts */
-+    temp = MGC_Read8(pBase, MGC_O_HDRC_INTRUSB);
-+    temp = MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
-+    temp = MGC_Read16(pBase, MGC_O_HDRC_INTRRX);
++/**
++ * A device has effectively been connected to a virtual hub port
++ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
++ * @param bPortIndex 0-based index of port with connected device
++ * @param bSpeed device speed (0=>low, 1=>full, 2=>high)
++ * @see #MGC_VirtualHubInit
++ */
++void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, uint8_t bPortIndex,
++      uint8_t bSpeed)
++{
++    DBG(2, "<== port %d connected, core reports speed=%d\n", bPortIndex, bSpeed);
++    if (bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) {
++              struct urb* pUrb=pHub->pUrb;
 +
-+    DBG(2, "==> HDRC Interrupts disabled\n");
-+}
++              MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bSpeed);
++              pHub->aPortStatusChange[bPortIndex].wChange |= 1;
 +
++              /* shorter time... it want it NOW! */
++              DBG(2, "<== pHub=%p, pHub->pUrb=%p, pHub->pUrb->hcpriv=%p\n", pHub,
++                      pUrb, (pUrb)?pUrb->hcpriv:NULL);
++              if ( pUrb && ( (!pUrb->hcpriv) || (pUrb->hcpriv== pHub))) {
++                      pUrb->hcpriv=pHub;
++                      MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired, 1);
++              }
++    }
++    DBG(2, "==>\n");
++}
 +
-+STATIC void mgc_reset(MGC_LinuxCd* pThis)
++/**
++ * A device has effectively been disconnected from a virtual hub port
++ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
++ * @param bPortIndex 0-based index of port of disconnected device
++ * @see #MGC_VirtualHubInit
++ */
++void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, uint8_t bPortIndex)
 +{
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    uint8_t temp;
++      struct urb* pUrb;
 +
-+    DBG(2, "<==\n");
++    DBG(-1, "<== Port %d disconnected\n", bPortIndex);
 +
-+      temp = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      MGC_Write8(pBase, MGC_O_HDRC_POWER, temp | MGC_M_POWER_RESET);  
-+    DBG(1, "%s power reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_POWER));
++      if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) {
++                      DBG(-1, "==>");
++                      return;
++      }
++
++#ifndef MUSB_USE_HCD_DRIVER
++      del_timer_sync(&pHub->Timer);
++#endif
++
++      pUrb= pHub->pUrb;
++      pHub->aPortStatusChange[bPortIndex].wStatus &= ~1;
++      pHub->aPortStatusChange[bPortIndex].wChange |= 1;
++      pHub->bIsChanged = TRUE;
++
++      if (pUrb && (pUrb->hcpriv == pHub)) {
++              pUrb->status=0;
++              MGC_VirtualHubCompleteIrq(pHub, pUrb);
++      }
 +
++    DBG(-1, "==>\n");
 +}
 +
 +/**
-+ * Enable the HDRC 
-+ * @param pThis the controller to disable
++ * A device has effectively resumed a virtual hub port
++ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
++ * @param bPortIndex 0-based index of port of resume
++ * @see #MGC_VirtualHubInit
 + */
-+void mgc_hdrc_enable(MGC_LinuxCd* pThis)
++void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, uint8_t bPortIndex)
 +{
-+    uint8_t* pBase = (uint8_t*)pThis->pRegs;
++      DBG(2, "<== Resume port %d\n", bPortIndex);
++#ifdef MUSB_USE_HCD_DRIVER
++      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
++#endif
 +
-+    DBG(2, "<==\n");
++      if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) {
++              return;
++      }
 +
-+      /*  Set INT enable registers, enable interrupts */
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, pThis->wEndMask);
-+    MGC_Write16(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
-+      /* don't enable suspend mode! */
-+      MGC_Write8(pBase, MGC_O_HDRC_INTRUSBE, 0xf7);   
++      pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_SUSPEND;
++      pHub->aPortStatusChange[bPortIndex].wChange |= USB_PORT_STAT_SUSPEND;
++      pHub->bIsChanged = TRUE;
++    DBG(2, "==>\n");
++}
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musb_virthub.h
+@@ -0,0 +1,240 @@
++/*
++ * linux/drivers/usb/nomadik/musb_virthub.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ */
 +
-+    DBG(1, "%s INTRUSBE reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE));
-+      DBG(1, "%s INTRTXE  reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRTXE));
-+      DBG(1, "%s INTRRXE  reg:0x%x \n", __FUNCTION__,MGC_Read8(pBase, MGC_O_HDRC_INTRRXE));
++#ifndef __MUSB_LINUX_VIRTUALHUB_H__
++#define __MUSB_LINUX_VIRTUALHUB_H__
 +
-+      /* no test mode */
-+    MGC_Write8(pBase, MGC_O_HDRC_TESTMODE, 0);
++#include <linux/spinlock.h>
++#include <linux/timer.h>
++#include <linux/version.h>
 +
-+#ifndef MUSB_GADGET
-+    /* enable high-speed/low-power and start session & suspend IM host*/
-+    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
++#define USB_NEW_DEVICE(_vh) usb_register_root_hub((_vh)->pDevice, (_vh)->pBus->controller)
 +#else
-+    {
-+              uint8_t state=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);      
-+              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, state & ~MGC_M_DEVCTL_SESSION);
-+    }
++#ifdef __bluecat__
++#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice, (((_vh)->pDevice)->parent)?&((_vh)->pDevice)->parent->dev:NULL )
++#else
++#define USB_NEW_DEVICE(_vh)  usb_new_device((_vh)->pDevice)
++#endif
 +#endif
 +
-+}
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
++#define MUSB_REGISTER_ROOT_HUB
++#endif
++
++struct urb;
++struct usb_bus;
++
++#ifdef MUSB_USE_HCD_DRIVER
++struct usb_hcd;
++#endif
 +
 +/**
-+* Program the HDRC to stop (disable interrupts, etc.).
-+*/
-+void MGC_HdrcStop(MGC_LinuxCd* pThis)
-+{
-+    DBG(2, "<==\n");
++ * Introduction.
++ * For USB controllers lacking embedded root hubs,
++ * this module can be used as a virtual root hub,
++ * with one or more controllers as the virtual hub's ports.
++ */
 +
-+    /* flush endpoints */
-+#ifdef MUSB_VIRTHUB
-+      { 
-+              uint8_t bEnd;
-+              
-+              mgc_hdrc_disable(pThis);                
-+              for(bEnd = 0; bEnd < min(16, (int)pThis->bEndCount); bEnd++) {
-+                      MGC_HdrcStopEnd(pThis, bEnd);
-+              }
-+      }
-+#endif    
-+}
++/****************************** CONSTANTS ********************************/
 +
-+/* ------------------------------------------------------------------------ */
++/** Maximum number of ports to accomodate */
++#define MGC_VIRTUALHUB_MAX_PORTS      7
 +
-+#define MUSB_HDRC_ULPI_ACCESS
-+#ifdef MUSB_HDRC_ULPI_ACCESS
++/******************************** TYPES **********************************/
 +
-+uint8_t MGC_HdrcUlpiVbusControl(MGC_LinuxCd* pThis, uint8_t bExtSource, uint8_t bExtIndicator)
-+{
-+    uint8_t bVal;
-+    uint8_t* pBase = pThis->pRegs;
-+      
-+    /* ensure not powered down */
-+    if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
-+              return FALSE;
-+    }
++/**
++ * Set a port's power on or off.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bPower TRUE to power on the port; FALSE to power off
++ */
++typedef void (*MGC_pfSetPortPower)(void* pPrivateData, uint8_t bPortIndex,
++                                 uint8_t bPower);
 +
-+    bVal = bExtSource ? MGC_M_ULPI_VBUSCTL_USEEXTVBUS : 0;
-+    bVal |= bExtIndicator ? MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND : 0;
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_VBUSCTL, bVal);
-+      
-+    return TRUE;
-+}
++/**
++ * Enable or disable a port.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bEnable TRUE to enable port; FALSE to disable
++ */
++typedef void (*MGC_pfSetPortEnable)(void* pPrivateData, uint8_t bPortIndex,
++                                  uint8_t bEnable);
 +
-+uint8_t MGC_HdrcReadUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t* pbData)
-+{
-+    uint8_t bCtl = 0;
-+      uint8_t* pBase = pThis->pRegs;
++/**
++ * Set a port's suspend mode on or off.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bSuspend TRUE to suspend port; FALSE to resume
++ */
++typedef void (*MGC_pfSetPortSuspend)(void* pPrivateData, uint8_t bPortIndex,
++                                   uint8_t bSuspend);
 +
-+    /* ensure not powered down */
-+    if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
-+              return FALSE;
-+    }
++/**
++ * Set a port's reset on or off.
++ * @param pPrivateData pPrivateData from port services
++ * @param bPortIndex 0-based index of port
++ * @param bReset TRUE to assert reset on the bus behind a port; FALSE to deassert
++ */
++typedef void (*MGC_pfSetPortReset)(void* pPrivateData, uint8_t bPortIndex,
++                                 uint8_t bReset);
 +
-+    /* polled */
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr);
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 
-+      MGC_M_ULPI_REGCTL_READNOTWRITE | MGC_M_ULPI_REGCTL_REG);
-+   
++/**
++ * MGC_PortServices.
++ * Services provided to a virtual by a USB port controller.
++ * @field pPrivateData port controller's implementation data;
++ * not to be interpreted by virtual hub
++ * @param pfSetPortPower set-port-power call
++ * @param pfSetPortEnable set-port-enable call
++ * @param pfSetPortSuspend set-port-suspend call
++ * @param pfSetPortReset set-port-reset call
++ */
++typedef struct
++{
++    void* pPrivateData;
++    MGC_pfSetPortPower pfSetPortPower;
++    MGC_pfSetPortEnable pfSetPortEnable;
++    MGC_pfSetPortSuspend pfSetPortSuspend;
++    MGC_pfSetPortReset pfSetPortReset;
++} MGC_PortServices;
 +
-+ while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) {
-+      bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL);
-+   }
-+      
-+    *pbData = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGDATA);
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
-+    return TRUE;
-+}
++/**
++ * MGC_HubPortStatusChange.
++ * @field wStatus status
++ * @field wChange change
++ */
++typedef struct
++{
++    uint16_t wStatus;
++    uint16_t wChange;
++} MGC_HubPortStatusChange;
 +
-+uint8_t MGC_HdrcWriteUlpiReg(MGC_LinuxCd* pThis, uint8_t bAddr, uint8_t bData)
++/**
++ * MGC_VirtualHub.
++ * Virtual USB hub instance data.
++ * @field Lock spinlock
++ * @field pBus our bus pointer
++ * @field pDevice our device pointer
++ * @field pUrb pointer to interrupt URB for status change
++ * @field pPortServices pointer to port services
++ * @field Timer interval timer for status change interrupts
++ * @field aPortStatusChange status/change array
++ * @field bPortCount how many ports
++ * @field wInterval actual interval in milliseconds
++ * @field bIsChanged TRUE if changes to report
++ * @field bAddress address assigned by usbcore
++ */
++typedef struct
 +{
-+    uint8_t bCtl = 0;
-+      uint8_t* pBase = pThis->pRegs;
++    spinlock_t Lock;
++    struct usb_bus* pBus;
++    struct usb_device* pDevice;
 +
-+    /* ensure not powered down */
-+    if(MGC_Read8(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
-+              return FALSE;
-+    }
++      void *pUrb;
++    MGC_PortServices* pPortServices;
++    struct timer_list Timer;
++    MGC_HubPortStatusChange aPortStatusChange[MGC_VIRTUALHUB_MAX_PORTS];
++    uint8_t bPortCount;
++    uint16_t wInterval;
++    uint8_t bIsChanged;
++    uint8_t bAddress;
 +
-+    /* polled */
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGADDR, bAddr);
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGDATA, bData);
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, MGC_M_ULPI_REGCTL_REG);
++} MGC_VirtualHub;
 +
-+    while(!(MGC_M_ULPI_REGCTL_COMPLETE & bCtl)) {
-+              bCtl = MGC_Read8(pBase, MGC_O_HDRC_ULPI_REGCTL);
-+    }
++/******************************** Protos **********************************/
 +
-+    MGC_Write8(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
++extern int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData);
 +
-+    return TRUE;
-+}
-+#endif
++#ifdef MUSB_VIRTHUB
++void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
++    uint8_t bPower);
++void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
++    uint8_t bEnable);
++void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
++      uint8_t bSuspend);
++void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
++      uint8_t bReset);
++
++extern int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus,
++      uint8_t bPortCount, MGC_PortServices* pPortServices);
++extern void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub);
++extern void MGC_VirtualHubStart(MGC_VirtualHub* pHub);
++extern void MGC_VirtualHubStop(MGC_VirtualHub* pHub);
++extern int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
++extern int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
++extern void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex, uint8_t bHubSpeed);
++extern void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex, uint8_t bSpeed);
++extern void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex);
++extern void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex);
 +
-+/* ------------------------------------------------------------------------ */
++#else /* #ifdef MUSB_VIRTHUB */
 +
-+/**
-+* Discover HDRC configuration.
-+* @param wType
-+* @param pThis the controller instance
-+*/
-+STATIC uint8_t MGC_HdrcInit(uint16_t wType, MGC_LinuxCd* pThis)
++static int uint8_t MGC_VirtualHubInit(MGC_VirtualHub* pHub,
++      struct usb_bus* pBus, uint8_t bPortCount,
++      MGC_PortServices* pPortServices)
 +{
-+#ifdef MUSB_AHB_ID
-+    uint32_t dwData;
-+#endif
-+    uint8_t reg, bType=0;
-+    uint16_t wRelease, wRelMajor, wRelMinor;
-+    char aInfo[78], aRevision[32], aDate[12];
-+    void* pBase = pThis->pRegs;
-+
-+    DBG(2, "<==\n");
++      DBG(-1, "this should not be called");
++      return -ENODEV;
++};
++static inline void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub) {
++      DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubStart(MGC_VirtualHub* pHub) {
++      DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubStop(MGC_VirtualHub* pHub) {
++      DBG(-1, "this should not be called");
++};
++static inline int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb) {
++      DBG(-1, "this should not be called");
++      return -ENODEV;
++};
 +
-+    /* log core options */
-+    MGC_SelectEnd(pBase, 0);
-+    reg = MGC_ReadCsr8(pBase, MGC_O_HDRC_CONFIGDATA, 0);
++static inline int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb) {
++      DBG(-1, "this should not be called");
++      return -ENODEV;
++};
 +
-+    strcpy(aInfo,(reg & MGC_M_CONFIGDATA_UTMIDW)?"UTMI-16":"UTMI-8");
-+    if(reg & MGC_M_CONFIGDATA_DYNFIFO) {
-+        strcat(aInfo, ", dyn FIFOs");
-+    }
-+    if(reg & MGC_M_CONFIGDATA_MPRXE) {
-+        strcat(aInfo, ", bulk combine");
-+    }
-+    if(reg & MGC_M_CONFIGDATA_MPTXE) {
-+        strcat(aInfo, ", bulk split");
-+    }
-+    if(reg & MGC_M_CONFIGDATA_HBRXE) {
-+        strcat(aInfo, ", HB-ISO Rx");
-+    }
-+    if(reg & MGC_M_CONFIGDATA_HBTXE) {
-+        strcat(aInfo, ", HB-ISO Tx");
-+    }
-+    if(reg & MGC_M_CONFIGDATA_SOFTCONE) {
-+        strcat(aInfo, ", SoftConn");
-+    }
-+    
-+    INFO("ConfigData=0x%02x (%s)\n", reg, aInfo);
++static inline void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex, uint8_t bHubSpeed) {
++      DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex, uint8_t bSpeed) {
++      DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub,
++      uint8_t bPortIndex) {
++      DBG(-1, "this should not be called");
++};
++static inline void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub,
++uint8_t bPortIndex) {
++      DBG(-1, "this should not be called");
++};
 +
-+#ifdef MUSB_AHB_ID
-+    dwData = MGC_Read32(pBase, 0x404);
-+    sprintf(aDate, "%04d-%02x-%02x", (dwData & 0xffff), 
-+      (dwData >> 16) & 0xff,
-+      (dwData >> 24) & 0xff);
-+    dwData = MGC_Read32(pBase, 0x408);
-+    printk("ID2=%lx\n", (long unsigned)dwData);
-+    dwData = MGC_Read32(pBase, 0x40c);
-+    printk("ID3=%lx\n", (long unsigned)dwData);
-+    bType = MGC_Read8(pBase, 0x400);
-+    pThis->bIsMultipoint=('M' == bType)
-+      ? TRUE : FALSE;
-+#else
-+    bType = 'x';
-+    pThis->bIsMultipoint=(MUSB_CONTROLLER_MHDRC == wType)
-+      ? TRUE : FALSE;
 +#endif
-+      
-+      /* log release info */
-+    wRelease = MGC_Read16(pBase, 0x6c);
-+    wRelMajor = (wRelease >> 10) & 0x1f;
-+    wRelMinor = wRelease & 0x3ff;
-+    snprintf(aRevision, 32, "%d.%d%s", wRelMajor, 
-+          wRelMinor, (wRelease & 0x8000) ? "RC" : "");
-+    INFO("%cDRC version %s %s\n", bType, aRevision, aDate);
 +
 +
-+      /* configure ep0 */
-+    pThis->aLocalEnd[0].wMaxPacketSizeTx = MGC_END0_FIFOSIZE;
-+    pThis->aLocalEnd[0].wMaxPacketSizeRx = MGC_END0_FIFOSIZE;
++#endif        /* multiple inclusion protection */
 +
-+      /* discover endpoint configuration */
-+    pThis->bBulkTxEnd = 0;
-+    pThis->bBulkRxEnd = 0;
-+    pThis->bEndCount = 1;
-+    pThis->wEndMask = 1;      
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musbdefs.h
+@@ -0,0 +1,828 @@
++/*
++ * linux/drivers/usb/nomadik/musbdefs.h
++ *
++ * Copyright 2007, STMicroelectronics
++ *
++ * 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
++ */
 +
-+#ifdef MUSB_C_DYNFIFO_DEF
-+    if(!(reg & MGC_M_CONFIGDATA_DYNFIFO)) {
-+        ERR("Dynamic FIFOs not detected in hardware; please rebuild software\n");
-+              return FALSE;
-+    }
-+#else 
-+    if (reg & MGC_M_CONFIGDATA_DYNFIFO) {
-+        ERR("Dynamic FIFOs detected in hardware; please rebuild\n");
-+              return FALSE;
-+    }
-+#endif
++#ifndef __MUSB_MUSBDEFS_H__
++#define __MUSB_MUSBDEFS_H__
 +
-+      MGC_HdrcConfigureEps(pThis);
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
 +
-+#ifdef MUSB_HOST
-+      MGC_InitLocalEndPoints(pThis);
++#ifdef MUSB_CONFIG_PROC_FS
++#include <linux/fs.h>
 +#endif
 +
-+      /* claim the bulk tx/rx ends */
-+    if(pThis->bBulkTxEnd) {
-+              pThis->aLocalEnd[pThis->bBulkTxEnd].bIsClaimed = TRUE;
-+    }
++/* useful for compiling across linux version & debug definitions */
++#include "musb_cross.h"
++#include "debug.h"
 +
-+    if(pThis->bBulkRxEnd) {
-+              pThis->aLocalEnd[pThis->bBulkRxEnd].bIsClaimed = TRUE;
-+    }
++/* Board-specific definitions (hard-wired controller locations/IRQs) */
++#include "plat_cnf.h"
++#include "plat_arc.h"
++#include "musbhdrc.h"
 +
-+    return TRUE;
-+}
++/****************************** VERIFY THE DEFINES **************************
++ * determine how to compile the driver; MUSB_GADGET->as gadget driver,
++ * MUSB_HOST as host mode, MUSB_OTG -> otg mode (host and gadget)
++ *
++ * OTG => GADGET
++ */
 +
-+/**************************************************************************
-+ * Linux HCD functions
-+**************************************************************************/
++#ifdef MUSB_GSTORAGE
 +
-+#ifdef MUSB_V26
-+#define IS_TIMER_INITILIZED(_t) ((_t)->magic==TIMER_MAGIC) 
-+#else
-+#define IS_TIMER_INITILIZED(_t) (1) 
++/* for now */
++#ifndef MUSB_OTG
++#define MUSB_OTG
 +#endif
 +
-+/**
-+ * Generic timer creation.
-+ * @param pThis instance pointer
-+ * @param pfFunc timer fire callback
-+ * @param pParam parameter for callback
-+ * @param millisecs how many milliseconds to set
-+ */
-+void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long), 
-+      unsigned long pParam, unsigned long millisecs)
-+{
-+    DBG(2, "<==\n");
-+
-+    init_timer(&(pThis->Timer));
-+    pThis->Timer.function = pfFunc;
-+    pThis->Timer.data = (unsigned long)pParam;
-+    pThis->Timer.expires = jiffies + (HZ * millisecs) / 1000;
-+    add_timer( &(pThis->Timer) );
-+}
-+
-+#ifdef MUSB_V26
-+void* MGC_LinuxBufferAlloc(struct usb_bus* pBus, size_t nSize,
-+      unsigned iMemFlags, dma_addr_t* pDmaAddress)
-+{
-+    /* for now, just kmalloc it */
-+    MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv);
++#endif
 +
-+#ifdef MUSB_PARANOID
-+    if ( !pThis ) {
-+      ERR("cannot find the controller, cannot allocate the memory\n");
-+      return 0;
-+    }
++#ifdef MUSB_OTG
++#endif
++#ifndef MUSB_HOST
++#define MUSB_HOST
 +#endif
 +
-+    DBG(2, "<== allocating memory on bus (%s), %d, pDmaAddress=%p\n", 
-+      pBus->bus_name, pBus->busnum, pDmaAddress );
-+    return MGC_AllocBufferMemory(pThis, nSize, iMemFlags, pDmaAddress);
-+}
++#ifdef CONFIG_PROC_FS
++#ifndef MUSB_CONFIG_PROC_FS
++#define MUSB_CONFIG_PROC_FS
++#endif
++#endif
 +
-+void MGC_LinuxBufferFree(struct usb_bus* pBus, size_t nSize,
-+                              void* address, dma_addr_t dma)
-+{
-+    MGC_LinuxCd* pThis=hcd_to_musbstruct(pBus->hcpriv);
++#ifdef MUSB_PROC_TESTMUSB
 +
-+#ifdef MUSB_PARANOID
-+    if ( !pThis ) {
-+              KFREE(address);
-+      ERR("cannot find the controller, cannot free the memory properly\n");
-+              return;
-+    }
++#ifndef CONFIG_PROC_FS
++#error "TestMusb needs CONFIG_PROC_FS"
 +#endif
 +
-+    MGC_FreeBufferMemory(pThis, nSize, address, dma);
-+}
++#ifndef MUSB_HOST
++#error "TestMusb needs HOST MODE"
 +#endif
 +
++#endif
 +
-+#if defined(MUSB_V26) || defined(MUSB_GADGET) 
-+/**
-+ * Allocate memory for a buffer that might use DMA.
-+ *
-+ * @param pThis
-+ * @param bytes
-+ * @param gfp_flags
-+ * @param dma NULL when DMAble memeory is not requested.
-+ */
-+void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma) {
-+    void* addr = NULL;
-+      
-+    if ( dma ) {
-+        *dma = DMA_ADDR_INVALID;
-+    }
-+    
-+#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21)
-+   {
-+      KMALLOC(addr, bytes, gfp_flags);
-+              if ( addr && dma ) {
-+                      *dma = virt_to_phys(addr);
-+      }
-+              DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma); 
-+     }
-+#else
-+    { 
-+      KMALLOC(addr, bytes, gfp_flags);
-+              if ( addr && dma ) {
-+                      *dma = virt_to_phys(addr);
-+      }
-+      
-+              DBG(2, "mallocd addr=%p, pDmaAddress=%p\n", addr, dma); 
-+     }
++#ifdef MUSB_HOST
++#define MUSB_VIRTHUB
 +#endif
 +
-+    if ( addr ) {
-+              memset(addr, 0, bytes);    
-+    }
-+      
-+    return addr;
-+}
++/************************* DEFINES DEPENDENT INCLUDES ************************/
 +
-+/**
-+ * Free memory previously allocated with AllocBufferMemory.
-+ * @param pThis
-+ * @param bytes
-+ * @param dma
-+ */
-+void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma) {
++/* virtual hub */
++#include "musb_virthub.h"
 +
-+    DBG(2, "<== freeing bytes=%d, address=%p, dma=%p\n", bytes, address, (void*)dma);
++/****************************** USB CONSTANTS ********************************/
 +
-+#if !defined(USE_KMALLOC) && !defined(MUSB_LINUX_MV21)
-+      DBG(2, "==>\n");
-+#else
-+    {
-+      KFREE(address);
-+    }
++#ifndef USB_DT_DEVICE_QUALIFIER
++#define USB_DT_DEVICE_QUALIFIER 6
 +#endif
-+    DBG(2, "==>\n");
-+}
++
++#ifndef USB_DT_DEVICE_QUALIFIER_SIZE
++#define USB_DT_DEVICE_QUALIFIER_SIZE 10
 +#endif
 +
-+/* ------------------------------------------------------------------------ */
++#ifndef USB_DT_OTHER_SPEED
++#define USB_DT_OTHER_SPEED 7
++#endif
 +
-+#ifndef MUSB_V26_POST10
-+/**
-+ * Private per-device allocation
-+ * @param pDevice Linux USBD device pointer
-+ * @return status code
-+ */
-+STATIC int mgc_linux_alloc_device(struct usb_device *pDevice)
-+{
-+    
-+    DBG(2, "<==>\n");
-+    return 0;
-+    
-+}
++#ifndef USB_MAXCHILDREN
++#define USB_MAXCHILDREN         (16)
++#endif
 +
-+/**
-+ * Private per-device cleanup
-+ * @param pDevice Linux USBD device pointer
-+ * @return 0 (success)
-+ */
-+STATIC int mgc_linux_free_device(struct usb_device * pDevice)
-+{
-+    DBG(2, "<==>\n");
-+    return 0;
-+}
++/****************************** DEBUG CONSTANTS ********************************/
 +
-+int MGC_LinuxHubSuspend(struct usb_bus *pBus) {
-+      return 0;
-+}
++#define MGC_PAD_FRONT   0xa5deadfe
++#define MGC_PAD_BACK    0xabadcafe
++#define MGC_TEST_PACKET_SIZE 53
 +
-+int MGC_LinuxHubResume(struct usb_bus *pBus) {
-+      return 0;
-+}
++/****************************** CONSTANTS ********************************/
 +
++#if MUSB_DEBUG > 0
++#define STATIC
++#define MUSB_PARANOID
++#else
++#define STATIC static
 +#endif
 +
-+/* ------------------------------------------------------------------------ */
++#ifndef TRUE
++#define TRUE 1
++#endif
++#ifndef FALSE
++#define FALSE 0
++#endif
 +
-+/**
-+ * Get the current frame number. 
-+ * @param struct usb_hcd pointer to usb_hcd structure
-+ * @return frame number
-+ */
-+static inline int mgc_get_frame_number(MGC_LinuxCd* pThis) {
-+      uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+    const int no=(int)MGC_Read16(pBase, MGC_O_HDRC_FRAME);
++#ifndef MUSB_C_NUM_EPS
++#define MUSB_C_NUM_EPS ((uint8_t)16)
++#endif
 +
-+    DBG(2, "<==> %d\n", no);
-+      return no;      
-+}
++#ifndef MUSB_MAX_END0_PACKET
++#define MUSB_MAX_END0_PACKET ((uint16_t)MGC_END0_FIFOSIZE)
++#endif
 +
-+/*
-+ */
-+int MGC_LinuxGetFrameNumber(struct usb_device* pDevice)
-+{
-+      MGC_LinuxCd* pThis=hcd_to_musbstruct(pDevice->bus->hcpriv);
-+      return mgc_get_frame_number( pThis );
-+}
++#define MGC_END0_START  0x0
++#define MGC_END0_OUT    0x2
++#define MGC_END0_IN     0x4
++#define MGC_END0_STATUS 0x8
 +
++#define MGC_END0_STAGE_SETUP          0x0
++#define MGC_END0_STAGE_TX             0x2
++#define MGC_END0_STAGE_RX             0x4
++#define MGC_END0_STAGE_STATUSIN               0x8
++#define MGC_END0_STAGE_STATUSOUT        0xf
++#define MGC_END0_STAGE_STALL_BIT      0x10
 +
-+/**************************************************************************
-+ * Linux driver hooks
-+**************************************************************************/
++/* obsolete */
++#define MGC_END0_STAGE_DATAIN         MGC_END0_STAGE_TX
++#define MGC_END0_STAGE_DATAOUT                MGC_END0_STAGE_RX
 +
-+/**
-+ * Generic Interrupt Service Routine.
-+ * @param pThis the controller
-+ */
-+static irqreturn_t mgc_linux_isr(MGC_LinuxCd* pThis)
-+{
-+    uint32_t nSource;
-+#if MUSB_DEBUG > 0
-+    uint16_t wIntrTxCheck, wIntrRxCheck;
++/* EASY GUESS */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
++#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus, _port)
++#else
++/* 2.4, mvl21, bc5 */
++#define USB_ALLOC_DEV( _parent, _usb_bus, _port) usb_alloc_dev(_parent, _usb_bus)
 +#endif
-+    const void* pBase = pThis->pRegs; 
-+    uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+      
-+    uint8_t power = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+      
-+    uint8_t bIntrUsbValue=MGC_Read8(pBase, MGC_O_HDRC_INTRUSB);
-+    uint16_t wIntrTxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRTX);
-+      uint16_t wIntrRxValue=MGC_Read16(pBase, MGC_O_HDRC_INTRRX);
-+
-+              nSource = bIntrUsbValue | wIntrTxValue | wIntrRxValue;
-+      DEBUG_CODE(10,  if (!nSource) { \
-+                      INFO("IRQ [mode=%s] nSource=%d\n", MUSB_MODE(pThis), nSource); } );
 +
 +
-+    if (!nSource) {
-+              RETURN_IRQ_NONE;
-+      }
-+      
-+      DBG(2, "<== [%ld]: IRQ RECEIVED [devmode=%s, hwmode=%s] IntrUSB=%02x, IntrUSBE=%02x, IntrTx=%04x, IntrRx=%04x\n", 
-+              jiffies, MUSB_MODE(pThis), (devctl & MGC_M_DEVCTL_HM)?"host":"function",
-+              bIntrUsbValue, MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE), 
-+              wIntrTxValue, wIntrRxValue);
-+
-+      
-+      /* Recent IPs return the right values (not the masked one) */
-+      bIntrUsbValue &= MGC_Read8(pBase, MGC_O_HDRC_INTRUSBE);
-+
-+              
-+    /* corruption check */
-+#ifdef MUSB_PARANOID
-+    if ( MGC_ISCORRUPT(pThis) ) {
-+              INFO("stopping before ISR, the controller structure is corrupted\n");
-+              MGC_HdrcStop(pThis);
-+              MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED); 
++/* 2.4/2.6 compatibility */
++#ifdef MUSB_V26
 +
-+      RETURN_IRQ_HANDLED;
-+    }
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
++#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) ((_dev)->bus->op->disable(_dev, _pipe_ep))
++#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
++#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) ( 0 )
++#else
++#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
++#define USB_RUN_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_running(_dev, _pipe_ep, _pipe_out)
++#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
 +#endif
 +
-+#ifdef MUSB_DMA
-+      /* ### DMA intr handler added */
-+      if ( pThis->pDmaController->pfDmaControllerIsr(pThis->pDmaController->pPrivateData) ) {
-+              DBG(1, "%s: ******** DMA interrupt *************\n",__FUNCTION__); 
-+              nSource |= 1;
-+      }
-+#endif
++/*#define COMPLETE_URB(_pUrb, _p)        _pUrb->complete(_pUrb, _p)*/
++#define COMPLETE_URB(_pUrb, _p)        (_pUrb->complete=_p)
++#define WAIT_MS(_ms)                  mdelay(_ms)
 +
++#define USB_ISO_ASAP            0x0002
++#define USB_ASYNC_UNLINK        0x0008
 +
-+   /* the core can interrupt us for multiple reasons, I.E. more than an
-+    * interrupt line can be asserted; service the globa interrupt first.
-+    * Global interrups are used to signal connect/disconnect/vbuserr
-+      * etc. processed in two phase */
-+    if ( bIntrUsbValue ) {
-+              DBG(3, "** IRQ [mode=%s] nSource=%d | DEVCTL :0x%x | IntrUsb:0x%x \n", \
-+              MUSB_MODE(pThis), nSource, MGC_Read8(pBase, MGC_O_HDRC_DEVCTL), bIntrUsbValue); 
-+      mgc_hdrc_service_usb_stage0(pThis, bIntrUsbValue, devctl, power);
-+    }
++#define USB_ST_NOERROR          (0)
++#define USB_ST_CRC              (-EILSEQ)
++#define USB_ST_BITSTUFF         (-EPROTO)
++#define USB_ST_NORESPONSE       (-ETIMEDOUT)    /* device not responding/handshaking */
++#define USB_ST_DATAOVERRUN      (-EOVERFLOW)
++#define USB_ST_DATAUNDERRUN     (-EREMOTEIO)
++#define USB_ST_BUFFEROVERRUN    (-ECOMM)
++#define USB_ST_BUFFERUNDERRUN   (-ENOSR)
++#define USB_ST_INTERNALERROR    (-EPROTO)       /* unknown error */
++#define USB_ST_SHORT_PACKET     (-EREMOTEIO)
++#define USB_ST_PARTIAL_ERROR    (-EXDEV)        /* ISO transfer only partially completed */
++#define USB_ST_URB_KILLED       (-ENOENT)       /* URB canceled by user */
++#define USB_ST_URB_PENDING      (-EINPROGRESS)
++#define USB_ST_REMOVED          (-ENODEV)       /* device not existing or removed */
++#define USB_ST_TIMEOUT          (-ETIMEDOUT)    /* communication timed out, also in urb->status**/
++#define USB_ST_NOTSUPPORTED     (-ENOSYS)
++#define USB_ST_BANDWIDTH_ERROR  (-ENOSPC)       /* too much bandwidth used */
++#define USB_ST_URB_INVALID_ERROR  (-EINVAL)     /* invalid value/transfer type */
++#define USB_ST_URB_REQUEST_ERROR  (-ENXIO)      /* invalid endpoint */
++#define USB_ST_STALL            (-EPIPE)        /* pipe stalled, also in urb->status*/
 +
-+#ifdef MUSB_PARANOID
-+      if ( wIntrTxValue || wIntrRxValue ) { /* got data! */
-+              if ( ((devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_HST(pThis))) 
-+                      || (!(devctl & MGC_M_DEVCTL_HM) && (!MUSB_IS_DEV(pThis))) )
-+              {
-+                      if ( bIntrUsbValue ) {                  
-+                              mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
-+                      } else {
-+                              WARN("early interrupt while in hm=%d: otg machine hasn't done yet\n", 
-+                                      devctl & MGC_M_DEVCTL_HM);      
-+                      }
++#define USB_ZERO_PACKET         0x0040        /* Finish bulk OUTs always with zero length packet */
 +
-+                      RETURN_IRQ_HANDLED;
-+              }
-+      }
 +#endif
 +
-+    /* ignore requests when in error */
-+    if( MUSB_IS_ERR(pThis) ) {                
-+              if ( bIntrUsbValue) {
-+                      mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
-+              } else {
-+                      ERR("Error mode, please ZAP the driver!\n");
-+                      mgc_hdrc_disable(pThis);
-+              }
-+
-+              RETURN_IRQ_HANDLED;    
-+    } 
-+
-+      /* handle tx/rx on endpoints; each bit of wIntrTxValue is an endpoint, 
-+       * endpoint 0 first (p35 of the manual) bc is "SPECIAL" treatment; 
-+       * WARNING: when operating as device you might start receving traffic 
-+       * to ep0 before anything else happens so be ready for it */    
-+      do {            
-+              uint8_t bShift=0;
-+              uint32_t reg=wIntrTxValue;
++#ifdef MUSB_V24
++#define usb_disabled()                        0
++#define COMPLETE_URB(_pUrb, _p)               _pUrb->complete(_pUrb)
++#define WAIT_MS(_ms)                  wait_ms(_ms)
++#define USB_HALT_ENDPOINT(_dev, _pipe_ep, _pipe_out) usb_endpoint_halt(_dev, _pipe_ep, _pipe_out)
++#define USB_ENDPOINT_HALTED(_dev, _pipe_ep, _pipe_out) usb_endpoint_halted(_dev, _pipe_ep, _pipe_out)
 +
-+              if(reg & 1 ) {  /* EP0 */
-+                      if (devctl & MGC_M_DEVCTL_HM) {
-+#ifdef MUSB_CONFIG_PROC_FS
-+                              if(pThis->pfDefaultEndHandler) {
-+                                      pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam);
-+                              } else
-+#endif
-+                              MGC_HdrcServiceDefaultEnd(pThis);
-+                      } else {
-+                              udc_ep0_irq();
-+                      }       
-+              }
-+      
-+#ifdef MUSB_PARANOID
-+              if( MGC_ISCORRUPT(pThis) ) {
-+                      INFO("after servicing Ep0 interrupt\n");
-+                      break;
-+              }
-+#endif
-+      
-+              /* TX on endpoints 1-15 */
-+              bShift = 1;
-+              reg >>= 1;
-+              while(reg) {
-+                      if(reg & 1) {
-+                              if(devctl & MGC_M_DEVCTL_HM) {
-+                                      MGC_HdrcServiceTxAvail(pThis, bShift);
-+                              } else {
-+                                      udc_ep_tx_irq(bShift) ;
-+                              }
-+                      }
-+                      reg >>= 1;
-+                      bShift++;
-+              }
-+                      
-+              DEBUG_CODE(10, wIntrTxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRTX); \
-+                      if(wIntrTxCheck && (wIntrTxCheck == wIntrTxValue)) { \
-+                              ERR("Unhandled TX interrupt, wIntrTx=%04x wIntrTxCheck=%04x; DRC stopped\n",\
-+                                      wIntrTxValue, wIntrTxCheck); \
-+                                      for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \
-+                                              MGC_HdrcDumpRegs(pThis->pRegs, \
-+                                              MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \
-+                                      } \
-+                                      MGC_HdrcStop(pThis); \
-+                                      MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \
-+                                      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \
-+                                      pThis->pRootDevice = NULL; \
-+                      } );
-+      
-+#ifdef MUSB_PARANOID
-+              if( MGC_ISCORRUPT(pThis) ) {
-+                      INFO("after servicing Tx interrupt\n");
-+                      break;
-+              }
-+#endif
-+      
-+              /* RX on endpoints 1-15 */
-+              reg = wIntrRxValue;
-+              bShift = 1;
-+              reg >>= 1;
-+              while(reg) {
-+                      if(reg & 1) {
-+                              if(devctl & MGC_M_DEVCTL_HM) {
-+                                      MGC_HdrcServiceRxReady(pThis, bShift);
-+                              } else {
-+                                      udc_ep_rx_irq(bShift) ;
-+                              }
-+                      }
-+                      
-+                      reg >>= 1;
-+                      bShift++;
-+              }
-+              
-+              DEBUG_CODE(10,  wIntrRxCheck = MGC_Read16(pBase, MGC_O_HDRC_INTRRX); \
-+              if(wIntrRxCheck && (wIntrRxCheck == wIntrRxValue)) { \
-+                      DBG(1, "Unhandled RX interrupt, IntrRx=%04x; IntrRxCheck=%04x DRC stopped\n", \
-+                                 wIntrRxValue, wIntrRxCheck); \
-+                      for(bShift = 0; bShift < pThis->bEndCount; bShift++) { \
-+                              MGC_HdrcDumpRegs(pThis->pRegs, \
-+                              MUSB_IS_HST(pThis) && pThis->bIsMultipoint, bShift); \
-+                      } \
-+                      MGC_HdrcStop(pThis); \
-+                              MUSB_ERR_MODE(pThis, MUSB_ERR_IRQ); \
-+                      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0); \
-+                      pThis->pRootDevice = NULL; \
-+                      });
-+      
-+              /* Global interrups are used to signal connect/disconnect/vbuserr
-+              * etc. processed in two phase */
-+              if (bIntrUsbValue) {
-+                      mgc_hdrc_service_usb_stage1(pThis, bIntrUsbValue, devctl, power);
-+              }
-+      
-+#ifdef MUSB_PARANOID
-+              if( MGC_ISCORRUPT(pThis) ) {
-+                      INFO("stopping after servicing Rx interrupt\n");
-+              }
++#ifdef MUSB_LINUX_MV21
++#define usb_get_urb(_pUrb) _pUrb
++#define usb_put_urb(_pUrb)
++#undef MUSB_HAS_BUSNAME
 +#endif
-+      } while (0);
 +
-+#ifdef MUSB_PARANOID
-+              if( MGC_ISCORRUPT(pThis) ) {
-+                      MGC_HdrcStop(pThis);
-+                      MUSB_ERR_MODE(pThis, MUSB_ERR_CORRUPTED);
-+              }
 +#endif
 +
-+    DBG(2, "==> IRQ HANDLED [devmode=%s]\n", MUSB_MODE(pThis)); 
-+    RETURN_IRQ_HANDLED;
-+}
++typedef enum
++{
++  MGC_STATE_DEFAULT,
++  MGC_STATE_ADDRESS,
++  MGC_STATE_CONFIGURED
++} MGC_DeviceState;
 +
++/* failure codes */
++#define MUSB_ERR_WAITING      1
++#define MUSB_ERR_VBUS         -1
++#define MUSB_ERR_BABBLE               -2
++#define MUSB_ERR_CORRUPTED    -3
++#define MUSB_ERR_IRQ          -4
++#define MUSB_ERR_SHUTDOWN     -5
++#define MUSB_ERR_RESTART      -6
 +
-+/** 
-+ * Interrupt service routine.
-+ * @param irq interrupt line associated with the controller 
-+ * @param hci data structure for the host controller
-+ * @param r holds the snapshot of the processor's context before 
-+ *             the processor entered interrupt code. (not used here) 
-+ */
-+#ifndef MUSB_USE_HCD_DRIVER
-+irqreturn_t MGC_LinuxIsr(int irq, void *__hci, struct pt_regs *r)
-+{
++/****************************** FUNCTIONS ********************************/
 +
-+    MGC_LinuxCd* pThis = (MGC_LinuxCd*)__hci;
-+      return mgc_linux_isr(pThis);
-+}
-+#endif
++#define KMALLOC(a,b,c)        { lock_kernel(); a=kmalloc(b,c); unlock_kernel(); }
++#define KFREE(p)      { lock_kernel(); kfree(p); unlock_kernel(); }
 +
-+/*****************************************************/
++/*************************** REGISTER ACCESS ********************************/
 +
-+void goto_host_mode(MGC_LinuxCd* pThis) {     
-+      /* TODO: graceful Gadget shutdown */
-+      MUSB_HST_MODE(pThis);
-+#ifdef MUSB_USE_HCD_DRIVER
-+      
++/* indexed vs. flat register model */
++#ifdef MUSB_FLAT_REG
++#define MGC_SelectEnd(_pBase, _bEnd)
++#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
++    MGC_Read8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
++#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
++    MGC_Read16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset))
++#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
++    MGC_Write8(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
++#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
++    MGC_Write16(_pBase, MGC_END_OFFSET(_bEnd, _bOffset), _bData)
 +#else
-+
++#define MGC_SelectEnd(_pBase, _bEnd) \
++    MGC_Write8(_pBase, MGC_O_HDRC_INDEX, _bEnd)
++#define MGC_ReadCsr8(_pBase, _bOffset, _bEnd) \
++    MGC_Read8(_pBase, (_bOffset + 0x10))
++#define MGC_ReadCsr16(_pBase, _bOffset, _bEnd) \
++    MGC_Read16(_pBase, (_bOffset + 0x10))
++#define MGC_WriteCsr8(_pBase, _bOffset, _bEnd, _bData) \
++    MGC_Write8(_pBase, (_bOffset + 0x10), _bData)
++#define MGC_WriteCsr16(_pBase, _bOffset, _bEnd, _bData) \
++    MGC_Write16(_pBase, (_bOffset + 0x10), _bData)
 +#endif
-+}
 +
-+void goto_device_mode(MGC_LinuxCd* pThis) {
-+      /* TODO: graceful host shutdown */
-+      MUSB_DEV_MODE(pThis);   
-+}
 +
++/************************** ULPI Registers ********************************/
 +
-+/* --------------------------------------------------------------------------
-+ * Init function
-+ * 
-+ */
++/* Added in HDRC 1.9(?) & MHDRC 1.4 */
++/* ULPI pass-through */
++#define MGC_O_HDRC_ULPI_VBUSCTL       0x70
++#define MGC_O_HDRC_ULPI_REGDATA 0x74
++#define MGC_O_HDRC_ULPI_REGADDR 0x75
++#define MGC_O_HDRC_ULPI_REGCTL        0x76
 +
-+#ifndef MUSB_USE_HCD_DRIVER   
-+/** attach to the IRQ and update the controller structure.
-+ * @param nIrq the Irq number
-+ * @param pThis the controller
-+ * @return 0 if success (pThis is also update), negative is error
-+ */
-+static int mgc_request_irq(int nIrq, MGC_LinuxCd* pThis) {
-+      int rc=-ENODEV;
++/* extended config & PHY control */
++#define MGC_O_HDRC_ENDCOUNT   0x78
++#define MGC_O_HDRC_DMARAMCFG  0x79
++#define MGC_O_HDRC_PHYWAIT    0x7A
++#define MGC_O_HDRC_PHYVPLEN   0x7B    /* units of 546.1 us */
++#define MGC_O_HDRC_HSEOF1     0x7C    /* units of 133.3 ns */
++#define MGC_O_HDRC_FSEOF1     0x7D    /* units of 533.3 ns */
++#define MGC_O_HDRC_LSEOF1     0x7E    /* units of 1.067 us */
 +
-+      pThis->nIrq = nIrq;
-+      /* the hcd driver will take care of that */ 
-+      do {
++/* Added in HDRC 1.9(?) & MHDRC 1.4 */
++/* ULPI */
++#define MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND    0x02
++#define MGC_M_ULPI_VBUSCTL_USEEXTVBUS     0x01
++#define MGC_M_ULPI_REGCTL_INT_ENABLE      0x08
++#define MGC_M_ULPI_REGCTL_READNOTWRITE            0x04
++#define MGC_M_ULPI_REGCTL_COMPLETE        0x02
++#define MGC_M_ULPI_REGCTL_REG             0x01
++/* extended config & PHY control */
++#define MGC_M_ENDCOUNT_TXENDS 0x0f
++#define MGC_S_ENDCOUNT_TXENDS 0
++#define MGC_M_ENDCOUNT_RXENDS 0xf0
++#define MGC_S_ENDCOUNT_RXENDS 4
++#define MGC_M_DMARAMCFG_RAMBITS       0x0f        /* RAMBITS-1 */
++#define MGC_S_DMARAMCFG_RAMBITS       0
++#define MGC_M_DMARAMCFG_DMACHS        0xf0
++#define MGC_S_DMARAMCFG_DMACHS        4
++#define MGC_M_PHYWAIT_WAITID  0x0f        /* units of 4.369 ms */
++#define MGC_S_PHYWAIT_WAITID  0
++#define MGC_M_PHYWAIT_WAITCON 0xf0        /* units of 533.3 ns */
++#define MGC_S_PHYWAIT_WAITCON 4
 +
-+#ifdef MUSB_HARD_IRQ
-+              if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_INTERRUPT, 
-+                      pThis->aName, pThis)) 
-+              {
-+                      rc=0;
-+                      pThis->nIrqType=SA_INTERRUPT;
-+                      break;
-+              }
-+#endif
-+              if ( 0==request_irq(nIrq, MGC_LinuxIsr, SA_SHIRQ, 
-+                      pThis->aName, pThis)) 
-+              {
-+                      rc=0;
-+                      pThis->nIrqType=SA_SHIRQ;
-+                      break;
-+              }
-+      } while (0);
-+      
-+      return rc;
-+}
++/****************************** FUNCTIONS ********************************/
 +
-+/**
-+ * release in irq previously allocated with mgc_request_irq().
-+* @param pTHis the controller the IRQ was allocated for
-+ */
-+static void mgc_free_irq(MGC_LinuxCd* pThis) {
-+      free_irq(pThis->nIrq, pThis);
-+}
-+#endif        
++#define MUSB_HST_MODE(_pthis) { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
++      (_pthis)->bIsA=1; (_pthis)->bFailCode=0; }
++#define MUSB_DEV_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
++      (_pthis)->bIsA=0; (_pthis)->bFailCode=0; }
++#define MUSB_B_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
++      (_pthis)->bIsA=0; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
++#define MUSB_A_IDLE_MODE(_pthis) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
++      (_pthis)->bIsA=1; (_pthis)->bFailCode=MUSB_ERR_WAITING; }
++#define MUSB_ERR_MODE(_pthis, _cause) { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
++      (_pthis)->bFailCode=_cause; }
 +
-+#ifdef MUSB_VIRTHUB
-+#ifndef MUSB_USE_HCD_DRIVER
-+static int mgc_init_bus(MGC_LinuxCd *pThis, void* pDevice) 
-+{
-+      int rc=0;
-+      
-+    /* allocate and register bus */
-+    pThis->pBus=usb_alloc_bus(  &MGC_LinuxOperations );
-+    if (!pThis->pBus ) {
-+              return -ENODEV;
-+    }
++#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
++#define MUSB_IS_HST(_x) ( !MUSB_IS_ERR(_x) && (_x)->bIsHost && !(_x)->bIsDevice )
++#define MUSB_IS_DEV(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && (_x)->bIsDevice )
++#define MUSB_IS_B_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && !(_x)->bIsA )
++#define MUSB_IS_A_IDLE(_x) ( !MUSB_IS_ERR(_x) && !(_x)->bIsHost && !(_x)->bIsDevice && (_x)->bIsA )
 +
-+#ifdef MUSB_V26
-+    pThis->pBus->controller =(struct device*)pDevice;
-+#endif
++#define MUSB_MODE(_x) ( MUSB_IS_HST(_x)?"HOST":( MUSB_IS_DEV(_x)?"FUNCTION":(MUSB_IS_B_IDLE(_x)?"B_IDLE":(MUSB_IS_A_IDLE(_x)?"A_IDLE":"ERROR"))) )
 +
-+#ifdef MUSB_HAS_BUSNAME
-+    pThis->pBus->bus_name = pThis->aName;
-+#endif
++#define HDRC_IS_HST(_x) (  MGC_Read8((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM )
++#define HDRC_IS_DEV(_x) (  !HDRC_IS_HST(_x) )
 +
-+      /* when using the HCD driver (USE_HCD_DRIVER) 
-+         pThis->pBus->hcpriv points to the hcd driver 
-+      */
-+    pThis->pBus->hcpriv = (void *)pThis;              
 +
-+      usb_register_bus(pThis->pBus);  
-+      INFO("Registered new bus @%p\n", pThis->pBus);    
-+    
-+      rc=mgc_init_root_hub(pThis);
-+      if ( rc!=0 ) {
-+              usb_deregister_bus(pThis->pBus);
-+      } else {                
-+              pThis->pBus->root_hub = pThis->RootHub.pDevice;
-+      }
-+      
-+      return rc;
-+}
++/******************************** DMA TYPES **********************************/
 +
-+static void mgc_free_bus(struct usb_bus *bus) {
-+#ifdef MUSB_V26
-+    usb_deregister_bus(bus);
-+#endif
-+}
++#ifdef MUSB_DMA
++#include "dma.h"
 +
++#ifndef MGC_HSDMA_CHANNELS
++#define MGC_HSDMA_CHANNELS 8
 +#endif
++
++#ifdef MUSB_HAS_DMA_URBS
++#define WANTS_DMA(_pUrb) ((_pUrb)->transfer_dma && (_pUrb->flags & URB_NO_TRANSFER_DMA_MAP))
++#define DMA_BUFFER(_pUrb) ((_pUrb)->transfer_dma)
++#else
++#define WANTS_DMA(_pUrb) (0)
++#define DMA_BUFFER(pUrb) ((void*)0x000666)
 +#endif
 +
-+/* disable an endpoint */
-+#ifdef MUSB_V26
-+void mgc_linux_disable(struct usb_device* pDevice, int bEndpointAddress)
-+{
-+    /* to do */
-+}
++extern MGC_DmaControllerFactory MGC_HdrcDmaControllerFactory;
 +#endif
 +
 +
-+/* --------------------------------------------------------------------------
-+ * HOST DMA related code
-+ * 
-+ */
++/************************** Ep Configuration ********************************/
 +
-+#ifdef MUSB_DMA
-+/**
-+ * used ONLY in host mode, I'll be moved to musb_host
-+ * @param pPrivateData
-+ * @param bLocalEnd
-+ * @param bTransmit
-+ */
-+STATIC uint8_t MGC_LinuxDmaChannelStatusChanged(
-+    void* pPrivateData, uint8_t bLocalEnd, uint8_t bTransmit)
-+{
-+    MGC_LinuxCd* pThis = (MGC_LinuxCd*)pPrivateData;
-+    MGC_LinuxLocalEnd* pEnd = &(pThis->aLocalEnd[bLocalEnd]);
-+    struct urb* pUrb = MGC_GetCurrentUrb(pEnd);
-+    const void* pBase = pThis->pRegs;
-+    uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
++/** The End point descriptor */
++struct MUSB_EpFifoDescriptor {
++    uint8_t bType;    /* 0 for autoconfig, CNTR, ISOC, BULK, INTR */
++    uint8_t bDir;     /* 0 for autoconfig, INOUT, IN, OUT */
++    uint16_t wSize;   /* 0 for autoconfig, or the size */
++    uint8_t bDbe;     /* Double buffering: 0 disabled, 1 enabled */
++};
 +
-+    if(!bLocalEnd) {
-+              /* endpoint 0 */
-+              if(devctl & MGC_M_DEVCTL_HM) {
-+#ifdef MUSB_CONFIG_PROC_FS
-+                      if(pThis->pfDefaultEndHandler) {
-+                              pThis->pfDefaultEndHandler(pThis->pDefaultEndHandlerParam);
-+                      } else
-+#endif
-+                      MGC_HdrcServiceDefaultEnd(pThis);
-+              } else {
-+                      MGC_HdrcServiceDeviceDefaultEnd(pThis);
-+              }       
-+    } else {
-+              /* endpoints 1..15 */
-+              if(bTransmit) {
-+                      if(devctl & MGC_M_DEVCTL_HM) {
-+                              MGC_HdrcServiceTxAvail(pThis, bLocalEnd);
-+                      } else {
-+                              MGC_HdrcServiceDeviceTxAvail(pThis, bLocalEnd);
-+                      }
-+              } else {
-+              /* receive */
-+              if(devctl & MGC_M_DEVCTL_HM) {      
-+                      MGC_HdrcServiceRxReady(pThis, bLocalEnd);
-+                  } else {
-+                              MGC_HdrcServiceDeviceRxReady(pThis, bLocalEnd);
-+                  }
-+              }
-+    }
-+    
-+    /* trick: if end's URB changed; previous one completed;
-+       * probably not needed now... */
-+    return (pUrb == MGC_GetCurrentUrb(pEnd)) ? FALSE : TRUE;
-+}
-+#endif
++#define MUSB_EPD_AUTOCONFIG   0
 +
-+/*-------------------------------------------------------------------------*/
++#define MUSB_EPD_T_CNTRL      1
++#define MUSB_EPD_T_ISOC               2
++#define MUSB_EPD_T_BULK               3
++#define MUSB_EPD_T_INTR               4
 +
-+#ifdef MUSB_USE_HCD_DRIVER
-+#include "musb_hcd.c"
-+#endif
++#define MUSB_EPD_D_INOUT      0
++#define MUSB_EPD_D_TX         1
++#define MUSB_EPD_D_RX         2
++
++/******************************** TYPES *************************************/
++
++struct urb;
++struct usb_device;
++struct usb_gadget;
++struct usb_hcd;
 +
 +/**
-+ * Perform generic per-controller initialization.
-+ *
-+ * @param pDevice  
-+ * @param nIrq IRQ (interpretation is system-dependent)
-+ * @param pRegs pointer to controller registers, 
-+ *  assumed already mapped into kernel space
-+ * @param pName name for bus
++ * The device request.
 + */
++typedef struct __attribute__((packed)) {
++    uint8_t bmRequestType;
++    uint8_t bRequest;
++    uint16_t wValue;
++    uint16_t wIndex;
++    uint16_t wLength;
++} MUSB_DeviceRequest;
 +
-+MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType, 
-+      int nIrq, void* pRegs, u64 len, const char* pName)
++/**
++ * MGC_LinuxLocalEnd.
++ * Local endpoint resource.
++ * @field Lock spinlock
++ * @field pUrb current URB
++ * @field urb_list list
++ * @field dwOffset current buffer offset
++ * @field dwRequestSize how many bytes were last requested to move
++ * @field wMaxPacketSizeTx local Tx FIFO size
++ * @field wMaxPacketSizeRx local Rx FIFO size
++ * @field wPacketSize programmed packet size
++ * @field bIsSharedFifo TRUE if FIFO is shared between Tx and Rx
++ * @field bAddress programmed bus address
++ * @field bEnd programmed remote endpoint address
++ * @field bTrafficType programmed traffic type
++ * @field bIsClaimed TRUE if claimed
++ * @field bIsTx TRUE if current direction is Tx
++ * @field bIsReady TRUE if ready (available for new URB)
++ */
++typedef struct
 +{
-+    uint8_t bEnd;
-+    MGC_LinuxCd* pThis;       
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      struct usb_hcd *hcd = NULL;
++#if MUSB_DEBUG > 0
++    uint32_t dwPadFront;
 +#endif
-+    MGC_LinuxLocalEnd* pEnd;
-+    uint16_t temp;
-+      DBG(2, "<==\n"); 
-+
-+    /* allocate */
-+      INFO("MUSB Driver [Base Address(PA)=0x%p] [IRQ = %d] [pDevice=%p]\n",
-+              pRegs , nIrq, pDevice);
-+
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      ///////////////////////////////////////////////////////////////////////////////
-+    /* allocate */    
-+
-+
-+      hcd = usb_create_hcd(&musb_ahb_hc_driver, (struct device*)pDevice, 
-+              ((struct device*)pDevice)->bus_id);
-+      hcd1=hcd;
-+      if ( !hcd ) {
-+              return NULL;
-+      }
-+
-+      hcd->rsrc_len = len;
-+      /* register Base address (VA)*/
-+      hcd->regs = pRegs;                      
-+      ///////////////////////////////////////////////////////////////////////////////
++    spinlock_t Lock;
++    uint8_t bEnd; /* ep number */
 +
-+      pThis=hcd_to_musbstruct(hcd);
-+      udc_address=pThis;
-+      spin_lock_init(&pThis->LocalQueue.urb_queue_lock);
-+      init_waitqueue_head(&pThis->waitqh);    
-+#else 
-+      KMALLOC(pThis, sizeof(MGC_LinuxCd), GFP_ATOMIC);    
-+    if(!pThis) {
-+        ERR("kmalloc driver instance data failed\n");
-+              return NULL;
-+    }
-+      memset (pThis, 0, sizeof(MGC_LinuxCd));
++#ifdef MUSB_USE_HCD_DRIVER
++      struct urb* pCurrentUrb;
++#else
++    struct list_head urb_list;
 +#endif
 +
++      uint8_t bBusyCompleting; /* TRUE on Tx when the current urb is completing */
 +
++    unsigned int dwOffset;            /* offset int the current request */
++    unsigned int dwRequestSize; /* request size */
++    unsigned int dwIsoPacket;
++    unsigned int dwWaitFrame;
++    uint8_t bRetries;
 +
-+      pThis->pRegs = pRegs;
-+      
-+    strcpy(pThis->aName, pName);
-+      spin_lock_init(&pThis->Lock);
-+      
-+#if MUSB_DEBUG > 0
-+    pThis->dwPadFront = MGC_PAD_FRONT;
-+    pThis->dwPadBack = MGC_PAD_BACK;
++#ifdef MUSB_DMA
++    MGC_DmaChannel* pDmaChannel;
 +#endif
 +
-+#ifdef MUSB_DMA
-+    pThis->pDmaController = MGC_HdrcDmaControllerFactory
-+              .pfNewDmaController(MGC_LinuxDmaChannelStatusChanged, pThis, (uint8_t*)pRegs);
-+    if(pThis->pDmaController) {
-+              DBG(2, "DMA initialized&enabled Address: 0x%p\n", pThis->pDmaController);
-+      pThis->pDmaController->pfDmaStartController(
-+              pThis->pDmaController->pPrivateData);
-+    }
++#ifdef MUSB_CONFIG_PROC_FS
++    unsigned long dwTotalTxBytes;
++    unsigned long dwTotalRxBytes;
++    unsigned long dwTotalTxPackets;
++    unsigned long dwTotalRxPackets;
++    unsigned long dwErrorTxPackets;
++    unsigned long dwErrorRxPackets;
++    unsigned long dwMissedTxPackets;
++    unsigned long dwMissedRxPackets;
 +#endif
 +
++    uint16_t wMaxPacketSizeTx;
++    uint16_t wMaxPacketSizeRx;
++    uint16_t wPacketSize;
++    uint8_t bDisableDma; /* not used now! */
++    uint8_t bIsSharedFifo;
 +
-+    mgc_reset(pThis);
++      /* softstate, used from find_end() to determine a good match */
++    uint8_t bRemoteAddress;
++    uint8_t bRemoteEnd;
++    uint8_t bTrafficType;
++    uint8_t bIsClaimed; /* only for isoc and int traffic */
++    uint8_t bIsTx;
++    uint8_t bIsReady;
++      uint8_t bStalled; /* the ep has been halted */
 +
-+    /* be sure interrupts are disabled before connecting ISR */
-+    mgc_hdrc_disable(pThis);
++#if MUSB_DEBUG > 0
++    uint32_t dwPadBack;
++#endif
++} MGC_LinuxLocalEnd;
 +
-+      // Reset the device, otherwise the controller 
-+      // can be in unknown state.
-+      temp = MGC_Read16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL);
++/** A listener for disconnection */
++typedef void (*MGC_pfDisconnectListener)(void*);
++/** A handler for the default endpoint interrupt */
++typedef void (*MGC_pfDefaultEndHandler)(void*);
 +
-+      MGC_Write16(pThis->pRegs, MGC_O_HDRC_TOPCONTROL, (temp |MGC_M_TOPCTRL_MODE_SRST));
++#ifdef MUSB_USE_HCD_DRIVER
++typedef struct {
++    spinlock_t urb_queue_lock;
++      int urb_queue_count;
++      int urb_exec_count;
++    void *urb_queue_head;
++    void *urb_queue_tail;
++} mgc_hcd_urb_queue;
++#endif
 +
-+    /* discover configuration */
-+    if ( !MGC_HdrcInit(wType, pThis) ) {
-+#ifdef MUSB_USE_HCD_DRIVER    
-+              /* free memory ? */     
-+#else
-+              /* free memory ? */     
++/**
++ * MGC_LinuxCd.
++ * Driver instance data.
++ * @field Lock spinlock
++ * @field Timer interval timer for various things
++ * @field pBus pointer to Linux USBD bus
++ * @field RootHub virtual root hub
++ * @field PortServices services provided to virtual root hub
++ * @field pRootDevice root device pointer, to track connection speed
++ * @field nIrq IRQ number (needed by free_irq)
++ * @field bIsMultipoint TRUE if multi-point core
++ * @field bIsHost TRUE if host
++ * @field bIsDevice TRUE if peripheral
++ * @field pRegs pointer to mapped registers
++ */
++typedef struct
++{
++#if MUSB_DEBUG > 0
++    uint32_t dwPadFront;
 +#endif
-+              return NULL;    
-+    }
-+      /*for nhk15 this a must for powering up the STULPI
-+       */  
-+      /*power up the STULPI tranceiver*/
-+      MGC_Write8(pThis->pRegs, MGC_O_HDRC_ULPI_VBUSCTL, 0x3);                
-+  
-+    /* print config */
-+    for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+        pEnd = &(pThis->aLocalEnd[bEnd]);
-+              if(pEnd->wMaxPacketSizeTx || pEnd->wMaxPacketSizeRx) {
-+                      INFO("End %02d: %sFIFO TxSize=%04x/RxSize=%04x\n",
-+                              bEnd, pEnd->bIsSharedFifo ? "Shared " : "",
-+                              pEnd->wMaxPacketSizeTx, pEnd->wMaxPacketSizeRx);
-+              } else {
-+                      INFO("End %02d: not configured\n", bEnd);
-+              }
-+    }
-+      
-+      /* procfs and testing interface */
-+    MGC_LinuxCreateProcFs(pThis->aName, pThis);
++    spinlock_t Lock;
++    struct timer_list Timer;
++    struct usb_bus *pBus;
++    char aName[32];
++    MGC_VirtualHub RootHub;
++    MGC_PortServices PortServices;
++    struct usb_device* pRootDevice;
 +
-+#ifdef MUSB_PROC_TESTMUSB
-+    MGC_LinuxCreateTestProcFs(pThis->aName, pThis);
++#ifdef MUSB_DMA
++    MGC_DmaController* pDmaController;
 +#endif
 +
-+    MUSB_B_IDLE_MODE(pThis); 
-+    DBG(1, "MUSB_B_IDLE mode \n");    
-+    temp = MGC_Read8(pThis->pRegs, MGC_O_HDRC_DEVCTL  );
++    int nIrq;
++      int nIrqType;
 +
-+    /* connect ISR */
++    int nBabbleCount;
++    void* pRegs;
 +
++    MGC_LinuxLocalEnd aLocalEnd[MUSB_C_NUM_EPS];
 +
 +#ifdef MUSB_USE_HCD_DRIVER
-+      /* by default allocate shared IRQ */
-+      pThis->nIrq=nIrq;
-+      pThis->nIrqType=MUSB_DEFAULT_IRQTYPE;
-+#else
++      mgc_hcd_urb_queue LocalQueue;
++      wait_queue_head_t waitqh;
++#endif
 +
++    uint16_t wEndMask;
++    uint8_t bEndCount;
++    uint8_t bRootSpeed;
++    uint8_t bIsMultipoint;
++    uint8_t bIsHost;
++    uint8_t bIsDevice;
++    uint8_t bIsA;
++    uint8_t bIgnoreDisconnect; /* during bus resets I got fake disconnects */
++      uint8_t bVbusErrors; /* bus errors found */
 +
-+      if ( mgc_request_irq(nIrq, pThis)!=0 ) {
-+        err("request_irq %d failed!", nIrq);
-+        return NULL;
-+      }
-+#endif
++    int bFailCode; /* one of MUSB_ERR_* failure code */
 +
++    uint8_t bBulkTxEnd;
++    uint8_t bBulkRxEnd;
++    uint8_t bBulkSplit;
++    uint8_t bBulkCombine;
 +
++    uint8_t bEnd0Stage; /* end0 stage while in host or device mode */
 +
-+if(udcinitmonitorflag_init==0){
-+nomadik_udc_init(udc_address);
-+}
++#ifdef MUSB_GADGET
++    uint8_t bDeviceState;
++    uint8_t bIsSelfPowered;
++    uint8_t bSetAddress;
++    uint8_t bAddress;
++    uint8_t bTestMode;
++    uint8_t bTestModeValue;
 +
-+#ifdef MUSB_VIRTHUB
-+#ifdef MUSB_USE_HCD_DRIVER
-+      if ( usb_add_hcd(hcd, pThis->nIrq, pThis->nIrqType)!=0 ) {
-+              DBG(2, "==> Usb_add_hcd failed \n");
-+              return NULL;
-+      }
-+#else
-+    if( 0!=mgc_init_bus(pThis, pDevice) ) {
-+        dbg("usb_alloc_bus fail");
-+              mgc_free_irq(pThis);
-+              return NULL;
-+    }
-+                      
++    struct usb_gadget* pGadget; /* the gadget */
++    struct usb_gadget_driver* pGadgetDriver; /* it's driver */
++
++    /* Endpoint 0 buffer and its buffer code; can be customized for
++     * devices that are not usign the default USB headers. Default
++     * values are:
++       *
++     * . pfFillBuffer is MGC_HdrcReadUSBControlRequest()
++     * . pEnd0Buffer is an instance of MGC_End0Buffer
++     **/
++    int (*pfReadHeader)(void*, uint16_t); /* NULL==MGC_HdrcReadUSBControlRequest*/
++   void* pEnd0Buffer; /* this is the buffer, default implementation uses MGC_End0Buffer */
++
++    /* compatibility, need to be osoleted used from gstorage */
++    uint16_t wEnd0Offset;
 +#endif
-+#endif 
-+udcinitmonitorflag_isr=1;
-+init_timer(&notify_timer);
-+notify_timer.expires = jiffies + msecs_to_jiffies(1000);
-+notify_timer.function = funct_host_notify_timer;
-+notify_timer.data = (unsigned long)pThis;
-+add_timer(&notify_timer);
 +
-+      return pThis;   
-+}
++#ifdef MUSB_OTG
++    MGC_OtgMachine OtgMachine;
++    MGC_OtgServices OtgServices;
++    uint8_t bDelayPortPowerOff;
++    uint8_t bOtgError;
++#endif
 +
-+static void funct_host_notify_timer(unsigned long uContext)
-+{
-+      MGC_LinuxCd *pThis = (MGC_LinuxCd*) uContext;
-+      uint8_t* pBase = (uint8_t*)pThis->pRegs;
-+      uint8_t devctl = 0;
-+      uint8_t power = 0;
-+      
-+      if(MUSB_IS_B_IDLE(pThis)) {
-+              MGC_HdrcReadUlpiReg(pThis, 0x13, &temp);
-+              if (!(temp & 0x10))
-+              {
-+                      MUSB_A_IDLE_MODE(pThis);
-+                      if(host_a_idle==0)
-+                      {
-+                              devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1);
-+                              power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF );
-+                      }
-+                      else{
-+                              power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER,power &0xBF );
-+                      }
-+              }
-+              mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
-+      }
-+      else if (MUSB_IS_A_IDLE(pThis)) {
-+              MGC_HdrcReadUlpiReg(pThis, 0x13, &temp);
-+              if(temp==0x08){
++#if MUSB_DEBUG > 0
++    uint32_t dwPadBack;
++#endif
 +
-+                      devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, 1);
-+              }
-+              else 
-+              {
-+                      MUSB_B_IDLE_MODE(pThis);
-+                      devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl &0xFE);
-+                      power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+                      MGC_Write8(pBase, MGC_O_HDRC_POWER,power | MGC_M_POWER_SOFTCONN );
-+              }
-+              mod_timer(&notify_timer, jiffies + msecs_to_jiffies(1000));
-+      }
-+      else if (MUSB_IS_DEV(pThis)) {
-+              del_timer(&notify_timer);
-+      }
-+      else if (MUSB_IS_HST(pThis)) {
-+              
-+              del_timer(&notify_timer);
-+      }
-+}
++#ifdef MUSB_CONFIG_PROC_FS
++    struct proc_dir_entry* pProcEntry;
 +
++    /* A couple of hooks to enable HSET */
++    MGC_pfDisconnectListener pfDisconnectListener;
++    void* pDisconnectListenerParam;
++    MGC_pfDefaultEndHandler pfDefaultEndHandler;
++    void* pDefaultEndHandlerParam;
++#endif
 +
-+void del_timer_func(void)
-+{
-+      del_timer(&notify_timer);
-+}
++} MGC_LinuxCd;
 +
-+void otg_disconnect(MGC_LinuxCd* pThis)
-+{
-+      uint8_t bEnd, devctl = 0;
-+      
-+      devctl &= ~MGC_M_DEVCTL_SESSION;
-+      
-+      MGC_VirtualHubPortDisconnected(&(pThis->RootHub), 0);
-+      
-+      /* flush endpoints */
-+      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+              MGC_HdrcStopEnd(pThis, bEnd);
-+      }
-+      
-+      mgc_hcd_flush(pThis);
++#ifdef MUSB_USE_HCD_DRIVER
++void mgc_hcd_complete_urb(MGC_LinuxCd *pThis, struct urb* pUrb);
++mgc_hcd_urb_queue * mgc_hcd_get_urb_queue(MGC_LinuxCd* pThis);
++#endif
 +
-+      pThis->pRootDevice = NULL;
 +
-+      MGC_Write8(pThis->pRegs, MGC_O_HDRC_DEVCTL, devctl);    
-+}
++/***************************** Glue it together *****************************/
 +
-+/* A couple of hooks to enable HSET */
-+#ifdef MUSB_CONFIG_PROC_FS
-+/**
-+ * Set a listener for disconnect interrupts.
-+ * @param pfListener listener, or NULL for none
-+ * @param pParam parameter to pass listener
-+ */
-+void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
-+      MGC_pfDisconnectListener pfListener, void* pParam)
-+{
-+    pCd->pfDisconnectListener = pfListener;
-+    pCd->pDisconnectListenerParam = pParam;
-+}
 +
-+/**
-+ * Set a new handler for the default endpoint interrupt.
-+ * @param pfHandler new handler, or NULL to restore default handler
-+ * @param pParam parameter to pass handler
-+ */
-+void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
-+      MGC_pfDefaultEndHandler pfHandler, void* pParam)
-+{
-+    pCd->pfDefaultEndHandler = pfHandler;
-+    pCd->pDefaultEndHandlerParam = pParam;
-+}
-+#endif
++extern unsigned int MGC_nIndex;
 +
++extern int MGC_DriverInit(void);
++extern void MGC_DriverCleanup(void);
 +
++extern void MGC_HdrcStart(MGC_LinuxCd* pThis);
++extern void MGC_HdrcStop(MGC_LinuxCd* pThis);
++extern void MGC_HdrcServiceUsb(MGC_LinuxCd* pThis, uint8_t reg);
++extern void MGC_HdrcLoadFifo(const uint8_t* pBase, uint8_t bEnd,
++      uint16_t wCount, const uint8_t* pSource);
++extern void MGC_HdrcUnloadFifo(const uint8_t* pBase, uint8_t bEnd,
++      uint16_t wCount, uint8_t* pDest);
 +
-+/*
-+ * Release resources acquired by driver
-+ */
-+void MGC_LinuxCdFree(MGC_LinuxCd* pThis)
-+{
-+    DBG(2, "<==\n");
-+    
-+    MGC_HdrcStop(pThis);
-+    MUSB_ERR_MODE(pThis, MUSB_ERR_SHUTDOWN);
-+    
-+#ifdef MUSB_CONFIG_PROC_FS
-+    MGC_LinuxDeleteProcFs(pThis);
-+#endif
++extern MGC_LinuxCd* MGC_LinuxInitController(void* pDevice, uint16_t wType,
++      int nIrq, void* pRegs, u64 len, const char* pName);
++extern void MGC_LinuxSetTimer(MGC_LinuxCd* pThis, void (*pfFunc)(unsigned long),
++      unsigned long pParam, unsigned long millisecs);
 +
-+#ifdef MUSB_PROC_TESTMUSB
-+    MGC_LinuxDeleteTestProcFs(pThis->aName, pThis);
-+#endif
++extern void MGC_LinuxCdFree(MGC_LinuxCd* pThis);
 +
-+#ifdef MUSB_DMA
-+    if(pThis->pDmaController) {
-+      pThis->pDmaController->pfDmaStopController(
-+              pThis->pDmaController->pPrivateData);
-+      MGC_HdrcDmaControllerFactory.pfDestroyDmaController(
-+              pThis->pDmaController);
-+    }
-+#endif
++extern struct urb* MGC_GetCurrentUrb(MGC_LinuxLocalEnd *pEnd);
 +
-+    MGC_VirtualHubStop(&pThis->RootHub);
-+    MGC_VirtualHubDestroy(&pThis->RootHub);
-+    
-+#ifndef MUSB_USE_HCD_DRIVER
-+    if (pThis->pBus->root_hub) {
-+        usb_disconnect(&(pThis->pBus->root_hub));
-+    }
-+      
-+    WAIT_MS(1);
-+    
-+    if(pThis->nIrq) {
-+        mgc_free_irq(pThis);
-+    }
++extern int queue_length(struct list_head *lh);
 +
-+    mgc_free_bus(pThis->pBus);
-+    KFREE(pThis);     
-+#endif
++/* Conditionally-compiled to update OTG state machine when necessary */
++extern void MGC_OtgUpdate(MGC_LinuxCd* pThis, uint8_t bVbusError,
++      uint8_t bConnect);
 +
-+    DBG(2, "==>\n");
-+}
++extern        void MGC_HdrcConfigureEps(MGC_LinuxCd* pThis);
++extern MGC_LinuxCd *hcd_to_musbstruct(void *ptr);
++extern struct usb_hcd* musbstruct_to_hcd(const MGC_LinuxCd *pThis);
 +
++/*-------------------------- available buses ---------------------*/
 +
++extern int direct_bus_init(void);
++extern void direct_bus_shutdown(void);
 +
-+/**
-+ * Initialize the driver.
-+ */
-+int MGC_DriverInit(void) 
-+{
-+    int rc=-ENODEV;
-+      int result;    
-+    DBG(2, "<==\n");
-+      
-+    nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
-+      
-+      /* the driver  was already initialized, no need to repeat this */
-+      if ( MGC_nIndex ) { 
-+              DBG(2, "==>\n"); 
-+              return 0;
-+      }
-+      
-+      if ( !usb_disabled() ) {
-+              do {
-+                      
-+                      int direct_bus=-ENODEV;
-+                      
-+                      direct_bus=direct_bus_init();
++/*-------------------------- ProcFS definitions ---------------------*/
 +
-+                      if ( direct_bus<0 ) {
++struct MGC_TestProcData;
++struct proc_dir_entry;
 +
-+                              ERR("Error initializing controller on the direct bus\n");   
-+                              rc=-ENODEV; break;
-+                      }
++#ifdef MUSB_CONFIG_PROC_FS
++extern char* decode_hst_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
++extern char* decode_dev_ep_protocol(MGC_LinuxCd* pThis, unsigned bEnd);
++#endif
 +
-+                      rc = 0;
++#ifdef MUSB_CONFIG_PROC_FS
++extern void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
++      MGC_pfDisconnectListener pfListener, void* pParam);
++extern void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
++      MGC_pfDefaultEndHandler pfHandler, void* pParam);
++extern struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name,
++      MGC_LinuxCd* data);
++extern void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data);
++#else
++#define PROC_FS_DISABLED(_x) {  DBG(3, "#PROC_FS DISABLED"); _x }
 +
-+              } while (0);
-+      } else {
-+              DBG(2, "USB Disabled , exiting\n");   
-+      }
-+              
-+      result = register_chrdev (MAJOR_NUMBER_OTG, "st-otg", &otg_fops);
++static inline void MGC_HdrcSetDisconnectListener(MGC_LinuxCd* pCd,
++      MGC_pfDisconnectListener pfListener, void* pParam) PROC_FS_DISABLED(;)
++static inline  void MGC_HdrcSetDefaultEndHandler(MGC_LinuxCd* pCd,
++      MGC_pfDefaultEndHandler pfHandler, void* pParam) PROC_FS_DISABLED(;)
++static inline struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name,
++      MGC_LinuxCd* data) PROC_FS_DISABLED(;)
++static inline void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data)
++      PROC_FS_DISABLED(;)
++#endif
 +
-+      if (result <0){
++/*-------------------------- TestProcFS definitions ---------------------*/
 +
-+              printk (KERN_WARNING "host can't get major %d\n", MAJOR_NUMBER_OTG);
-+              return result;
-+      }
-+      
-+      DBG(2, "==> rc=%d\n", rc); 
-+      return rc;
-+}
++#ifdef MUSB_PROC_TESTMUSB
++extern struct proc_dir_entry* MGC_LinuxCreateTestProcFs(char *name, MGC_LinuxCd* data);
++extern void MGC_LinuxDeleteTestProcFs(char *name, MGC_LinuxCd* data);
++#endif
 +
-+EXPORT_SYMBOL(MGC_DriverInit);
++/*------------------------------ IOCTLS/PROCFS -----------------------*/
 +
-+/**
-+ * release everything...
-+ */
-+void MGC_DriverCleanup(void) 
-+{ 
-+      int chr = 0; 
++extern void MGC_Zap(MGC_LinuxCd* pThis); /* zap the driver */
++extern void MGC_Session(MGC_LinuxCd* pThis); /* start a session */
++extern void MGC_SetDebugLevel(int level); /* set the debug level */
++extern int dump_header_stats(MGC_LinuxCd* pThis, char *buffer); /* compile options etc */
++#ifdef MUSB_HOST
++int dump_end_stats(MGC_LinuxCd* pThis, uint8_t bEnd, char* aBuffer);
++#endif
 +
-+      DBG(2, "<==\n");
 +
-+      if ( MGC_nIndex ) {
-+              
-+        chr  = unregister_chrdev (MAJOR_NUMBER_OTG, "st-otg");
-+        if (chr < 0)
-+                      printk (KERN_INFO"OTG Device cannot unregister %d %d\n", MAJOR_NUMBER_OTG, chr);
-+              
-+              usb_remove_hcd(hcd1);
-+        direct_bus_shutdown();
-+        free_irq(udc_address->nIrq,udc_address);
-+        MGC_LinuxDeleteProcFs(udc_address);
-+              nomadik_gpio_altfuncdisable(GPIO_ALT_USB_OTG, "OTG");
-+        iounmap(udc_address->pRegs);
-+        del_timer(&notify_timer);
-+        usb_put_hcd(hcd1);
-+              
-+      }
-+      
-+      MGC_nIndex=0;
-+      DBG(2, "==>\n");        
-+}
-+EXPORT_SYMBOL(MGC_DriverCleanup);
 +
-+/*-------------------------------------------------------------------------*/
++/*-------------------------- DEBUG Definitions ---------------------*/
 +
-+/* gstorage is liked to the driver: the init code lives there */
-+/* When compiled in the kernel, the init function is needed only when gadget
-+ * gadget API is not compiled (usb_register_driver takes care of the init 
-+ * using MGC_DriverInit & MGC_DriverCleanup)
-+ */
-+#ifndef MUSB_SKIP_INIT
 +
-+/**
-+ * Required initialization for any module.
-+ */
-+int __init MGC_ModuleInit (void) 
-+{
-+      return MGC_DriverInit();
-+}
++#ifdef MUSB_PARANOID
++#define MGC_HDRC_DUMPREGS(_t, _s) MGC_HdrcDumpRegs((_t)->pRegs, MUSB_IS_HST(_t) && _t->bIsMultipoint, _s)
++#define MGC_ISCORRUPT(_x)     mgc_is_corrupt((_x), __FUNCTION__,__LINE__)
 +
 +/**
-+ * Required cleanup for any module
++ * Test whether the struct is corrupted.
++ * @param pThis
 + */
-+void __exit MGC_ModuleCleanup (void)
-+{
-+              
-+      MGC_DriverCleanup();
-+}
-+
-+module_init(MGC_ModuleInit);
-+module_exit(MGC_ModuleCleanup);
++static inline uint8_t mgc_is_corrupt(MGC_LinuxCd* pThis, const char *function, int line) {
++#ifdef MUSB_HOST
++      uint8_t bEnd;
++      MGC_LinuxLocalEnd* pEnd;
 +#endif
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_procfs.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_procfs.c
---- linux-2.6.20/drivers/usb/nomadik/musb_procfs.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_procfs.c      2008-08-08 19:15:29.000000000 +0530
-@@ -0,0 +1,413 @@
-+/*
-+ * linux/drivers/usb/nomadik/musb_procfs.c
-+ *
-+ * Copyright 2007, STMicroelectronics
-+ *
-+ * 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 <asm/uaccess.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/proc_fs.h>
++      if(MGC_PAD_FRONT != pThis->dwPadFront) {
++              printk(KERN_INFO"musb %s:%d: pThis front pad corrupted (%x)\n",
++                      function, line, pThis->dwPadFront);
++              return TRUE;
++      }
 +
-+#include <linux/usb.h>
-+#include "musbdefs.h"
-+#include "musb_ioctl.h"
++      if(MGC_PAD_BACK != pThis->dwPadBack) {
++              printk(KERN_INFO"musb %s:%d: pThis back pad corrupted (%x)\n",
++                      function, line, pThis->dwPadBack);
++              return TRUE;
++      }
 +
-+/* ----------------------------------------------------------------------- */
++#ifdef MUSB_HOST
++      for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
++              pEnd = &(pThis->aLocalEnd[bEnd]);
 +
-+#if MUSB_DEBUG > 0
-+static int atoi(char* buffer, int base, int len) {
-+    int result=0, digit=0;
-+      
-+    while ( len-->0 && (*buffer) ) {    
-+              digit=((*buffer>='0') && (*buffer<='9'))
-+                      ? *buffer-'0'
-+                      : ((*buffer>='a') && (*buffer<='f'))
-+                      ? *buffer-'a'
-+                      : -1;
-+      
-+              if ( digit<0 ) {        
-+                      break;
++              if(MGC_PAD_FRONT != pEnd->dwPadFront) {
++                      printk(KERN_INFO"musb %s:%d: end %d front pad corrupted (%x)\n",
++                              function, line, bEnd, pEnd->dwPadFront);
++                      return TRUE;
 +              }
-+              
-+              buffer++; 
-+              result=result*base+digit;
-+    }
-+    
-+    return result;
-+}
 +
-+static int atoi_from_user(const char* buffer, int count) {
-+      char digits[8];
-+      int len=min(count, 8);  
-+      copy_from_user(&digits, buffer, len);
-+      return atoi(digits, 10, len);
-+}
++              if(MGC_PAD_BACK != pEnd->dwPadBack) {
++                      printk(KERN_INFO"musb %s:%d: end %d back pad corrupted (%x)\n",
++                              function, line, bEnd, pEnd->dwPadBack);
++                      return TRUE;
++              }
++      }
++#endif
 +
++#ifdef MUSB_GADGET
++      /* do something about it */
++#endif
 +
-+static const char* decode_address(int index) {
-+    static const char* COMMON_REGISTER_MAP[] = {
-+      "FAddr", "Power", "IntrTx", "IntrRx", 
-+      "IntrTxE", "IntrRxE", "IntrUSB", "IntrUSBE", 
-+      "Frame", "Index","TestMode" };
-+    return (index<11) ? COMMON_REGISTER_MAP[index]:NULL;
++      return FALSE;
 +}
-+#endif
 +
-+/* ----------------------------------------------------------------------- */
++#else
++#define MGG_IsCorrupt(_x)     (_x)
++#define MGC_HDRC_DUMPREGS(_t, _s)
++#endif
 +
++/* -------------------------- Host Definitions ------------------------ */
 +
-+/* Write to ProcFS
-+ *
-+ * C soft-connect
-+ * c soft-disconnect
-+ * I enable HS
-+ * i disable HS
-+ * R resume bus
-+ * S start session (OTG-friendly when OTG-compiled)
-+ * s stop session
-+ * F force session (OTG-unfriendly)
-+ * E rElinquish bus (OTG)
-+ * H request host mode
-+ * h cancel host request
-+ * P disable the low-power mode that kills us in peripheral mode
-+ * D<num> set/query the debug level
-+ * Z zap
-+ */
-+static int MGC_ProcWrite(struct file *file, const char *buffer,
-+                                               unsigned long count, void *data)
-+{
-+    char cmd;
-+    uint8_t bReg;    
-+    uint8_t* pBase=((MGC_LinuxCd*)data)->pRegs;
-+      
-+    /* MOD_INC_USE_COUNT; */
-+      
-+    if(copy_from_user(&cmd, buffer, 1) == 0){
-+              switch(cmd) {
-+              case 'C':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_SOFTCONN;
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+                      }
-+                      break;
-+                      
-+              case 'c':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_SOFTCONN;
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+                      }
-+                      break;
-+                      
-+              case 'I':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) | MGC_M_POWER_HSENAB;
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+                      }
-+                      break;
-+                      
-+              case 'i':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER) & ~MGC_M_POWER_HSENAB;
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+                      }
-+                      break;
-+                      
-+              case 'R':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_POWER);
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg | MGC_M_POWER_RESUME);
-+                              WAIT_MS(10);
-+                              MGC_Write8(pBase, MGC_O_HDRC_POWER, bReg);
-+                              WARN("Power Resumed\n");
-+                      } break;
-+                      
-+              case 'S':
-+                      MGC_Session((MGC_LinuxCd*)data);
-+                      break;
-+                      
-+                      
-+              case 's':
-+                      bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                      bReg &= ~MGC_M_DEVCTL_SESSION;
-+                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+                      break;
-+                      
-+              case 'F':
-+                      bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                      bReg |= MGC_M_DEVCTL_SESSION;
-+                      MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+                      break;
-+                      
-+              case 'H':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                              bReg |= MGC_M_DEVCTL_HR;
-+                              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+                      }
-+                      break;
-+                      
-+              case 'h':
-+                      if ( pBase ) {
-+                              bReg = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
-+                              bReg &= ~MGC_M_DEVCTL_HR;
-+                              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, bReg);
-+                      }
-+                      break;
-+                      
-+                      /* Xap the controller */
-+              case 'Z':
-+                      MGC_Zap((MGC_LinuxCd*)data);
-+                      break;
-+                      
-+#if (MUSB_DEBUG>0)    
-+                      /* read & write registers */
-+              case 'r':
-+              case 'w': {
-+                      uint8_t index=0;
-+                      uint32_t value=0;
-+                      char command[64];       
-+                      
-+                      memset(command, 0, sizeof(command));
-+                      copy_from_user(command, buffer, min(count, (unsigned long)63));
-+                      
-+                      /* detrermine the index, 
-+                      * only the adrress now */
-+                      index=atoi(&command[2], 16, count-2);
-+                      if ( index>0 && pBase ) {
-+                              const char *address=decode_address(index);
-+                              
-+                              if ( buffer[0]=='r' ) {
-+                                      value=(command[1]=='8')
-+                                              ? MGC_Read8(pBase, index)
-+                                              : (command[1]=='f')
-+                                              ? MGC_Read16(pBase, index)
-+                                              : 0;            
-+                              } else {
-+                                      /* not write, not yet... */
-+                                      index=-1;
-+                              }
-+                              
-+                              if ( address ) {
-+                                      INFO("%s=0x%x\n", address, value); 
-+                              } else {
-+                                      INFO("0x%x=0x%x\n", index, value); 
-+                              }
-+                      }       
-+                                } break;
-+                      
-+                      /* set/read debug level */
-+              case 'D': {             
-+                      if ( count>1 ) {
-+                              int level=0;                            
-+                              level=atoi_from_user(&buffer[1], count-1);                              
-+                              MGC_SetDebugLevel(level);
-+                      } else {
-+                              INFO("MGC_DebugLevel=%d\n", MGC_DebugLevel); 
-+                              /* & dump the status to syslog */
-+                      }                        
-+                                } break;
-+                      
-+                      /* display queue status */
-+              case 'Q': {
-+                      int index=-1;
-+                      char endb[256];
-+                      MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
-+                      
-+                      if (count>2) {
-+                              index=atoi_from_user(&buffer[1], count-1);
-+                      }
-+                      
-+                      if ( dump_header_stats(pThis, endb)>0 ) {
-+                              printk(KERN_INFO"%s", endb);
-+                      }
-+                      
 +#ifdef MUSB_HOST
-+                      if( MUSB_IS_HST(pThis) ) {
-+                              if ( index<0 ) {
-+                                      uint8_t bEnd;
-+                                      
-+                                      /* generate the report for the end points */
-+                                      for (bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+                                              if ( dump_end_stats(pThis, bEnd, endb)>0 ) {
-+                                                      printk(KERN_INFO"%s", endb);
-+                                              }
-+                                      }
-+                                      
-+                              } else {
-+                                      if ( dump_end_stats(pThis, index, endb)>0 ) {
-+                                              printk(KERN_INFO"%s", endb);
-+                                      }
-+                              }                               
-+                      }
-+#endif                        
-+                      
-+                      
-+                                } break;
-+                      
-+              case 'd': {
-+                      if ( count>1 ) {
-+                              int delay=atoi_from_user(&buffer[1], count-1);
-+                              MGC_SetDeviceDelay(delay);
-+                      }
-+                      INFO("mgc_slow_device_kludge_delay=%d\n", 
-+                              MGC_SetDeviceDelay(-1)); 
-+                                } break;
-+                      
-+                      /* flush */     
-+              case '?': 
-+                      INFO("?: you are seeing it\n");
-+                      INFO("C/c: soft connect enable/disable\n");
-+                      INFO("I/i: hispeed enable/disable\n");
-+                      INFO("S/s: session set/clear\n");
-+                      INFO("F: \n");
-+                      INFO("H: host mode\n");
-+                      INFO("r/w: read write register\n");
-+                      INFO("Z: zap\n");
-+                      INFO("D: set/read dbug level\n");
-+                      INFO("Q: show queue status\n");
-+                      break;
-+#endif                
-+                      
-+              default:
-+                      ERR("Command %c not implemented\n", cmd);
-+                      break;
-+    }
-+      }
-+      
-+    return count;
-+} 
-+
++extern void MGC_InitLocalEndPoints(MGC_LinuxCd* pThis);
++#endif
 +
-+/**
-+ * Read from /proc filesystem.
-+ * @param
-+ * @param
-+ * @param
-+ * @param
-+ * @param
-+ * @param
-+ */
-+static int MGC_ProcRead(char *page, char **start, 
-+      off_t off, int count, int *eof, void *data) 
-+{
-+    off_t len=0;
-+    char *buffer;
-+    int rc=0, code=0; 
-+    unsigned long flags;
-+    MGC_LinuxCd* pThis=(MGC_LinuxCd*)data;
++/* -------------------------- Gadget Definitions --------------------- */
 +
-+    spin_lock_irqsave(&pThis->Lock, flags);
++struct usb_ep;
 +
-+      buffer=kmalloc(4*1024, GFP_USER);
-+      if ( !buffer ) {
-+              ERR("Out of memory\n");
-+              return -1;
-+      }
-+      
-+      /* generate the report for the end points */
-+      code=dump_header_stats(pThis, buffer);
-+      if ( code>0 ) {
-+              len+=code;
-+      }
-+      
-+#ifdef MUSB_HOST      
-+      if( MUSB_IS_HST(pThis) ) {
-+              
-+              uint8_t bEnd;
++extern const uint8_t MGC_aTestPacket[MGC_TEST_PACKET_SIZE];
 +
-+              for(bEnd = 0; bEnd < pThis->bEndCount; bEnd++) {
-+                      code=dump_end_stats(pThis, bEnd, &buffer[len]);
-+                      if ( code>0 ) {
-+                              len+=code;      
-+                      }
-+              }
-+      }
++#if defined(MUSB_GADGET) || defined(MUSB_V26)
++void* MGC_AllocBufferMemory(MGC_LinuxCd* pThis, size_t bytes, int gfp_flags, dma_addr_t* dma);
++void MGC_FreeBufferMemory(MGC_LinuxCd* pThis, size_t bytes, void *address, dma_addr_t dma);
 +#endif
 +
-+    if ( off<len ) {
-+              int i=0, togo=len-off;
-+              char *s=&buffer[off],*d=page;
-+      
-+              if ( togo>count ) {
-+                      togo=count;
-+              }
-+      
-+              while ( i++<togo ) {
-+                      *d++=*s++;
-+              }
-+      
-+              rc=togo;            
-+    } else {
-+              *buffer=0;
-+              *eof=1; 
-+    }
++#ifdef MUSB_GADGET
++extern void* MGC_MallocEp0Buffer(const MGC_LinuxCd* pThis);
++#endif
 +
-+      kfree(buffer);
-+    spin_unlock_irqrestore(&pThis->Lock, flags);
-+    return rc;
-+} 
++/* Gadget functions */
++#ifdef MUSB_GADGET
++struct usb_gadget;
 +
++extern MGC_LinuxCd* MGC_GetDriverByName(const char *name);
++extern int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd);
++extern void mgc_init_gadget_endpoints(MGC_LinuxCd *pThis, struct usb_gadget *gadget);
++extern void MGC_GadgetReset(MGC_LinuxCd* pThis);
++extern void MGC_GadgetResume(MGC_LinuxCd* pThis);
++extern void MGC_GadgetSuspend(MGC_LinuxCd* pThis);
++extern void MGC_GadgetDisconnect(MGC_LinuxCd* pThis);
++extern void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis);
++extern void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd);
++extern void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd);
 +
-+/**
-+ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
-+ * @param data the controller instance
-+ */
-+void MGC_LinuxDeleteProcFs(MGC_LinuxCd* data) {    
-+    remove_proc_entry(data->pProcEntry->name, NULL);
-+}
++extern void dump_ep_status(MGC_LinuxCd* pThis);
++extern void dump_ep_queue(int index, int verbose);
 +
-+/**
-+ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points 
-+ * @param data the controller instance
++/*
++ * Gadget disabled
 + */
-+void MGC_LinuxRemoveProcFs(MGC_LinuxCd* data) {
-+    remove_proc_entry(data->pProcEntry->name, NULL);
-+}
++#else
++#define GADGET_DISABLED(_x) {  DBG(0, "#GADGET DISABLED"); _x }
 +
-+/**
-+ * TODO: 2.4 and 2.6 create the pseudo-device in 2 different points
-+ * @param name
-+ * @param data the controller instance
-+ */
-+struct proc_dir_entry* MGC_LinuxCreateProcFs(char *name, MGC_LinuxCd* data) {
-+    if ( !name ) {
-+      name=data->aName;
-+    }
++static inline MGC_LinuxCd* MGC_GetDriverByName(const char *name)
++      GADGET_DISABLED( return NULL; )
++static inline int MGC_GadgetFindEnd(struct usb_ep* pGadgetEnd)
++      GADGET_DISABLED( return -1; )
++static inline void MGC_InitGadgetEndPoints(MGC_LinuxCd *pThis)
++      GADGET_DISABLED(;)
++static inline void MGC_GadgetReset(MGC_LinuxCd* pThis)
++      GADGET_DISABLED(;)
++static inline void MGC_GadgetResume(MGC_LinuxCd* pThis)
++      GADGET_DISABLED(;)
++static inline void MGC_GadgetSuspend(MGC_LinuxCd* pThis)
++      GADGET_DISABLED(;)
++static inline void MGC_GadgetDisconnect(MGC_LinuxCd* pThis)
++      GADGET_DISABLED(;)
++static inline void MGC_HdrcServiceDeviceDefaultEnd(MGC_LinuxCd* pThis)
++      GADGET_DISABLED(;)
++static inline void MGC_HdrcServiceDeviceTxAvail(MGC_LinuxCd* pThis, uint8_t bEnd)
++      GADGET_DISABLED(;)
++static inline void MGC_HdrcServiceDeviceRxReady(MGC_LinuxCd* pThis, uint8_t bEnd)
++      GADGET_DISABLED(;)
 +
-+    data->pProcEntry=create_proc_entry(name, 
-+      S_IFREG | S_IRUGO | S_IWUSR, NULL);
-+    if( data->pProcEntry )
-+    {
-+      data->pProcEntry->data = data;
-+#ifdef MUSB_V26
-+      data->pProcEntry->owner=THIS_MODULE;
++static inline void dump_ep_status(MGC_LinuxCd* pThis)
++      GADGET_DISABLED(;)
++static inline void dump_ep_queue(int index, int verbose)
++      GADGET_DISABLED(;)
 +#endif
-+      
-+      data->pProcEntry->read_proc = MGC_ProcRead;
-+      data->pProcEntry->write_proc = MGC_ProcWrite;
-+
-+      data->pProcEntry->size = 0;
-+
-+      dbg("Registered /proc/%s\n", name);
-+    } else {
-+        dbg ("Cannot create a valid proc file entry");    
-+    }
 +
-+    return data->pProcEntry;  
-+}
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.c ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.c
---- linux-2.6.20/drivers/usb/nomadik/musb_virthub.c    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.c     2008-07-28 15:21:03.000000000 +0530
-@@ -0,0 +1,840 @@
++#endif        /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musbhdrc.h
+@@ -0,0 +1,315 @@
 +/*
-+ * linux/drivers/usb/nomadik/musb_virthub.c
++ * linux/drivers/usb/nomadik/musbhdrc.h
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -201554,835 +203305,309 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.c ../new/linux-2.6.20
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
++#ifndef __MUSB_HDRC_DEFS_H__
++#define __MUSB_HDRC_DEFS_H__
 +
-+//#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/time.h>
-+#include <linux/timer.h>
++/*
++ * HDRC-specific definitions
++ * $Revision: 1.8 $
++ */
 +
-+#include <linux/usb.h>
++#define MGC_MAX_USB_ENDS       16
 +
-+#ifndef MUSB_LINUX_MV21
-+#include "../core/hcd.h"
-+#define HAS_USB_TT_MULTI
-+#else
-+#include <hub.h>
-+#endif
++#define MGC_END0_FIFOSIZE      64      /* this is non-configurable */
 +
-+#include "musbdefs.h"
++/*
++ *     MUSBMHDRC Register map
++ */
 +
-+/******************************* FORWARDS ********************************/
++/* Common USB registers */
 +
-+static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub, 
-+      void (*pfExpired)(unsigned long), unsigned long timeout);
-+static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb);
-+static void MGC_VirtualHubTimerExpired(unsigned long ptr);
++#define MGC_O_HDRC_FADDR      0x00    /* 8-bit */
++#define MGC_O_HDRC_POWER      0x01    /* 8-bit */
 +
-+/******************************* GLOBALS *********************************/
++#define MGC_O_HDRC_INTRTX     0x02    /* 16-bit */
++#define MGC_O_HDRC_INTRRX       0x04
++#define MGC_O_HDRC_INTRTXE      0x06
++#define MGC_O_HDRC_INTRRXE      0x08
++#define MGC_O_HDRC_INTRUSB      0x0A   /* 8 bit */
++#define MGC_O_HDRC_INTRUSBE     0x0B   /* 8 bit */
++#define MGC_O_HDRC_FRAME        0x0C
++#define MGC_O_HDRC_INDEX        0x0E   /* 8 bit */
++#define MGC_O_HDRC_TESTMODE     0x0F   /* 8 bit */
 +
-+/** device descriptor */
-+static uint8_t MGC_aVirtualHubDeviceDesc[] =
-+{
-+    USB_DT_DEVICE_SIZE,
-+    USB_DT_DEVICE,
-+    0x00, 0x02,                       /* bcdUSB */
-+    USB_CLASS_HUB,            /* bDeviceClass */
-+    0,                                /* bDeviceSubClass */
-+    1,                                /* bDeviceProtocol (single TT) */
-+    64,                               /* bMaxPacketSize0 */
-+    0xd6, 0x4,                        /* idVendor */
-+    0, 0,                     /* idProduct */
-+    0, 0,                     /* bcdDevice */
-+    0,                                /* iManufacturer */
-+    0,                                /* iProduct */
-+    0,                                /* iSerialNumber */
-+    1                         /* bNumConfigurations */
-+};
++/* Get offset for a given FIFO */
++#define MGC_FIFO_OFFSET(_bEnd) (0x20 + (_bEnd * 4))
 +
-+/** device qualifier */
-+static uint8_t MGC_aVirtualHubQualifierDesc[] =
-+{
-+    USB_DT_DEVICE_QUALIFIER_SIZE,
-+    USB_DT_DEVICE_QUALIFIER,
-+    0x00, 0x02,                       /* bcdUSB */
-+    USB_CLASS_HUB,            /* bDeviceClass */
-+    0,                                /* bDeviceSubClass */
-+    0,                                /* bDeviceProtocol */
-+    64,                               /* bMaxPacketSize0 */
-+    0xd6, 0x4,                        /* idVendor */
-+    0, 0,                     /* idProduct */
-+    0, 0,                     /* bcdDevice */
-+    0,                                /* iManufacturer */
-+    0,                                /* iProduct */
-+    0,                                /* iSerialNumber */
-+    1                         /* bNumConfigurations */
-+};
++/* Additional Control Registers */
 +
-+/** Configuration descriptor */
-+static uint8_t MGC_VirtualHubConfigDesc[] = 
-+{
-+    USB_DT_CONFIG_SIZE,
-+    USB_DT_CONFIG,
-+    USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
-+    0x01,                     /* bNumInterfaces */
-+    0x01,                     /* bConfigurationValue */
-+    0x00,                     /* iConfiguration */
-+    0xE0,                     /* bmAttributes (self-powered, remote wake) */
-+    0x00,                     /* MaxPower */
-+    
-+    /* interface */
-+    USB_DT_INTERFACE_SIZE,
-+    USB_DT_INTERFACE,
-+    0x00,                     /* bInterfaceNumber */
-+    0x00,                     /* bAlternateSetting */
-+    0x01,                     /* bNumEndpoints */
-+    USB_CLASS_HUB,            /* bInterfaceClass */
-+    0x00,                     /* bInterfaceSubClass */
-+    0x00,                     /* bInterfaceProtocol */
-+    0x00,                     /* iInterface */
-+    
-+    /* endpoint */
-+    USB_DT_ENDPOINT_SIZE,
-+    USB_DT_ENDPOINT,
-+    USB_DIR_IN | 1,           /* bEndpointAddress: IN Endpoint 1 */
-+    USB_ENDPOINT_XFER_INT,    /* bmAttributes: Interrupt */
-+    (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0,            /* wMaxPacketSize */
-+    12                        /* bInterval: 256 ms */
-+};
++#define       MGC_O_HDRC_DEVCTL       0x60       /* 8 bit */
 +
-+/** other-speed Configuration descriptor */
-+static uint8_t MGC_VirtualHubOtherConfigDesc[] = 
-+{
-+    USB_DT_CONFIG_SIZE,
-+    USB_DT_OTHER_SPEED,
-+    USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE, 0,
-+    0x01,                     /* bNumInterfaces */
-+    0x01,                     /* bConfigurationValue */
-+    0x00,                     /* iConfiguration */
-+    0xE0,                     /* bmAttributes (self-powered, remote wake) */
-+    0x00,                     /* MaxPower */
-+    
-+    /* interface */
-+    USB_DT_INTERFACE_SIZE,
-+    USB_DT_INTERFACE,
-+    0x00,                     /* bInterfaceNumber */
-+    0x00,                     /* bAlternateSetting */
-+    0x01,                     /* bNumEndpoints */
-+    USB_CLASS_HUB,            /* bInterfaceClass */
-+    0x00,                     /* bInterfaceSubClass */
-+    0x00,                     /* bInterfaceProtocol */
-+    0x00,                     /* iInterface */
-+    
-+    /* endpoint */
-+    USB_DT_ENDPOINT_SIZE,
-+    USB_DT_ENDPOINT,
-+    USB_DIR_IN | 1,           /* bEndpointAddress: IN Endpoint 1 */
-+    USB_ENDPOINT_XFER_INT,    /* bmAttributes: Interrupt */
-+    (MGC_VIRTUALHUB_MAX_PORTS + 8) / 8, 0,            /* wMaxPacketSize */
-+    0xff                      /* bInterval: 255 ms */
-+};
++/* These are actually indexed: */
++#define MGC_O_HDRC_TXFIFOSZ   0x62    /* 8-bit (see masks) */
++#define MGC_O_HDRC_RXFIFOSZ   0x63    /* 8-bit (see masks) */
++#define MGC_O_HDRC_TXFIFOADD  0x64    /* 16-bit offset shifted right 3 */
++#define MGC_O_HDRC_RXFIFOADD  0x66    /* 16-bit offset shifted right 3 */
 +
-+/****************************** FUNCTIONS ********************************/
++#define MGC_O_HDRC_TOPCONTROL 0x204   /* top control register 16-bit */
 +
-+/**
-+ * Generic timer activation helper. Requires the hub structure to 
-+ * be locked.
-+ * 
-+ * @param pHub pointer to hub struct
-+ * @param pfExpired callback function
-+ * @param timeout millisecs
-+ * @requires spin_lock(pHub->Lock)
-+ */
-+static void MGC_VirtualHubActivateTimer(MGC_VirtualHub* pHub, 
-+      void (*pfExpired)(unsigned long), unsigned long timeout)
-+{
-+      DBG(2, "<== pHub=%p, pHub->pUrb=%p\n", pHub, pHub->pUrb);
-+    del_timer(&pHub->Timer); /* make sure another timer is not running */
-+    init_timer(&(pHub->Timer));
-+    pHub->Timer.function = pfExpired;
-+    pHub->Timer.data = (unsigned long)pHub;
-+    pHub->Timer.expires = jiffies + timeout * HZ / 1000;
-+    add_timer( &(pHub->Timer) );
-+}
++/* offsets to registers in flat model */
++#define MGC_O_HDRC_TXMAXP     0x00
++#define MGC_O_HDRC_TXCSR      0x02
++#define MGC_O_HDRC_CSR0       MGC_O_HDRC_TXCSR        /* re-used for EP0 */
++#define MGC_O_HDRC_RXMAXP     0x04
++#define MGC_O_HDRC_RXCSR      0x06
++#define MGC_O_HDRC_RXCOUNT    0x08
++#define MGC_O_HDRC_COUNT0     MGC_O_HDRC_RXCOUNT      /* re-used for EP0 */
++#define MGC_O_HDRC_TXTYPE     0x0A
++#define MGC_O_HDRC_TYPE0      MGC_O_HDRC_TXTYPE       /* re-used for EP0 */
++#define MGC_O_HDRC_TXINTERVAL 0x0B
++#define MGC_O_HDRC_NAKLIMIT0  MGC_O_HDRC_TXINTERVAL   /* re-used for EP0 */
++#define MGC_O_HDRC_RXTYPE     0x0C
++#define MGC_O_HDRC_RXINTERVAL 0x0D
++#define MGC_O_HDRC_FIFOSIZE   0x0F
++#define MGC_O_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE     /* re-used for EP0 */
 +
-+/**
-+ * Report the VHUB status bits. Assumes that pData has enough
-+ * storage for all of them.
-+ * @param pHub the hub
-+ * @param pData the data buffer status shoudl be written to
-+ * @return  
-+ */
-+int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData) {
-+    int nPort, length=1;
-+    uint8_t bData=0, bBit=1;
-+    
-+    /* count 1..N to accomodate hub status bit */
-+    for(nPort = 1; nPort <= pHub->bPortCount + 1; nPort++) {
-+              if(pHub->aPortStatusChange[nPort-1].wChange & 1) {
-+                      bData |= 1 << bBit;
-+              }
-+              
-+              if(++bBit > 7) {
-+                      *pData++ = bData;
-+                      bData = bBit = 0;
-+                      length++;
-+              }
-+    }
-+    
-+    if(bBit) {
-+              *pData++ = bData;
-+    }
++#define MGC_END_OFFSET(_bEnd, _bOffset)       (0x100 + (0x10*_bEnd) + _bOffset)
 +
-+      return length;
-+}
++/* "bus control" registers */
++#define MGC_O_HDRC_TXFUNCADDR 0x00
++#define MGC_O_HDRC_TXHUBADDR  0x02
++#define MGC_O_HDRC_TXHUBPORT  0x03
++
++#define MGC_O_HDRC_RXFUNCADDR 0x04
++#define MGC_O_HDRC_RXHUBADDR  0x06
++#define MGC_O_HDRC_RXHUBPORT  0x07
++
++#define MGC_BUSCTL_OFFSET(_bEnd, _bOffset)    (0x80 + (8*_bEnd) + _bOffset)
 +
 +/*
-+ * assumes pHub to be locked!
-+ * @requires spin_lock(pHub->Lock)
++ *     MUSBHDRC Register bit masks
 + */
-+static void MGC_VirtualHubCompleteIrq(MGC_VirtualHub* pHub, struct urb* pUrb)
-+{
-+    pHub->bIsChanged = FALSE;
 +
-+    pUrb->actual_length=mgc_rh_port_status(pHub, (uint8_t*)pUrb->transfer_buffer);
-+      if (pUrb->actual_length && pUrb->complete) {
-+        COMPLETE_URB(pUrb, NULL);
-+    }
-+}
++/* POWER */
 +
-+/**
-+ * Timer expiration function to complete the interrupt URB on changes
-+ * @param ptr standard expiration param (hub pointer)
-+ */
-+static void MGC_VirtualHubTimerExpired(unsigned long ptr)
-+{
-+    struct urb* pUrb;
-+    MGC_VirtualHub* pHub = (MGC_VirtualHub*)ptr;
-+    
-+      DBG(2, "<== pHub=%p, pHub->pUrb=%p, pUrb->hcpriv=%p\n", pHub, 
-+              pHub->pUrb, (pHub->pUrb)?((struct urb*)pHub->pUrb)->hcpriv:NULL);
-+              
-+    spin_lock(&pHub->Lock);
-+    pUrb=pHub->pUrb;  
-+    if(pUrb && (pUrb->hcpriv == pHub)) {
-+      uint8_t bPort;
-+    
-+              for(bPort = 0; bPort < pHub->bPortCount; bPort++) {
-+                      if ( pHub->aPortStatusChange[bPort].wChange ) {
-+                              pUrb->status=0;
-+                              MGC_VirtualHubCompleteIrq(pHub, pUrb);
-+                              break;
-+                      }
-+              }
++#define MGC_M_POWER_ISOUPDATE   0x80
++#define       MGC_M_POWER_SOFTCONN    0x40
++#define       MGC_M_POWER_HSENAB      0x20
++#define       MGC_M_POWER_HSMODE      0x10
++#define MGC_M_POWER_RESET       0x08
++#define MGC_M_POWER_RESUME      0x04
++#define MGC_M_POWER_SUSPENDM    0x02
++#define MGC_M_POWER_ENSUSPEND   0x01
++
++/* INTRUSB */
++#define MGC_M_INTR_SUSPEND    0x01
++#define MGC_M_INTR_RESUME     0x02
++#define MGC_M_INTR_RESET      0x04
++#define MGC_M_INTR_BABBLE     0x04
++#define MGC_M_INTR_SOF        0x08
++#define MGC_M_INTR_CONNECT    0x10
++#define MGC_M_INTR_DISCONNECT 0x20
++#define MGC_M_INTR_SESSREQ    0x40
++#define MGC_M_INTR_VBUSERROR  0x80   /* FOR SESSION END */
++#define MGC_M_INTR_EP0      0x01  /* FOR EP0 INTERRUPT */
++
++/* DEVCTL */
++#define MGC_M_DEVCTL_BDEVICE    0x80
++#define MGC_M_DEVCTL_FSDEV      0x40
++#define MGC_M_DEVCTL_LSDEV      0x20
++#define MGC_M_DEVCTL_VBUS       0x18
++#define MGC_S_DEVCTL_VBUS       3
++#define MGC_M_DEVCTL_HM         0x04
++#define MGC_M_DEVCTL_HR         0x02
++#define MGC_M_DEVCTL_SESSION    0x01
++
++/* TESTMODE */
++
++#define MGC_M_TEST_FORCE_HOST   0x80
++#define MGC_M_TEST_FIFO_ACCESS  0x40
++#define MGC_M_TEST_FORCE_FS     0x20
++#define MGC_M_TEST_FORCE_HS     0x10
++#define MGC_M_TEST_PACKET       0x08
++#define MGC_M_TEST_K            0x04
++#define MGC_M_TEST_J            0x02
++#define MGC_M_TEST_SE0_NAK      0x01
 +
-+              /* re-activate timer only when the urb is still mine; pUrb->hcpriv is
-+               * set to NULL on port disconnect */
-+              MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired, 
-+                      pHub->wInterval);
-+    } else {
-+              DBG(3, "pUrb=%p, for me =%d\n", pUrb, (pUrb)?((pUrb->hcpriv)?1:0):-1 );         
-+      }
-+    spin_unlock(&pHub->Lock);
-+}
++/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
++#define MGC_M_FIFOSZ_DPB      0x10
++/* allocation size (8, 16, 32, ... 4096) */
++#define MGC_M_FIFOSZ_SIZE     0x0f
 +
-+/**
-+ * Initialize the virtual hub.
-+ * @param pHub  
-+ * @param pBus
-+ * @param bPortCount
-+ * @param pPortServices
-+ * @return 0 success, <0 when errror
-+ */
-+int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus,
-+    uint8_t bPortCount, MGC_PortServices* pPortServices)
-+{
-+    uint8_t bPort;
-+    
-+    if(bPortCount > MGC_VIRTUALHUB_MAX_PORTS) {
-+              ERR("Cannot allocate a %d-port device (too many ports)", bPortCount); 
-+              return -EINVAL;
-+    }
++/* CSR0 */
++#define       MGC_M_CSR0_FLUSHFIFO      0x0100
++#define MGC_M_CSR0_TXPKTRDY       0x0002
++#define MGC_M_CSR0_RXPKTRDY       0x0001
 +
-+#if defined(MUSB_REGISTER_ROOT_HUB) || !defined(MUSB_USE_HCD_DRIVER)  
-+    /* allocate device, the hcd driver allocate */
-+    pHub->pDevice=USB_ALLOC_DEV(NULL, pBus, 0);
-+    if(!pHub->pDevice) {
-+              ERR("Cannot allocate a %d-port device", bPortCount); 
-+              return -ENODEV;
-+    }
-+      
-+    pHub->pDevice->speed=USB_SPEED_HIGH;
-+#endif
++/* CSR0 in Peripheral mode */
++#define MGC_M_CSR0_P_SVDSETUPEND  0x0080
++#define MGC_M_CSR0_P_SVDRXPKTRDY  0x0040
++#define MGC_M_CSR0_P_SENDSTALL    0x0020
++#define MGC_M_CSR0_P_SETUPEND     0x0010
++#define MGC_M_CSR0_P_DATAEND      0x0008
++#define MGC_M_CSR0_P_SENTSTALL    0x0004
 +
-+    DBG(3, "New device (%d-port virtual hub) @%#lx allocated\n", \
-+              bPortCount, (unsigned long)pHub->pDevice); 
++/* CSR0 in Host mode */
++#define MGC_M_CSR0_H_NO_PING    0x0800
++#define MGC_M_CSR0_H_WR_DATATOGGLE   0x0400   /* set to allow setting: */
++#define MGC_M_CSR0_H_DATATOGGLE           0x0200      /* data toggle control */
++#define       MGC_M_CSR0_H_NAKTIMEOUT   0x0080
++#define MGC_M_CSR0_H_STATUSPKT    0x0040
++#define MGC_M_CSR0_H_REQPKT       0x0020
++#define MGC_M_CSR0_H_ERROR        0x0010
++#define MGC_M_CSR0_H_SETUPPKT     0x0008
++#define MGC_M_CSR0_H_RXSTALL      0x0004
 +
-+    pHub->pBus = pBus;
-+    
-+      spin_lock_init(&pHub->Lock);
-+    pHub->pUrb = NULL;
-+    pHub->pPortServices = pPortServices;
-+    pHub->bPortCount = bPortCount;
-+    pHub->bIsChanged = FALSE;
-+    init_timer(&(pHub->Timer)); /* I will need this later */
++/* TxType/RxType */
++#define MGC_M_TYPE_SPEED      0xc0
++#define MGC_S_TYPE_SPEED      6
++#define MGC_TYPE_SPEED_HIGH   1
++#define MGC_TYPE_SPEED_FULL   2
++#define MGC_TYPE_SPEED_LOW    3
++#define MGC_M_TYPE_PROTO      0x30
++#define MGC_S_TYPE_PROTO      4
++#define MGC_M_TYPE_REMOTE_END 0xf
 +
-+    for(bPort = 0; bPort < bPortCount; bPort++) {
-+      pHub->aPortStatusChange[bPort].wStatus = 0;
-+      pHub->aPortStatusChange[bPort].wChange = 0;
-+    }
++/* CONFIGDATA */
 +
-+#ifdef MUSB_V24
-+    usb_connect(pHub->pDevice);
-+#endif
++#define MGC_M_CONFIGDATA_MPRXE      0x80      /* auto bulk pkt combining */
++#define MGC_M_CONFIGDATA_MPTXE      0x40      /* auto bulk pkt splitting */
++#define MGC_M_CONFIGDATA_BIGENDIAN  0x20
++#define MGC_M_CONFIGDATA_HBRXE      0x10      /* HB-ISO for RX */
++#define MGC_M_CONFIGDATA_HBTXE      0x08      /* HB-ISO for TX */
++#define MGC_M_CONFIGDATA_DYNFIFO    0x04      /* dynamic FIFO sizing */
++#define MGC_M_CONFIGDATA_SOFTCONE   0x02      /* SoftConnect */
++#define MGC_M_CONFIGDATA_UTMIDW     0x01   /* data width 0 => 8bits, 1 => 16bits */
 +
-+    return 0; /* OK */ 
-+}
++/* TXCSR in Peripheral and Host mode */
 +
-+/**
-+ * Destroy a virtual hub
-+ * @param pHub the vhub to destroy
-+ */
-+void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub)
-+{
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
-+}
++#define MGC_M_TXCSR_AUTOSET       0x8000
++#define MGC_M_TXCSR_ISO           0x4000
++#define MGC_M_TXCSR_MODE          0x2000
++#define MGC_M_TXCSR_DMAENAB       0x1000
++#define MGC_M_TXCSR_FRCDATATOG    0x0800
++#define MGC_M_TXCSR_DMAMODE       0x0400
++#define MGC_M_TXCSR_CLRDATATOG    0x0040
++#define MGC_M_TXCSR_FLUSHFIFO     0x0008
++#define MGC_M_TXCSR_FIFONOTEMPTY  0x0002
++#define MGC_M_TXCSR_TXPKTRDY      0x0001
 +
-+/**
-+ * Start a virtual hub. Set the address and create a new device for it.
-+ * @param pHub the vhub to start.
-+ */
-+void MGC_VirtualHubStart(MGC_VirtualHub* pHub)
-+{
-+    DBG(2, "<== announcing pHub=%p to usbcore\n", pHub);    
-+      pHub->bAddress=1;       
-+      
-+#ifdef MUSB_REGISTER_ROOT_HUB
-+#ifndef MUSB_USE_HCD_DRIVER
-+      if ( USB_NEW_DEVICE(pHub) ) {
-+        ERR("usb_new_device failed\n");
-+    }
-+#endif        
-+#endif
++/* TXCSR in Peripheral mode */
 +
-+      DBG(2, "==>\n");
-+}
++#define MGC_M_TXCSR_P_INCOMPTX    0x0080
++#define MGC_M_TXCSR_P_SENTSTALL   0x0020
++#define MGC_M_TXCSR_P_SENDSTALL   0x0010
++#define MGC_M_TXCSR_P_UNDERRUN    0x0004
 +
-+/**
-+ * Stop a virtual hub. 
-+ * @param pHub the vhub to stop
-+ */
-+void MGC_VirtualHubStop(MGC_VirtualHub* pHub)
-+{
-+#ifndef MUSB_USE_HCD_DRIVER           
-+    /* stop interrupt timer */
-+    del_timer_sync(&pHub->Timer);
-+#endif
-+}
++/* TXCSR in Host mode */
 +
-+/** Submit an URB to the virtual hub.
-+ *  bRequest: 
-+ *            00      
-+ *            01      
-+ *            03              
-+ *
-+ *    bmRequestType:
-+ *            0x23
-+ *            0xa3
-+ *
-+ * @param pHub the hub urb should be submitted to 
-+ * @param pUrb the urb to submit 
-+ */
-+int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb)
-+{
-+    uint8_t bRecip;           /* from standard request */
-+    uint8_t bReqType;         /* from standard request */
-+    uint8_t bType;            /* requested descriptor type */
-+    uint16_t wValue;          /* from standard request */
-+    uint16_t wIndex;          /* from standard request */
-+    uint16_t wLength;         /* from standard request */
-+    uint8_t bPort;
-+    const MUSB_DeviceRequest* pRequest;
-+    uint16_t wSize = 0xffff;
-+    uint8_t* pData = (uint8_t*)pUrb->transfer_buffer;
-+    unsigned int pipe = pUrb->pipe;
++#define MGC_M_TXCSR_H_WR_DATATOGGLE   0x0200
++#define MGC_M_TXCSR_H_DATATOGGLE      0x0100
++#define MGC_M_TXCSR_H_NAKTIMEOUT  0x0080
++#define MGC_M_TXCSR_H_RXSTALL     0x0020
++#define MGC_M_TXCSR_H_ERROR       0x0004
 +
-+      DBG(-1, "<== pUrb=%p\n", pUrb);
-+      
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
-+      
-+    spin_lock(&pHub->Lock);
-+    usb_get_urb(pUrb);
-+        
-+    pUrb->hcpriv = pHub;
-+    pUrb->status = -EINPROGRESS;
-+      
-+    if ( usb_pipeint(pipe) ) {
-+      DBG(-1, "pUrb=%p is periodic status/change event\n", pUrb );
-+        
-+        /* this is the one for periodic status/change events */
-+        pHub->pUrb = pUrb;
-+              pHub->wInterval = (pUrb->interval < 16) ? (1 << (pUrb->interval - 1)) :
-+              pUrb->interval;
-+        spin_unlock(&pHub->Lock);
-+              return 0;
-+    }
++/* RXCSR in Peripheral and Host mode */
 +
-+    /* handle hub requests/commands */
-+    pRequest = (const MUSB_DeviceRequest*)pUrb->setup_packet;
-+    bReqType = pRequest->bmRequestType & USB_TYPE_MASK;
-+    bRecip = pRequest->bmRequestType & USB_RECIP_MASK;
-+    wValue = le16_to_cpu(pRequest->wValue);
-+    wIndex = le16_to_cpu(pRequest->wIndex);
-+    wLength = le16_to_cpu(pRequest->wLength);
++#define MGC_M_RXCSR_AUTOCLEAR     0x8000
++#define MGC_M_RXCSR_DMAENAB       0x2000
++#define MGC_M_RXCSR_DISNYET       0x1000
++#define MGC_M_RXCSR_DMAMODE       0x0800
++#define MGC_M_RXCSR_INCOMPRX      0x0100
++#define MGC_M_RXCSR_CLRDATATOG    0x0080
++#define MGC_M_RXCSR_FLUSHFIFO     0x0010
++#define MGC_M_RXCSR_DATAERROR     0x0008
++#define MGC_M_RXCSR_FIFOFULL      0x0002
++#define MGC_M_RXCSR_RXPKTRDY      0x0001
 +
-+    DBG(3, "pRequest->bRequest=%02x, pRequest->bmRequestType=%02x, wLength=%04x\n", 
-+      pRequest->bRequest, pRequest->bmRequestType, wLength); 
++/* RXCSR in Peripheral mode */
 +
-+    switch (pRequest->bRequest) {
-+              case USB_REQ_GET_STATUS:        
-+                      DBG(3, "GET_STATUS(), bType=%02x, bRecip=%02x, wIndex=%04x\n", \
-+                              bReqType, bRecip, wIndex); 
-+              
-+                      if(USB_TYPE_STANDARD == bReqType) {
-+                              /* self-powered */
-+                              pData[0] = (USB_RECIP_DEVICE == bRecip) ? 1 : 0;
-+                              pData[1] = 0;
-+                              wSize = 2;
-+                      } else if(USB_TYPE_CLASS == bReqType) {
-+                              if((USB_RECIP_OTHER == bRecip) && (wIndex <= pHub->bPortCount)) {
-+                                      /* port status/change report */
-+                                      memcpy(pData, &(pHub->aPortStatusChange[wIndex-1].wStatus), 2);
-+                                      memcpy(&(pData[2]), &(pHub->aPortStatusChange[wIndex-1].wChange),
-+                                              2);
-+                                              
-+                                      /* reset change (TODO: lock) */
-+                                      pHub->aPortStatusChange[wIndex-1].wChange = 0;
-+                                      wSize = 4;
-+                              } else {
-+                                      /* hub status */
-+                                      memset(pData, 0, 4);
-+                                      wSize = 4;
-+                              }
-+              
-+                              DBG(2, "status report=%02x%02x%02x%02x\n", \
-+                              pData[0], pData[1], pData[2], pData[3]);        
-+                      }
-+              break;
-+              
-+              case USB_REQ_CLEAR_FEATURE:
-+                      bPort = (uint8_t)(wIndex & 0xff) - 1;
-+                      DBG(3, "CLR_FEAT bReqType=0x%x, wValue=0x%x, wIndex=0x%x\n", 
-+                              bReqType, wValue, (wIndex & 0xff) );                    
-+              if((USB_TYPE_STANDARD == bReqType) && (USB_RECIP_ENDPOINT == bRecip))
-+              {
-+                      wSize = 0;
-+                      DBG(3, "END POINT FEATURE!\n");                                                 
-+              } else if(USB_TYPE_CLASS == bReqType) {
-+              
-+                      if(USB_RECIP_OTHER == bRecip)
-+                      {
-+                              bPort = (uint8_t)(wIndex & 0xff) - 1;                           
-+                              DBG(3, "CLEAR_PORT_FEATURE(%d), port %d\n", \
-+                                      wValue, bPort);
-+                              switch(wValue) {
-+                                      case USB_PORT_FEAT_CONNECTION:
-+                                      case USB_PORT_FEAT_OVER_CURRENT:
-+                                      case USB_PORT_FEAT_POWER:
-+                                      case USB_PORT_FEAT_LOWSPEED:
-+                                      case USB_PORT_FEAT_HIGHSPEED:
-+                                      case USB_PORT_FEAT_TEST:
-+                                      case USB_PORT_FEAT_INDICATOR:
-+                                              DBG(3, "feat 0x%02x, wIndex=%d\n", wValue, bPort); 
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_ENABLE:
-+                                              DBG(4, "enable port %d\n", bPort); 
-+                                              pHub->pPortServices->pfSetPortEnable(
-+                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_SUSPEND:
-+                                              DBG(3, "suspend port %d\n", bPort); 
-+                                              pHub->pPortServices->pfSetPortSuspend(
-+                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_RESET:
-+                                              DBG(4, "reset port %d\n", bPort); 
-+                                              pHub->pPortServices->pfSetPortReset(
-+                                              pHub->pPortServices->pPrivateData, bPort, FALSE);
-+                                              wSize = 0;
-+                                              break;
-+                                              
-+                                      /* acknowledge changes: */
-+                                      case USB_PORT_FEAT_C_CONNECTION:
-+                                              DBG(3, "ack connection port %d\n", bPort);                      
-+                                              pHub->aPortStatusChange[bPort].wChange &= ~1;
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_C_ENABLE:
-+                                              DBG(3, "ack enable port %d\n", bPort);                  
-+                                              pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_ENABLE;
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_C_SUSPEND:
-+                                              DBG(3, "ack suspend port %d\n", bPort); 
-+                      
-+                                              pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_SUSPEND;
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_C_RESET:
-+                                              DBG(3, "ack reset port %d\n", bPort); 
-+                                              pHub->aPortStatusChange[bPort].wChange &= ~USB_PORT_STAT_RESET;
-+                                              wSize = 0;
-+                                              break;
-+                                      case USB_PORT_FEAT_C_OVER_CURRENT:
-+                                              DBG(3, "ack over current port %d\n", bPort);                    
-+                                              wSize = 0;
-+                                              break;
-+                                      
-+                                      default:
-+                                              INFO("clear feature 0x%02x on port=%d unknown\n", wValue, bPort);                       
-+                                              break;                                          
-+                              }
-+                      } else {
-+                              DBG(3, "clear wValue=%d on port=%d\n", wValue, bPort);                  
-+                              switch(wValue) {
-+                                      case C_HUB_LOCAL_POWER:
-+                                      case C_HUB_OVER_CURRENT:
-+                                              wSize = 0;
-+                                              break;
-+                              }
-+                      }                       
-+                      pHub->bIsChanged = TRUE;
-+              }
-+              break;
-+              
-+              case USB_REQ_SET_FEATURE:
-+                      if((USB_TYPE_CLASS == bReqType) && (USB_RECIP_OTHER == bRecip))
-+              {
-+                      bPort = (uint8_t)(wIndex & 0xff) - 1;                   
-+                      DBG(3, "SET_PORT_FEATURE(0x%02x), port %d\n", wValue, bPort);                   
-+                      switch(wValue) {
-+                              case USB_PORT_FEAT_SUSPEND:
-+                                      DBG(3, "suspend port %d\n", bPort); 
-+                                              pHub->pPortServices->pfSetPortSuspend(
-+                                              pHub->pPortServices->pPrivateData, bPort, TRUE);
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_SUSPEND;
-+                                      pHub->bIsChanged = TRUE;
-+                                      wSize = 0;
-+                                      break;
-+                              
-+                              case USB_PORT_FEAT_RESET:
-+                                      DBG(3, "reset port %d\n", bPort);                                       
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_RESET;
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
-+                                      pHub->aPortStatusChange[bPort].wChange |= USB_PORT_STAT_RESET;
-+                                      pHub->bIsChanged = TRUE;
-+                                      pHub->pPortServices->pfSetPortReset(pHub->pPortServices->pPrivateData, 
-+                                              bPort, TRUE);
-+                                      wSize = 0;
-+                                      break;
-+                                
-+                              case USB_PORT_FEAT_POWER:
-+                                      DBG(3, "power port %d\n", bPort);               
-+                                      pHub->pPortServices->pfSetPortPower(pHub->pPortServices->pPrivateData, 
-+                                              bPort, TRUE);
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_POWER;
-+                                      wSize = 0;
-+                                      break;
-+                              
-+                              case USB_PORT_FEAT_ENABLE:
-+                                      DBG(3, "enable port %d\n", bPort); 
-+                                      pHub->pPortServices->pfSetPortEnable(pHub->pPortServices->pPrivateData, 
-+                                              bPort, TRUE);
-+                                      pHub->aPortStatusChange[bPort].wStatus |= USB_PORT_STAT_ENABLE;
-+                                      wSize = 0;
-+                                      break;
-+                      }
-+              } else {
-+                      DBG(3, "SET_FEATURE(%04x), but feature unknown\n", wValue); 
-+              }
-+              break;
-+              
-+              case USB_REQ_SET_ADDRESS:
-+                      pHub->bAddress = (wValue & 0x7f);
-+                      DBG(3, "SET_ADDRESS(%x) \n", pHub->bAddress); 
-+                              wSize = 0;
-+              break;
-+              
-+              case USB_REQ_GET_DESCRIPTOR:
-+                      if(USB_TYPE_CLASS == bReqType) {
-+                              DBG(3, "GET_CLASS_DESCRIPTOR()\n");
-+              
-+                              pData[0] = 9;
-+                              pData[1] = 0x29;
-+                              pData[2] = pHub->bPortCount;
-+                              /* min characteristics */
-+                              pData[3] = 1;  /* invidual port power switching */
-+                              pData[4] = 0;
-+                              /* PowerOn2PowerGood */
-+                              pData[5] = 50;
-+                              /* no current */
-+                              pData[6] = 0;
-+                              /* removable ports */
-+                              pData[7] = 0;
-+                              /* reserved */
-+                              pData[8] = 0xff;
-+                              wSize = pData[0];
-+                      } else {
-+                              bType = (uint8_t)(wValue >> 8); 
-+                              DBG(3, "GET_DESCRIPTOR(%d)\n", bType); 
-+                              switch(bType) {
-+                                      case USB_DT_DEVICE: /* 1 */
-+                                              wSize = min(wLength, (uint16_t)MGC_aVirtualHubDeviceDesc[0]);
-+                                      memcpy(pData, MGC_aVirtualHubDeviceDesc, wSize);
-+                                      break;
-+                                      case USB_DT_DEVICE_QUALIFIER:
-+                                              wSize = min(wLength, (uint16_t)MGC_aVirtualHubQualifierDesc[0]);
-+                                      memcpy(pData, MGC_aVirtualHubQualifierDesc, wSize);
-+                                      break;
-+                                      case USB_DT_CONFIG: /* 2 */
-+                                              wSize = min(wLength, (uint16_t)MGC_VirtualHubConfigDesc[2]);
-+                                      memcpy(pData, MGC_VirtualHubConfigDesc, wSize);
-+                                      break;
-+                                      case USB_DT_OTHER_SPEED:
-+                                              wSize = min(wLength, (uint16_t)MGC_VirtualHubOtherConfigDesc[2]);
-+                                      memcpy(pData, MGC_VirtualHubOtherConfigDesc, wSize);
-+                                      break;
-+                              }
-+                      }
-+              break;
-+              
-+              case USB_REQ_GET_CONFIGURATION:
-+              DBG(3, "GET_CONFIG() => 1\n");
-+                      pData[0] = 1;
-+              wSize = 1;
-+              break;
-+              
-+              case USB_REQ_SET_CONFIGURATION:
-+              DBG(3, "SET_CONFIG(%04x)\n", wValue);
-+                      wSize = 0;
-+              break;
-+              
-+    }   /* END: switch on request type */
++#define MGC_M_RXCSR_P_ISO         0x4000
++#define MGC_M_RXCSR_P_SENTSTALL   0x0040
++#define MGC_M_RXCSR_P_SENDSTALL   0x0020
++#define MGC_M_RXCSR_P_OVERRUN     0x0004
 +
-+    if(0xffff == wSize) {
-+        pUrb->status = USB_ST_STALL;
-+    } else {
-+              pUrb->actual_length = wSize;
-+              pUrb->status = 0;       
-+    }
-+      
-+    spin_unlock(&pHub->Lock);    
-+    if (pUrb->complete) {
-+              DBG(3, "completing URB status=%d\n", pUrb->status );
-+               COMPLETE_URB(pUrb, NULL);
-+              pUrb->hcpriv = NULL;    
-+              usb_put_urb(pUrb);
-+              DBG(4, "URB completed\n");
-+    }
++/* RXCSR in Host mode */
 +
-+    DBG(2, "==> pUrb->status=%d %s, length=%d, completed=%s\n", pUrb->status, \
-+      (pUrb->status)?"(STALL)":"", pUrb->actual_length, 
-+              (pUrb->complete)?"yes":"no");
-+              
-+    return 0;
-+}
++#define MGC_M_RXCSR_H_AUTOREQ     0x4000
++#define MGC_M_RXCSR_H_WR_DATATOGGLE   0x0400
++#define MGC_M_RXCSR_H_DATATOGGLE        0x0200
++#define MGC_M_RXCSR_H_RXSTALL     0x0040
++#define MGC_M_RXCSR_H_REQPKT      0x0020
++#define MGC_M_RXCSR_H_ERROR       0x0004
 +
-+/**
-+ * Unlink an URB from a virtual hub.
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param pUrb URB pointer
-+ * @return Linux status code
-+ * @see #MGC_VirtualHubInit
-+ */
-+int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb)
-+{
-+    DBG(2, "<== pUrb=%p\n", pUrb);
-+      
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
++/* HUBADDR */
++#define MGC_M_HUBADDR_MULTI_TT                0x80
 +
-+    spin_lock(&pHub->Lock);
-+    if(pUrb && (pHub->pUrb == pUrb) && (pUrb->hcpriv == pHub)) {
-+        pHub->bIsChanged = FALSE;
-+      
-+              if (pUrb->transfer_flags & USB_ASYNC_UNLINK) {
-+                      pUrb->status = -ECONNRESET;
-+                      if (pUrb->complete) {
-+                        COMPLETE_URB(pUrb, NULL);
-+                      }
-+              } else {
-+                      pUrb->status = -ENOENT;
-+              }
 +
-+        pUrb->hcpriv = NULL;
-+              pHub->pUrb = NULL;
-+      }
-+      
-+      spin_unlock(&pHub->Lock);    
-+    usb_put_urb(pUrb);            
++/* TXCSR in Peripheral and Host mode */
 +
-+    DBG(2, "==>\n");
-+    return 0;
-+}
++#define MGC_M_TXCSR2_AUTOSET       0x80
++#define MGC_M_TXCSR2_ISO           0x40
++#define MGC_M_TXCSR2_MODE          0x20
++#define MGC_M_TXCSR2_DMAENAB       0x10
++#define MGC_M_TXCSR2_FRCDATATOG    0x08
++#define MGC_M_TXCSR2_DMAMODE       0x04
 +
++#define MGC_M_TXCSR1_CLRDATATOG    0x40
++#define MGC_M_TXCSR1_FLUSHFIFO     0x08
++#define MGC_M_TXCSR1_FIFONOTEMPTY  0x02
++#define MGC_M_TXCSR1_TXPKTRDY      0x01
 +
-+/**
-+ * assumes bPortIndex < MGC_VIRTUALHUB_MAX_PORTS
-+ * AND pHub->Lock to be... locked :)
-+ */
-+STATIC void MGC_SetVirtualHubPortSpeed(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex, uint8_t bSpeed
-+) {
-+    uint16_t wSpeedMask = 0;
++/* TXCSR in Peripheral mode */
 +
-+    DBG(2, "<== bPortIndex=%d, bSpeed=%d\n", bPortIndex, bSpeed);     
-+    
-+    switch(bSpeed) {
-+              case 0:
-+                      wSpeedMask = USB_PORT_STAT_LOW_SPEED;
-+              break;
-+              case 2:
-+                      wSpeedMask = USB_PORT_STAT_HIGH_SPEED;
-+              break;
-+    }
++#define MGC_M_TXCSR1_P_INCOMPTX    0x80
++#define MGC_M_TXCSR1_P_SENTSTALL   0x20
++#define MGC_M_TXCSR1_P_SENDSTALL   0x10
++#define MGC_M_TXCSR1_P_UNDERRUN    0x04
 +
-+    pHub->aPortStatusChange[bPortIndex].wStatus &= 
-+      ~(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
-+    pHub->aPortStatusChange[bPortIndex].wStatus |= 1 | wSpeedMask;
-+    pHub->bIsChanged = TRUE;
-+    DBG(2, "==>\n");
-+}
++/* TXCSR in Host mode */
 +
-+/**
-+ * A port reset is complete
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, uint8_t bPortIndex, 
-+      uint8_t bHubSpeed)
-+{     
-+    DBG(2, "<==port %d reset complete\n", bPortIndex);
-+      
-+    if(bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) {
-+      MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bHubSpeed);
-+      
-+        pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_RESET;
-+        pHub->aPortStatusChange[bPortIndex].wStatus |= USB_PORT_STAT_ENABLE;
-+              pHub->aPortStatusChange[bPortIndex].wChange = USB_PORT_STAT_RESET |
-+                      USB_PORT_STAT_ENABLE;
-+              pHub->bIsChanged = TRUE;
-+    } 
-+    DBG(2, "==>\n");
-+}
++#define MGC_M_TXCSR1_H_NAKTIMEOUT  0x80
++#define MGC_M_TXCSR1_H_RXSTALL     0x20
++#define MGC_M_TXCSR1_H_ERROR       0x04
 +
-+/**
-+ * A device has effectively been connected to a virtual hub port
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port with connected device
-+ * @param bSpeed device speed (0=>low, 1=>full, 2=>high)
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, uint8_t bPortIndex,
-+      uint8_t bSpeed)
-+{
-+    DBG(2, "<== port %d connected, core reports speed=%d\n", bPortIndex, bSpeed);         
-+    if (bPortIndex < MGC_VIRTUALHUB_MAX_PORTS) {      
-+              struct urb* pUrb=pHub->pUrb;
-+      
-+              MGC_SetVirtualHubPortSpeed(pHub, bPortIndex, bSpeed);
-+              pHub->aPortStatusChange[bPortIndex].wChange |= 1;
-+      
-+              /* shorter time... it want it NOW! */
-+              DBG(2, "<== pHub=%p, pHub->pUrb=%p, pHub->pUrb->hcpriv=%p\n", pHub,
-+                      pUrb, (pUrb)?pUrb->hcpriv:NULL);            
-+              if ( pUrb && ( (!pUrb->hcpriv) || (pUrb->hcpriv== pHub))) {
-+                      pUrb->hcpriv=pHub;                      
-+                      MGC_VirtualHubActivateTimer(pHub, MGC_VirtualHubTimerExpired, 1);
-+              }
-+    }
-+    DBG(2, "==>\n");
-+}
-+      
-+/**
-+ * A device has effectively been disconnected from a virtual hub port
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port of disconnected device
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, uint8_t bPortIndex)
-+{
-+      struct urb* pUrb;
++/* RXCSR in Peripheral and Host mode */
 +
-+    DBG(-1, "<== Port %d disconnected\n", bPortIndex);
-+      
-+      if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) {
-+                      DBG(-1, "==>");
-+                      return;
-+      }
-+      
-+#ifndef MUSB_USE_HCD_DRIVER   
-+      del_timer_sync(&pHub->Timer);
-+#endif
++#define MGC_M_RXCSR2_AUTOCLEAR     0x80
++#define MGC_M_RXCSR2_DMAENAB       0x20
++#define MGC_M_RXCSR2_DISNYET       0x10
++#define MGC_M_RXCSR2_DMAMODE       0x08
++#define MGC_M_RXCSR2_INCOMPRX      0x01
 +
-+      pUrb= pHub->pUrb;       
-+      pHub->aPortStatusChange[bPortIndex].wStatus &= ~1;
-+      pHub->aPortStatusChange[bPortIndex].wChange |= 1;
-+      pHub->bIsChanged = TRUE;
-+      
-+      if (pUrb && (pUrb->hcpriv == pHub)) {
-+              pUrb->status=0;
-+              MGC_VirtualHubCompleteIrq(pHub, pUrb);
-+      }
++#define MGC_M_RXCSR1_CLRDATATOG    0x80
++#define MGC_M_RXCSR1_FLUSHFIFO     0x10
++#define MGC_M_RXCSR1_DATAERROR     0x08
++#define MGC_M_RXCSR1_FIFOFULL      0x02
++#define MGC_M_RXCSR1_RXPKTRDY      0x01
 +
-+    DBG(-1, "==>\n");
-+}
-+      
-+/**
-+ * A device has effectively resumed a virtual hub port
-+ * @param pHub pointer to hub initialized by successful MGC_VirtualHubInit
-+ * @param bPortIndex 0-based index of port of resume
-+ * @see #MGC_VirtualHubInit
-+ */
-+void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, uint8_t bPortIndex)
-+{
-+      DBG(2, "<== Resume port %d\n", bPortIndex); 
-+#ifdef MUSB_USE_HCD_DRIVER    
-+      ERR("** you shoudl not call %s when using the HCD driver\n", __FUNCTION__);
-+#endif
++/* RXCSR in Peripheral mode */
 +
-+      if(bPortIndex >= MGC_VIRTUALHUB_MAX_PORTS) {
-+              return;
-+      }
++#define MGC_M_RXCSR2_P_ISO         0x40
++#define MGC_M_RXCSR1_P_SENTSTALL   0x40
++#define MGC_M_RXCSR1_P_SENDSTALL   0x20
++#define MGC_M_RXCSR1_P_OVERRUN     0x04
 +
-+      pHub->aPortStatusChange[bPortIndex].wStatus &= ~USB_PORT_STAT_SUSPEND;
-+      pHub->aPortStatusChange[bPortIndex].wChange |= USB_PORT_STAT_SUSPEND;
-+      pHub->bIsChanged = TRUE;        
-+    DBG(2, "==>\n");
-+}
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.h ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.h
---- linux-2.6.20/drivers/usb/nomadik/musb_virthub.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/musb_virthub.h     2008-07-28 15:21:05.000000000 +0530
-@@ -0,0 +1,240 @@
++/* RXCSR in Host mode */
++
++#define MGC_M_RXCSR2_H_AUTOREQ     0x40
++#define MGC_M_RXCSR1_H_RXSTALL     0x40
++#define MGC_M_RXCSR1_H_REQPKT      0x20
++#define MGC_M_RXCSR1_H_ERROR       0x04
++
++/* Top control register */
++#define MGC_M_TOPCTRL_MODE_ULPI          0x09
++#define MGC_M_TOPCTRL_MODE_SRST    0x04
++
++#endif        /* multiple inclusion protection */
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/musbhsfc.h
+@@ -0,0 +1,150 @@
 +/*
-+ * linux/drivers/usb/nomadik/musb_virthub.h
++ * linux/drivers/usb/nomadik/musbhsfc.h
 + *
 + * Copyright 2007, STMicroelectronics
 + *
@@ -202398,232 +203623,141 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_virthub.h ../new/linux-2.6.20
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+#ifndef __MUSB_LINUX_VIRTUALHUB_H__
-+#define __MUSB_LINUX_VIRTUALHUB_H__
-+
-+#include <linux/spinlock.h>
-+#include <linux/timer.h>
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
-+#define USB_NEW_DEVICE(_vh) usb_register_root_hub((_vh)->pDevice, (_vh)->pBus->controller)
-+#else
-+#ifdef __bluecat__
-+#define USB_NEW_DEVICE(_vh) usb_new_device((_vh)->pDevice, (((_vh)->pDevice)->parent)?&((_vh)->pDevice)->parent->dev:NULL )
-+#else
-+#define USB_NEW_DEVICE(_vh)  usb_new_device((_vh)->pDevice)
-+#endif
-+#endif
++#ifndef __MUSB_HSFC_DEFS_H__
++#define __MUSB_HSFC_DEFS_H__
 +
-+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
-+#define MUSB_REGISTER_ROOT_HUB
-+#endif
++#define MGC_MAX_USB_ENDS      16
 +
-+struct urb;
-+struct usb_bus;
++#define MGC_END0_FIFOSIZE    64      /* this is non-configurable */
 +
-+#ifdef MUSB_USE_HCD_DRIVER
-+struct usb_hcd;
-+#endif
++#define MGC_M_FIFO_EP0     0x20
 +
-+/**
-+ * Introduction.
-+ * For USB controllers lacking embedded root hubs,
-+ * this module can be used as a virtual root hub,
-+ * with one or more controllers as the virtual hub's ports.
++/*
++ *     MUSBHSFC Register map
 + */
 +
-+/****************************** CONSTANTS ********************************/
++/* Common USB registers */
 +
-+/** Maximum number of ports to accomodate */
-+#define MGC_VIRTUALHUB_MAX_PORTS      7
++#define MGC_O_HSFC_FADDR      0x00    /* 8-bit */
++#define MGC_O_HSFC_POWER      0x01    /* 8-bit */
 +
-+/******************************** TYPES **********************************/
++#define MGC_O_HSFC_INTRIN     0x02    /* 16-bit */
++#define MGC_O_HSFC_INTROUT      0x04
++#define MGC_O_HSFC_INTRINE      0x06
++#define MGC_O_HSFC_INTROUTE     0x08
++#define MGC_O_HSFC_INTRUSB      0x0A   /* 8 bit */
++#define MGC_O_HSFC_INTRUSBE     0x0B   /* 8 bit */
++#define MGC_O_HSFC_FRAME        0x0C
++#define MGC_O_HSFC_INDEX        0x0E   /* 8 bit */
++#define MGC_O_HSFC_TESTMODE     0x0F   /* 8 bit */
 +
-+/**
-+ * Set a port's power on or off.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bPower TRUE to power on the port; FALSE to power off
-+ */
-+typedef void (*MGC_pfSetPortPower)(void* pPrivateData, uint8_t bPortIndex,
-+                                 uint8_t bPower);
++/* These are actually indexed: */
++#define MGC_O_HSFC_TXFIFOSZ   0x1a    /* 8-bit (see masks) */
++#define MGC_O_HSFC_RXFIFOSZ   0x1b    /* 8-bit (see masks) */
++#define MGC_O_HSFC_TXFIFOADD  0x1c    /* 16-bit offset shifted right 3 */
++#define MGC_O_HSFC_RXFIFOADD  0x1e    /* 16-bit offset shifted right 3 */
 +
-+/**
-+ * Enable or disable a port.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bEnable TRUE to enable port; FALSE to disable
-+ */
-+typedef void (*MGC_pfSetPortEnable)(void* pPrivateData, uint8_t bPortIndex,
-+                                  uint8_t bEnable);
++/* Endpoint registers */
++#define MGC_O_HSFC_TXMAXP     0x00
++#define MGC_O_HSFC_TXCSR      0x02
++#define MGC_O_HSFC_CSR0               MGC_O_HSFC_TXCSR        /* re-used for EP0 */
++#define MGC_O_HSFC_RXMAXP     0x04
++#define MGC_O_HSFC_RXCSR      0x06
++#define MGC_O_HSFC_RXCOUNT    0x08
++#define MGC_O_HSFC_COUNT0     MGC_O_HSFC_RXCOUNT      /* re-used for EP0 */
 +
-+/**
-+ * Set a port's suspend mode on or off.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bSuspend TRUE to suspend port; FALSE to resume
++/*
++ *     MUSBHSFC Register bit masks
 + */
-+typedef void (*MGC_pfSetPortSuspend)(void* pPrivateData, uint8_t bPortIndex,
-+                                   uint8_t bSuspend);
 +
-+/**
-+ * Set a port's reset on or off.
-+ * @param pPrivateData pPrivateData from port services
-+ * @param bPortIndex 0-based index of port
-+ * @param bReset TRUE to assert reset on the bus behind a port; FALSE to deassert
-+ */
-+typedef void (*MGC_pfSetPortReset)(void* pPrivateData, uint8_t bPortIndex,
-+                                 uint8_t bReset);
-+                                 
-+/**
-+ * MGC_PortServices.
-+ * Services provided to a virtual by a USB port controller.
-+ * @field pPrivateData port controller's implementation data;
-+ * not to be interpreted by virtual hub
-+ * @param pfSetPortPower set-port-power call
-+ * @param pfSetPortEnable set-port-enable call
-+ * @param pfSetPortSuspend set-port-suspend call
-+ * @param pfSetPortReset set-port-reset call
-+ */
-+typedef struct
-+{
-+    void* pPrivateData;
-+    MGC_pfSetPortPower pfSetPortPower;
-+    MGC_pfSetPortEnable pfSetPortEnable;
-+    MGC_pfSetPortSuspend pfSetPortSuspend;
-+    MGC_pfSetPortReset pfSetPortReset;
-+} MGC_PortServices;
++/* POWER */
 +
-+/**
-+ * MGC_HubPortStatusChange.
-+ * @field wStatus status
-+ * @field wChange change
-+ */
-+typedef struct
-+{
-+    uint16_t wStatus;
-+    uint16_t wChange;
-+} MGC_HubPortStatusChange;
++#define MGC_M_POWER_ISOUPDATE   0x80
++#define       MGC_M_POWER_SOFTCONN    0x40
++#define       MGC_M_POWER_HSENAB      0x20
++#define       MGC_M_POWER_HSMODE      0x10
++#define MGC_M_POWER_RESET       0x08
++#define MGC_M_POWER_RESUME      0x04
++#define MGC_M_POWER_SUSPENDM    0x02
++#define MGC_M_POWER_ENSUSPEND   0x01
 +
-+/**
-+ * MGC_VirtualHub.
-+ * Virtual USB hub instance data.
-+ * @field Lock spinlock
-+ * @field pBus our bus pointer
-+ * @field pDevice our device pointer
-+ * @field pUrb pointer to interrupt URB for status change
-+ * @field pPortServices pointer to port services
-+ * @field Timer interval timer for status change interrupts
-+ * @field aPortStatusChange status/change array
-+ * @field bPortCount how many ports
-+ * @field wInterval actual interval in milliseconds
-+ * @field bIsChanged TRUE if changes to report
-+ * @field bAddress address assigned by usbcore
-+ */
-+typedef struct
-+{
-+    spinlock_t Lock;
-+    struct usb_bus* pBus;
-+    struct usb_device* pDevice;
++/* Interrupt register bit masks */
++#define MGC_M_INTR_SUSPEND    0x01
++#define MGC_M_INTR_RESUME     0x02
++#define MGC_M_INTR_RESET      0x04
++#define MGC_M_INTR_SOF        0x08
 +
-+      void *pUrb;
-+    MGC_PortServices* pPortServices;
-+    struct timer_list Timer;
-+    MGC_HubPortStatusChange aPortStatusChange[MGC_VIRTUALHUB_MAX_PORTS];
-+    uint8_t bPortCount;
-+    uint16_t wInterval;
-+    uint8_t bIsChanged;
-+    uint8_t bAddress;
-+      
-+} MGC_VirtualHub;
++/* TESTMODE */
 +
-+/******************************** Protos **********************************/
++#define MGC_M_TEST_FORCEFS      0x20
++#define MGC_M_TEST_FORCEHS      0x10
++#define MGC_M_TEST_PACKET       0x08
++#define MGC_M_TEST_K            0x04
++#define MGC_M_TEST_J            0x02
++#define MGC_M_TEST_SE0_NAK      0x01
 +
-+extern int mgc_rh_port_status(MGC_VirtualHub* pHub, uint8_t* pData);
++/* allocate for double-packet buffering (effectively doubles assigned _SIZE) */
++#define MGC_M_FIFOSZ_DPB      0x10
++/* allocation size (8, 16, 32, ... 4096) */
++#define MGC_M_FIFOSZ_SIZE     0x0f
 +
-+#ifdef MUSB_VIRTHUB
-+void MGC_LinuxSetPortPower(void* pPrivateData, uint8_t bPortIndex,
-+    uint8_t bPower);
-+void MGC_LinuxSetPortEnable(void* pPrivateData, uint8_t bPortIndex,
-+    uint8_t bEnable);
-+void MGC_LinuxSetPortSuspend(void* pPrivateData, uint8_t bPortIndex,
-+      uint8_t bSuspend);
-+void MGC_LinuxSetPortReset(void* pPrivateData, uint8_t bPortIndex,
-+      uint8_t bReset);
++/* CSR0 */
 +
-+extern int MGC_VirtualHubInit(MGC_VirtualHub* pHub, struct usb_bus* pBus, 
-+      uint8_t bPortCount, MGC_PortServices* pPortServices);
-+extern void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub);
-+extern void MGC_VirtualHubStart(MGC_VirtualHub* pHub);
-+extern void MGC_VirtualHubStop(MGC_VirtualHub* pHub);
-+extern int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
-+extern int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb);
-+extern void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex, uint8_t bHubSpeed);
-+extern void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex, uint8_t bSpeed);
-+extern void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex);
-+extern void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex);
++#define MGC_M_CSR0_P_SVDSETUPEND  0x0080
++#define MGC_M_CSR0_P_SVDRXPKTRDY  0x0040
++#define MGC_M_CSR0_P_SENDSTALL    0x0020
++#define MGC_M_CSR0_P_SETUPEND     0x0010
++#define MGC_M_CSR0_P_DATAEND      0x0008
++#define MGC_M_CSR0_P_SENTSTALL    0x0004
++#define MGC_M_CSR0_TXPKTRDY       0x0002
++#define MGC_M_CSR0_RXPKTRDY       0x0001
 +
-+#else /* #ifdef MUSB_VIRTHUB */
++/* TXCSR */
 +
-+static int uint8_t MGC_VirtualHubInit(MGC_VirtualHub* pHub, 
-+      struct usb_bus* pBus, uint8_t bPortCount, 
-+      MGC_PortServices* pPortServices) 
-+{ 
-+      DBG(-1, "this should not be called");
-+      return -ENODEV;
-+};
-+static inline void MGC_VirtualHubDestroy(MGC_VirtualHub* pHub) { 
-+      DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubStart(MGC_VirtualHub* pHub) { 
-+      DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubStop(MGC_VirtualHub* pHub) { 
-+      DBG(-1, "this should not be called");
-+};
-+static inline int MGC_VirtualHubSubmitUrb(MGC_VirtualHub* pHub, struct urb* pUrb) { 
-+      DBG(-1, "this should not be called");
-+      return -ENODEV;
-+};
++#define MGC_M_TXCSR_AUTOSET       0x8000
++#define MGC_M_TXCSR_ISO           0x4000
++#define MGC_M_TXCSR_MODE          0x2000
++#define MGC_M_TXCSR_DMAENAB       0x1000
++#define MGC_M_TXCSR_FRCDATATOG    0x0800
++#define MGC_M_TXCSR_P_INCOMPTX    0x0080
++#define MGC_M_TXCSR_CLRDATATOG    0x0040
++#define MGC_M_TXCSR_P_SENTSTALL   0x0020
++#define MGC_M_TXCSR_P_SENDSTALL   0x0010
++#define MGC_M_TXCSR_FLUSHFIFO     0x0008
++#define MGC_M_TXCSR_P_UNDERRUN    0x0004
++#define MGC_M_TXCSR_FIFONOTEMPTY  0x0002
++#define MGC_M_TXCSR_TXPKTRDY      0x0001
 +
-+static inline int MGC_VirtualHubUnlinkUrb(MGC_VirtualHub* pHub, struct urb* pUrb) { 
-+      DBG(-1, "this should not be called");
-+      return -ENODEV;
-+};
++/* RXCSR */
 +
-+static inline void MGC_VirtualHubPortResetDone(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex, uint8_t bHubSpeed) { 
-+      DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubPortConnected(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex, uint8_t bSpeed) { 
-+      DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubPortResumed(MGC_VirtualHub* pHub, 
-+      uint8_t bPortIndex) { 
-+      DBG(-1, "this should not be called");
-+};
-+static inline void MGC_VirtualHubPortDisconnected(MGC_VirtualHub* pHub, 
-+uint8_t bPortIndex) { 
-+      DBG(-1, "this should not be called");
-+};
++#define MGC_M_RXCSR_AUTOCLEAR     0x8000
++#define MGC_M_RXCSR_P_ISO         0x4000
++#define MGC_M_RXCSR_DMAENAB       0x2000
++#define MGC_M_RXCSR_DISNYET       0x1000
++#define MGC_M_RXCSR_DMAMODE       0x0800
++#define MGC_M_RXCSR_INCOMPRX      0x0100
++#define MGC_M_RXCSR_CLRDATATOG    0x0080
++#define MGC_M_RXCSR_P_SENTSTALL   0x0040
++#define MGC_M_RXCSR_P_SENDSTALL   0x0020
++#define MGC_M_RXCSR_FLUSHFIFO     0x0010
++#define MGC_M_RXCSR_DATAERR       0x0008
++#define MGC_M_RXCSR_P_OVERRUN     0x0004
++#define MGC_M_RXCSR_FIFOFULL      0x0002
++#define MGC_M_RXCSR_RXPKTRDY      0x0001
 +
-+#endif
++/*
++ *  register access macros
++ */
 +
++/* Get offset for a given FIFO */
++#define MGC_FIFO_OFFSET(_bEnd) (MGC_M_FIFO_EP0 + (_bEnd * 4))
 +
 +#endif        /* multiple inclusion protection */
-+
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c
---- linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c      2008-09-17 13:23:34.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c
 @@ -0,0 +1,2845 @@
 +/*
 + * linux/drivers/usb/gadget/nomadik_udc.c
@@ -202642,7 +203776,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +
@@ -202683,8 +203817,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +
 +
 +/*
-+ * This driver handles the USB Device Controller (UDC) in Nomadik 
-+ * series processors.  
++ * This driver handles the USB Device Controller (UDC) in Nomadik
++ * series processors.
 + * There are fifteen endpoints, in addition to ep0.
 + *
 + * Such controller drivers work with a gadget driver.  The gadget driver
@@ -202692,7 +203826,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * by the host to interact with this device, and allocates endpoints to
 + * the different protocol interfaces.  The controller driver virtualizes
 + * usb hardware so that the gadget drivers will be more portable.
-+ * 
++ *
 + * This UDC hardware wants to implement a bit too much USB protocol, so
 + * it constrains the sorts of USB configuration change events that work.
 + */
@@ -202706,8 +203840,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + */
 +int udc_complete_request(struct usb_request *req_ptr, int status)
 +{
-+      DBG(4, "<==\n");    
-+    req_ptr->status=status;   
++      DBG(4, "<==\n");
++    req_ptr->status=status;
 +      return complete_request(req_ptr);
 +}
 +
@@ -202735,10 +203869,10 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +int udc_gadget_wakeup(struct usb_gadget *gadget)
 +{
 +    uint8_t power;
-+      
++
 +      u8 *base_addr = ( u8 *)udc_base_addr;
 +    DBG(4, "<==\n" );
-+      
++
 +    power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER);
 +    power |= MUSB_M_POWER_RESUME;
 +    MUSB_WRITE8(base_addr, MUSB_O_HDRC_POWER, power);
@@ -202746,7 +203880,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +}
 +
 +/**
-+ * Current Frame number will be returned 
++ * Current Frame number will be returned
 + * @param gadget the gadget
 + * @return Frame Number
 + */
@@ -202761,7 +203895,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * @param power state
 + * @return Frame Number
 + */
-+int udc_gadget_setselfpowered(struct usb_gadget *gadget, 
++int udc_gadget_setselfpowered(struct usb_gadget *gadget,
 +                                                        int is_selfpowered)
 +{
 +    DBG(4, "<==\n" );
@@ -202774,34 +203908,34 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/**
 + * Complete an usb request.
 + * @param req_ptr the request to complete.
-+ * @return the request status 
++ * @return the request status
 + */
 +int complete_request(struct usb_request *req_ptr)
 +{
 +      uint8_t bEnd;
-+      
++
 +    bEnd=((struct nomadik_req *)req_ptr)->end_number;
-+      
++
 +      if ( req_ptr->complete ) {
 +              req_ptr->complete(&dev_context->end[bEnd].ep,req_ptr);
 +      }
-+      
++
 +      DBG(3, "==> completed on bEnd=%d\n", bEnd);
 +      return req_ptr->status;
-+} 
++}
 +
 +void done(struct nomadik_ep *ep, struct nomadik_req *req, int status)
 +{
 +      unsigned        stopped = ep->stopped;
-+      
++
 +      list_del_init(&req->req.list);
-+      
++
 +      if (req->req.status == -EINPROGRESS)
 +              req->req.status = status;
 +      else
 +              status = req->req.status;
-+      
-+      
++
++
 +      if (use_dma && ep->has_dma)
 +      {
 +              if (req->mapped)
@@ -202823,12 +203957,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                              : DMA_FROM_DEVICE);
 +              }
 +      }
-+      
++
 +#ifndef       USB_TRACE
 +      /*if (status && status != -ESHUTDOWN)*/
 +#endif
-+      
-+      
++
++
 +      /* don't modify queue heads during completion callback */
 +      ep->stopped = 1;
 +      spin_unlock(&ep->udc->lock);
@@ -202848,15 +203982,15 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      struct nomadik_req      *req;
 +      struct usb_request* req1;
 +      ep->stopped = 1;
-+      
++
 +      req1 = udc_current_request(ep);
-+      
++
 +      if (use_dma && ep->dma_channel){
 +              dma_channel_release(ep);
 +      }
-+      
++
 +      use_ep(ep);
-+      
++
 +      while (!list_empty(&ep->req_list))
 +      {
 +              req = (struct nomadik_req*)list_entry(ep->req_list.next, struct usb_request, list);
@@ -202868,7 +204002,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +{
 +      u16     num = EP_NUMBER(ep);
 +      u8 *base_addr = ( u8 *)udc_base_addr;
-+      
++
 +      MUSB_SELECTEND(base_addr, num);
 +}
 +
@@ -202883,9 +204017,9 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      u8 *base_addr = (u8 *)udc_base_addr;
 +      uint16_t  intr_txe = 0;
 +      uint16_t  intr_rxe = 0;
-+      
++
 +      maxp = le16_to_cpu (desc->wMaxPacketSize);
-+      
++
 +#ifdef        USE_ISO
 +      if ((desc->bmAttributes == USB_ENDPOINT_XFER_ISOC
 +              && desc->bInterval != 1)) {
@@ -202900,7 +204034,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              return -EDOM;
 +      }
 +#endif
-+      
++
 +      /* xfer types must match, except that interrupt ~= bulk */
 +      if (ep->bmAttributes != desc->bmAttributes
 +              && ep->bmAttributes != USB_ENDPOINT_XFER_BULK
@@ -202908,29 +204042,29 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              ERR( "%s, %s type mismatch\n", __FUNCTION__, _ep->name);
 +              return -EINVAL;
 +      }
-+      
++
 +      udc = ep->udc;
 +      if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
 +              ERR( "%s, bogus device state\n", __FUNCTION__);
 +              return -ESHUTDOWN;
 +      }
-+      
-+      
++
++
 +      ep->desc = desc;
 +      ep->maxpacket = ep->ep.maxpacket = maxp;
 +      ep->binactive = MUSB_GADGET_EP_ACTIVE;
 +      ep->stopped=0;
-+      
++
 +      if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
 +              list_add(&ep->iso, &udc->iso);
-+      
++
 +      spin_lock_irqsave(&udc->lock, flags);
 +      use_ep(ep);
 +      if ( desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) {
 +              intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE);
 +              intr_txe |= (1 <<bEnd);
 +              MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
-+              
++
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXMAXP, bEnd, desc->wMaxPacketSize);
 +      } else {
 +              intr_rxe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRRXE);
@@ -202938,13 +204072,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRRXE, intr_rxe);
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXMAXP, bEnd, desc->wMaxPacketSize);
 +      }
-+      
++
 +      /* ep size might have been changed, flush the FIFOs */
 +      spin_lock_irqsave(&(dev_context->lock), flags);
 +      intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE);
 +      MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe & ~(1 <<  bEnd));
-+      
-+      
++
++
 +      if(bEnd)
 +      {
 +              uint16_t csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)bEnd);
@@ -202961,18 +204095,18 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              csr |= MUSB_M_RXCSR_FLUSHFIFO;
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)bEnd, csr);
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)bEnd, csr);
-+              
++
 +      }
 +      else {
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, MUSB_M_CSR0_FLUSHFIFO);
 +      }
-+      
++
 +      /* re-enable interrupt */
 +      MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
 +      spin_unlock_irqrestore(&(dev_context->lock), flags);
-+      
++
 +      if(bEnd){
-+              
++
 +              if ( ep->is_tx ){
 +                      /* clear_bulk_in_halt */
 +                      uint16_t  csr= MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
@@ -202981,7 +204115,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      /* reset tx  data toggle */
 +                      csr =MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
 +                      csr |=MUSB_M_TXCSR_CLRDATATOG;
-+                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr);       
++                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr);
 +              }
 +              else{
 +                      /* clear_bulk_out_halt */
@@ -203000,7 +204134,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              csr &= ~MUSB_M_CSR0_P_SENDSTALL;
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0,0, csr);
 +      }
-+      
++
 +      spin_unlock_irqrestore(&udc->lock, flags);
 +      DBG(3,"%s enabled\n", _ep->name);
 +      return 0;
@@ -203013,36 +204147,36 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      u8 *base_addr = ( u8 *)udc_base_addr;
 +      const struct usb_endpoint_descriptor    *desc = (const struct usb_endpoint_descriptor    *)ep->desc;
 +      uint8_t bEnd = EP_NUMBER(ep);
-+      
++
 +      if (!ep || !ep->desc) {
 +              DBG(3, "%s, %s not enabled\n", __FUNCTION__,
 +                      ep ? ep->ep.name : NULL);
 +              return -EINVAL;
 +      }
-+      
-+      
++
++
 +      spin_lock_irqsave(&ep->udc->lock, flags);
-+      
++
 +      if ( desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) {
 +              uint16_t intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE);
 +              intr_txe&= ~(1 <<bEnd);
-+              MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);         
++              MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
 +      } else {
 +              uint16_t intr_rxe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRRXE);
 +              intr_rxe&=~(1 <<bEnd);
 +              MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRRXE, intr_rxe);
 +      }
-+      
++
 +      spin_unlock_irqrestore(&ep->udc->lock, flags);
 +      ep->desc = NULL;
 +      nuke (ep, -ESHUTDOWN);
 +      ep->ep.maxpacket = ep->maxpacket;
 +      ep->binactive = MUSB_GADGET_EP_DISABLED;
-+      
++
 +      if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
 +              list_del_init(&ep->iso);
-+      
-+      
++
++
 +      DBG(4,"%s disabled\n", _ep->name);
 +      return 0;
 +}
@@ -203053,8 +204187,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +nomadik_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
 +{
 +      struct nomadik_req      *req;
-+      
-+      
++
++
 +      req = (struct nomadik_req *)kzalloc(sizeof *req, gfp_flags);
 +      DBG(4, "==> allocated request at %p for ep %d\n", req, \
 +              EP_NUMBER(ep));
@@ -203062,7 +204196,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              req->req.dma = DMA_ADDR_INVALID;
 +              INIT_LIST_HEAD(&req->req.list);
 +              req->end_number = EP_NUMBER(ep);
-+              
++
 +      }
 +      return &req->req;
 +}
@@ -203071,7 +204205,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +nomadik_free_request(struct usb_ep *ep, struct usb_request *_req)
 +{
 +      struct nomadik_req      *req = container_of(_req, struct nomadik_req, req);
-+      
++
 +      if (_req)
 +              kfree (req);
 +}
@@ -203088,7 +204222,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +{
 +      void            *retval;
 +      struct nomadik_ep       *ep;
-+      
++
 +      ep = container_of(_ep, struct nomadik_ep, ep);
 +      if (use_dma && ep->has_dma) {
 +              static int      warned;
@@ -203101,7 +204235,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              return dma_alloc_coherent(ep->udc->gadget.dev.parent,
 +                      bytes, dma, gfp_flags);
 +      }
-+      
++
 +      retval = kmalloc(bytes, gfp_flags);
 +      if (retval)
 +              *dma = virt_to_phys(retval);
@@ -203116,7 +204250,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                                               )
 +{
 +      struct nomadik_ep       *ep;
-+      
++
 +      ep = container_of(_ep, struct nomadik_ep, ep);
 +      if (use_dma && _ep && ep->has_dma)
 +              dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma);
@@ -203129,38 +204263,38 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/*-------------------------------------------------------------------------*/
 +
 +int queue_length(struct list_head *lh) {
-+      int count=0;    
++      int count=0;
 +      struct list_head *p=lh;
-+      
++
 +      while ( p && (p->next!=lh) ) {
 +              count++;
 +              p=p->next;
 +      }
-+      
++
 +      return count;
 +}
 +
 +
 +
 +
-+char* dump_usb_request(struct usb_request *req) {    
++char* dump_usb_request(struct usb_request *req) {
 +    static char buff[256];
 +      if ( req ) {
 +              sprintf(buff, "req=%p, req->request.length=0x%0x, req->request.zero=0x%x, "
-+                      "req->request.actual=0x%x, req->request.status=%d", 
++                      "req->request.actual=0x%x, req->request.status=%d",
 +                      req, req->length, req->zero, req->actual, req->status );
 +      } else {
-+              sprintf(buff, "null request");          
++              sprintf(buff, "null request");
 +      }
-+      
++
 +    return buff;
 +}
 +
 +/**
 + * Set clear the halt bit of an endpoint. A halted enpoint won't tx/rx any
-+ * data but will queue requests. 
++ * data but will queue requests.
 + * @param ep the endpoint
-+ * @param value != 0 => halt, 0 == active  
++ * @param value != 0 => halt, 0 == active
 + */
 +int nomadik_ep_set_halt(struct usb_ep *_ep, int value)
 +{
@@ -203170,9 +204304,9 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    const uint8_t bEnd=EP_NUMBER(ep);
 +      u8 *base_addr = ( u8 *)udc_base_addr;
 +    struct nomadik_req *req_ptr;
-+      
++
 +    DBG(4, "<== end=%d, value=%d\n", bEnd, value);
-+    
++
 +    spin_lock_irqsave(&dev_context->lock, flags);
 +    MUSB_SELECTEND(base_addr, bEnd );
 +    if ( 0==bEnd )
@@ -203186,45 +204320,45 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              {
 +                      csr &= ~MUSB_M_CSR0_P_SENDSTALL;
 +              }
-+              
-+              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csr);        
++
++              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csr);
 +              spin_unlock_irqrestore(&dev_context->lock, flags );
 +              return 0;
 +      }
-+      
++
 +    /* prevent further request to be executed, this will prevent next
-+       * request to be scheduled oin the completiotion of the current 
++       * request to be scheduled oin the completiotion of the current
 +       * one
-+       */    
++       */
 +    ep->binactive=(value)
-+              ? MUSB_GADGET_EP_HALTED 
++              ? MUSB_GADGET_EP_HALTED
 +              : MUSB_GADGET_EP_ACTIVE;
-+      
++
 +      if ( value )
 +              DBG(4, "<== end halted=%d\n", bEnd);
 +      else
 +              DBG(4, "<== end activated=%d,d\n", bEnd);
-+      
-+    /* cannot abort the current request if the FIFO is full */    
-+    req_ptr=(struct nomadik_req*)udc_current_request(ep);    
++
++    /* cannot abort the current request if the FIFO is full */
++    req_ptr=(struct nomadik_req*)udc_current_request(ep);
 +    if ( value && ep->is_tx )
-+      {    
++      {
 +              csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
 +              if ( csr & MUSB_M_TXCSR_FIFONOTEMPTY ) {
-+                      spin_unlock_irqrestore(&dev_context->lock, flags);    
-+                      return -EAGAIN;    
++                      spin_unlock_irqrestore(&dev_context->lock, flags);
++                      return -EAGAIN;
 +              }
-+              
++
 +      }
 +      /* set/clear the stall bit */
 +    if ( ep->is_tx )
-+      {    
++      {
 +              if ( value )
 +              {
 +                      csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
 +                      csr |= MUSB_M_TXCSR_P_SENDSTALL;
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr)
-+              } 
++              }
 +              else
 +              {
 +                      csr= MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
@@ -203235,16 +204369,16 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      csr |=MUSB_M_TXCSR_CLRDATATOG;
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csr);
 +              }
-+              
++
 +      }
-+      else 
++      else
 +      {
 +              if( value )
 +              {
 +                      csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd);
 +                      csr |= MUSB_M_RXCSR_P_SENDSTALL;
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr);
-+                      
++
 +              }
 +              else
 +              {
@@ -203256,20 +204390,20 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      csr |=MUSB_M_RXCSR_CLRDATATOG;
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csr);
 +              }
-+              
++
 +      }
-+      
++
 +    spin_unlock_irqrestore(&dev_context->lock, flags);
-+      
-+      /* the ep has been re-activated, re-start the request if one 
++
++      /* the ep has been re-activated, re-start the request if one
 +      * is pending*/
 +    if ( !value  && req_ptr )
 +      {
 +              DBG(3, "restarting the request\n");
-+              udc_restart_request(dev_context, (struct usb_request*)req_ptr); 
++              udc_restart_request(dev_context, (struct usb_request*)req_ptr);
 +      }
-+      
-+    DBG(4, "==>\n" );    
++
++    DBG(4, "==>\n" );
 +    return 0;
 +}
 +
@@ -203291,14 +204425,14 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              ERR("Error in allocating private /*struct*/ure dev_context\n");
 +              return -ENOMEM;
 +      }
-+      
++
 +      dev_context->end0_buffer_ptr = kzalloc(sizeof(struct t_udc_end0_buffer), GFP_KERNEL);
 +      if ( !dev_context->end0_buffer_ptr ){
 +              kfree(dev_context);
 +              ERR("Error in allocating end0 buffer\n");
 +              return -ENOMEM;
 +      }
-+      
++
 +      spin_lock_init(&dev_context->lock);
 +      return 0;
 +}
@@ -203317,12 +204451,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      u16     epn_rxtx = 0;
 +      u8 ep_index =  dev_context->end_count;
 +      u8 *base_addr = (u8 *)udc_base_addr;
-+      
++
 +      dev_context->end_count++;
 +      dev_context->end_mask |= 1 << ep_index;
 +      ep = &dev_context->end[ep_index];
 +      MUSB_SELECTEND(base_addr, ep_index);
-+      
++
 +      /* chip setup ... bit values are same for IN, OUT */
 +      switch (maxp) {
 +      case 8:         epn_rxtx = 0 ; break;
@@ -203338,16 +204472,16 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              DBG(3, "dbe enabled for %d\n",ep_index);
 +              epn_rxtx |= 0x10;
 +      }
-+      
++
 +#if 0
 +      init_timer(&ep->timer);
 +      ep->timer.function = pio_out_timer;
 +      ep->timer.data = (unsigned long) ep;
 +#endif
-+      
++
 +      DBG(3, "%s addr %02x rxtx %04x maxp %d%s buf %d\n",
 +              name, dir, epn_rxtx, maxp, dbuf ? "x2" : "", buf);
-+      
++
 +      if ( ep_index) {
 +              if (dir & USB_DIR_IN)
 +              {
@@ -203362,13 +204496,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      ep->is_tx = 0;
 +              }
 +      }
-+      
++
 +      /* next endpoint's buffer starts after this one's */
 +      buf += maxp;
 +      if (dbuf)
 +              buf += maxp;
 +      BUG_ON(buf > 2048);
-+      
++
 +      /* set up driver data structures */
 +      BUG_ON(strlen(name) >= sizeof ep->name);
 +      strlcpy(ep->name, name, sizeof ep->name);
@@ -203377,56 +204511,56 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      ep->end_number = ep_index;
 +      ep->bmAttributes = type;
 +      ep->double_buf = dbuf;
-+      ep->udc = dev_context; 
++      ep->udc = dev_context;
 +      ep->has_dma = 0;
-+      
++
 +      ep->ep.name = ep->name;
 +      ep->ep.ops = &nomadik_ep_ops;
 +      ep->ep.maxpacket = ep->maxpacket = maxp;
 +      list_add_tail (&ep->ep.ep_list, &dev_context->gadget.ep_list);
 +      ep->binactive = MUSB_GADGET_EP_DISABLED;
-+      
++
 +      return buf;
 +}
 +
 +void nomadik_udc_release(struct device *dev)
 +{
-+      complete(dev_context->done); 
++      complete(dev_context->done);
 +      kfree (dev_context);
 +      dev_context = NULL;
 +}
 +
 +
-+int __init udc_setup(void) 
++int __init udc_setup(void)
 +{
-+      unsigned buf; 
-+      
++      unsigned buf;
++
 +      spin_lock_init( &udc_scheduler_queue.lock );
 +      INIT_LIST_HEAD( &udc_scheduler_queue.req_list );
-+      
++
 +      INIT_LIST_HEAD(&dev_context->iso);
-+      
++
 +      dev_context->gadget.ops = &nomadik_gadget_ops;
 +      dev_context->gadget.ep0 = &dev_context->end[0].ep;
 +      INIT_LIST_HEAD(&dev_context->gadget.ep_list);
 +      dev_context->gadget.speed = USB_SPEED_UNKNOWN;
 +      dev_context->gadget.name = driver_name;
-+      
++
 +      device_initialize(&dev_context->gadget.dev);
 +      strcpy (dev_context->gadget.dev.bus_id, "gadget");
 +      dev_context->gadget.dev.release = nomadik_udc_release;
 +      dev_context->gadget.dev.parent = NULL;
-+      
++
 +      dev_context->end_count = 0;
 +      dev_context->end_mask = 0;
-+      /* 
-+         ep0 is special; put it right after the SETUP buffer 
++      /*
++         ep0 is special; put it right after the SETUP buffer
 +      */
 +      buf = nomadik_ep_setup("ep0",0,  USB_ENDPOINT_XFER_CONTROL,
 +              0 /* after SETUP */, 64 /* maxpacket */, 0);
 +      list_del_init(&dev_context->end[0].ep.ep_list);
-+      
-+      
++
++
 +#define NOMADIK_BULK_EP(name,dir) \
 +      buf = nomadik_ep_setup(name "-bulk", dir, \
 +      USB_ENDPOINT_XFER_BULK, buf,512, 0);
@@ -203436,7 +204570,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +#define NOMADIK_ISO_EP(name,dir, maxp) \
 +      buf = nomadik_ep_setup(name "-iso", dir, \
 +      USB_ENDPOINT_XFER_ISOC, buf, maxp, 0);
-+      
++
 +      switch (fifo_mode) {
 +      case 0:
 +              NOMADIK_BULK_EP("ep1in",  USB_DIR_IN  );
@@ -203447,43 +204581,43 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              NOMADIK_BULK_EP("ep1in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep2out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep9in",   USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep3in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep4out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep10in",  USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep5in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep5out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep11in",  USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep6in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep6out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep12in",  USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep7in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep7out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep13in",  USB_DIR_IN  , 16);
 +              NOMADIK_INT_EP("ep13out", USB_DIR_OUT , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep8in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep8out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep14in",  USB_DIR_IN  , 16);
 +              NOMADIK_INT_EP("ep14out", USB_DIR_OUT , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep15in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep15out", USB_DIR_OUT );
-+              
++
 +              break;
-+              
++
 +#ifdef        USE_ISO
-+      case 2:                 /* mixed iso/bulk */ 
++      case 2:                 /* mixed iso/bulk */
 +              NOMADIK_ISO_EP("ep1in",   USB_DIR_IN  , 256);
 +              NOMADIK_ISO_EP("ep2out",  USB_DIR_OUT , 256);
 +              NOMADIK_ISO_EP("ep3in",   USB_DIR_IN  , 128);
 +              NOMADIK_ISO_EP("ep4out",  USB_DIR_OUT , 128);
-+              
++
 +              NOMADIK_INT_EP("ep5in",   USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep6in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep7out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep8in",   USB_DIR_IN  , 16);
@@ -203492,19 +204626,19 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              NOMADIK_BULK_EP("ep1in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep2out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep3in",   USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_BULK_EP("ep4in",  USB_DIR_IN  );
 +              NOMADIK_BULK_EP("ep5out", USB_DIR_OUT );
 +              NOMADIK_INT_EP("ep6in",   USB_DIR_IN  , 16);
-+              
++
 +              NOMADIK_ISO_EP("ep7in",   USB_DIR_IN  , 256);
 +              NOMADIK_ISO_EP("ep8out",  USB_DIR_OUT , 256);
 +              NOMADIK_INT_EP("ep9in",   USB_DIR_IN  , 16);
 +              break;
 +#endif
-+              
++
 +              /* add more modes as needed */
-+              
++
 +      default:
 +              ERR("unsupported fifo_mode #%d\n", fifo_mode);
 +              return -ENODEV;
@@ -203516,25 +204650,25 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +{
 +      u8 *base_addr = ( u8 *)udc_base_addr;
 +      DBG(4,"\n");
-+      
++
 +      MUSB_WRITE8(base_addr, MUSB_O_HDRC_INTRUSBE, 0x0);
 +      MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, 0x0);
 +      MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRRXE, 0x0);
 +}
 +
 +
-+void udc_reset() 
++void udc_reset()
 +{
 +      volatile u8 *base_addr = ( u8 *)udc_base_addr;
 +      uint8_t power;
 +      uint16_t top;
-+      
-+      
++
++
 +      MUSB_WRITE16(base_addr, MUSB_O_HDRC_TOPCONTROL, MUSB_MODE_ULPI);
 +      top =  MUSB_READ16(base_addr, MUSB_O_HDRC_TOPCONTROL);
-+      
++
 +      MUSB_WRITE16(base_addr, MUSB_O_HDRC_TOPCONTROL,( top | MUSB_MODE_SRST));
-+      
++
 +      power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER);
 +      /* Enabling high speed */
 +      power = power |(MUSB_M_POWER_HSENAB);
@@ -203547,8 +204681,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/**
 + * Identifies a transmit request.
 + * @param control_request_ptr the control request
-+ * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE, 
-+ *            USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME 
++ * @return true for USB_REQ_GET_CONFIGURATION, USB_REQ_GET_INTERFACE,
++ *            USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, USB_REQ_SYNC_FRAME
 + */
 +uint8_t is_tx_request(const struct usb_ctrlrequest *control_request_ptr) {
 +    return ( control_request_ptr->bRequestType & USB_DIR_IN );
@@ -203557,10 +204691,10 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/**
 + * Identifies a zero data request.
 + * @param control_request_ptr the control request
-+ * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION, 
++ * @return true for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
 + *    USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
-+ * 
-+ */ 
++ *
++ */
 +uint8_t is_zerodata_request(const struct usb_ctrlrequest *control_request_ptr) {
 +    return ( 0==control_request_ptr->wLength ) && !is_tx_request(control_request_ptr);
 +}
@@ -203568,8 +204702,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/**
 + * Identifies a receive request.
 + * @param control_request_ptr the control request
-+ * @return true for USB_REQ_SET_DESCRIPTOR  
-+ */ 
++ * @return true for USB_REQ_SET_DESCRIPTOR
++ */
 +uint8_t is_rx_request(const struct usb_ctrlrequest *control_request_ptr) {
 +    return control_request_ptr->bRequest==USB_REQ_SET_DESCRIPTOR;
 +}
@@ -203582,7 +204716,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * @param wcount how many bytes to load
 + * @param pSource data buffer
 + */
-+void udc_load_fifo(const uint8_t* base_ptr, uint8_t bEnd, 
++void udc_load_fifo(const uint8_t* base_ptr, uint8_t bEnd,
 +                                 uint16_t wcount, const uint8_t* pSource)
 +{
 +    uint16_t windex, windex32;
@@ -203590,7 +204724,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    uint8_t fifo_offset = MUSB_FIFO_OFFSET(bEnd);
 +    DBG(3, "base_ptr=%p, bEnd=%d, wcount=0x%04x, pSrc=%p\n",
 +              base_ptr, bEnd, wcount, pSource);
-+      
++
 +#ifdef MUSB_PARANOID
 +      if ( IS_INVALID_ADDRESS(pSource) )
 +      {
@@ -203598,18 +204732,18 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              return;
 +      }
 +#endif
-+      
-+      
-+    for(windex =0, windex32 = 0; windex32 < wcount32; windex32++, windex += 4) 
++
++
++    for(windex =0, windex32 = 0; windex32 < wcount32; windex32++, windex += 4)
 +      {
 +        MUSB_WRITE32(base_ptr, fifo_offset, *((uint32_t*)&(pSource[windex])));
 +      }
-+      
-+    for(; windex < wcount; windex++) 
++
++    for(; windex < wcount; windex++)
 +      {
 +        MUSB_WRITE8(base_ptr, fifo_offset, pSource[windex]);
 +      }
-+      
++
 +}
 +
 +/**
@@ -203620,29 +204754,29 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * @param wcount how many bytes to unload
 + * @param dest_ptr data buffer
 + */
-+void udc_unload_fifo(const uint8_t* base_ptr, uint8_t bEnd, 
++void udc_unload_fifo(const uint8_t* base_ptr, uint8_t bEnd,
 +                                       uint16_t wcount, uint8_t* dest_ptr)
 +{
 +    uint16_t windex=0;
 +    uint16_t windex32=0;
 +    uint16_t wcount32 = wcount >> 2;
 +      uint8_t fifo_offset = MUSB_FIFO_OFFSET(bEnd);
-+      
-+      
++
++
 +#ifdef MUSB_PARANOID
 +      if ( IS_INVALID_ADDRESS(dest_ptr) ) {
 +              ERR("unloading fifo from a null buffer\n");
 +              return;
 +      }
 +#endif
-+      
++
 +    DBG(3, "base_ptr=%p, bEnd=%d, wcount=0x%04x, dest_ptr=%p\n", base_ptr, bEnd,
 +              wcount, dest_ptr);
-+      
++
 +    for(windex = 0, windex32 = 0; windex32 < wcount32; windex32++, windex += 4) {
 +              *((uint32_t*)&(dest_ptr[windex])) = MUSB_READ32(base_ptr, fifo_offset);
 +    }
-+    
++
 +    while(windex < wcount) {
 +              dest_ptr[windex++]=MUSB_READ8(base_ptr, fifo_offset);
 +    }
@@ -203653,7 +204787,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +
 +/**
 + * Forward a request to the driver.
-+ *  
++ *
 + * FROM: usb_gadget.h
 + * Accordingly, the driver's setup() callback must always implement all
 + * get_descriptor requests, returning at least a device descriptor and
@@ -203668,28 +204802,28 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + *
 + * @param control_request_ptr the usb control request to forward to the driver
 + */
-+int forward_to_driver(const struct usb_ctrlrequest *control_request_ptr) 
++int forward_to_driver(const struct usb_ctrlrequest *control_request_ptr)
 +{
 +    int handled=-EOPNOTSUPP;
-+    DBG(3, "<== dev_context->driver=%p, control_request_ptr=%p\n", 
-+              dev_context->driver, control_request_ptr);      
-+    
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); 
-+#endif
-+      
++    DBG(3, "<== dev_context->driver=%p, control_request_ptr=%p\n",
++              dev_context->driver, control_request_ptr);
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]);
++#endif
++
 +    if ( dev_context->driver ){
 +              DBG(1, "calling mrt_setup\n");
-+              handled=dev_context->driver->setup(&dev_context->gadget, 
-+                      control_request_ptr);    
++              handled=dev_context->driver->setup(&dev_context->gadget,
++                      control_request_ptr);
 +    }
 +    else
 +    {
 +              ERR("Error case\n");
 +      }
-+      
-+    DBG(4, "==> handled=%d\n", handled);      
++
++    DBG(4, "==> handled=%d\n", handled);
 +    return handled;
 +}
 +
@@ -203700,11 +204834,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * @param control_request_ptr the usb control request to service.
 + * @see is_rx_request
 + */
-+int service_rx_request(struct usb_ctrlrequest *control_request_ptr) 
++int service_rx_request(struct usb_ctrlrequest *control_request_ptr)
 +{
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); 
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]);
 +#endif
 +    return forward_to_driver(control_request_ptr);
 +}
@@ -203719,38 +204853,38 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    uint8_t bResult[2], bEnd=0;
 +      uint16_t csrval;
 +    const uint8_t* base_addr = (uint8_t*)udc_base_addr;
-+    const uint8_t bRecip=control_request_ptr->bRequestType 
++    const uint8_t bRecip=control_request_ptr->bRequestType
 +              & USB_RECIP_MASK;
-+      
++
 +      /* ack the request */
 +      DBG(3, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) );
 +      spin_lock(&dev_context->lock);
 +      MUSB_SELECTEND(base_addr, 0);
-+      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
++      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
 +              MUSB_M_CSR0_P_SVDRXPKTRDY);
 +      spin_unlock(&dev_context->lock);
-+      
-+    switch(bRecip) {  
-+      case USB_RECIP_DEVICE:          
-+              DBG(1, "USB_RECIP_DEVICE()\n");             
++
++    switch(bRecip) {
++      case USB_RECIP_DEVICE:
++              DBG(1, "USB_RECIP_DEVICE()\n");
 +              bResult[0] = dev_context->is_selfpowered ? 1 : 0;
 +              bResult[0] |= 2;
-+              bResult[1] = 0;     
++              bResult[1] = 0;
 +              udc_load_fifo(base_addr, 0, 2, (uint8_t*)&bResult);
 +              csrval = MUSB_M_CSR0_TXPKTRDY | MUSB_M_CSR0_P_DATAEND;
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
 +              break;
-+              
++
 +      case USB_RECIP_ENDPOINT:
 +              {
 +                      uint16_t wTest;
-+                      
++
 +                      DBG(1, "USB_RECIP_ENDPOINT()\n");
 +                      bEnd = (uint8_t)control_request_ptr->wIndex;
 +                      spin_lock(&dev_context->lock);
 +                      MUSB_SELECTEND(base_addr, bEnd);
 +                      /* in EP */
-+                      if(bEnd & 0x80) 
++                      if(bEnd & 0x80)
 +                      {
 +                              wTest = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
 +                              bResult[0] = (wTest & MUSB_M_TXCSR_P_SENDSTALL) ? 1 : 0;
@@ -203760,7 +204894,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                              wTest = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd);
 +                              bResult[0] = (wTest & MUSB_M_RXCSR_P_SENDSTALL) ? 1 : 0;
 +                      }
-+                      
++
 +                      MUSB_SELECTEND(base_addr, 0);
 +                      bResult[1] = 0;
 +                      udc_load_fifo(base_addr, 0, 2, (uint8_t*)&bResult);
@@ -203768,46 +204902,46 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
 +                      spin_unlock(&dev_context->lock);
 +              } break;
-+              
++
 +      default:
 +              handled=0;
 +              break;
 +    }
-+      
-+    /* send it out! (this will trigger the ep0 completition IRQ) 
-+       * serviced in interrupt_complete()  
++
++    /* send it out! (this will trigger the ep0 completition IRQ)
++       * serviced in interrupt_complete()
 +       */
 +    if ( handled ) {
 +              dev_context->end0_stage=MUSB_END0_STAGE_STATUSOUT;
-+              
++
 +              spin_lock(&dev_context->lock);
 +              MUSB_SELECTEND(base_addr, bEnd);
-+              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
++              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
 +                      MUSB_M_CSR0_TXPKTRDY | MUSB_M_CSR0_P_DATAEND);
 +              spin_unlock(&dev_context->lock);
 +    }
 +}
 +
 +/**
-+ * Service a transmit a request. End0 buffer contains the current 
-+ * request (a standard control request). Assumes the fifo to be at least 
-+ * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION, 
-+ * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS, 
++ * Service a transmit a request. End0 buffer contains the current
++ * request (a standard control request). Assumes the fifo to be at least
++ * bytes long. Requests handled here are: USB_REQ_GET_CONFIGURATION,
++ * USB_REQ_GET_INTERFACE, USB_REQ_GET_DESCRIPTOR, USB_REQ_GET_STATUS,
 + * USB_REQ_SYNC_FRAME.
 + *
 + * @param control_request_ptr the request to service
-+ * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not 
-+ * supprorted), > 0 when the request is processed 
++ * @return 0 if the request was NOT HANDLED, < 0 when error (ENOSUPP not
++ * supprorted), > 0 when the request is processed
 + * @see is_tx_request
 + */
-+int service_tx_request(const struct usb_ctrlrequest *control_request_ptr) 
++int service_tx_request(const struct usb_ctrlrequest *control_request_ptr)
 +{
 +    int handled=0; /* not handled */
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); 
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]);
 +#endif
-+      
++
 +    if ( USB_TYPE_STANDARD!=(control_request_ptr->bRequestType&USB_TYPE_MASK )) {
 +              return forward_to_driver(control_request_ptr);
 +    }
@@ -203815,95 +204949,95 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      case USB_REQ_GET_CONFIGURATION:
 +              DBG(1, "USB_REQ_GET_CONFIGURATION()\n");
 +              break;
-+              
++
 +      case USB_REQ_GET_INTERFACE:
 +              DBG(1, "USB_REQ_GET_INTERFACE()\n");
 +              break;
-+              
++
 +      case USB_REQ_GET_DESCRIPTOR:
 +              DBG(1, "USB_REQ_GET_DESCRIPTOR()\n");
 +              break;
-+              
++
 +      case USB_REQ_GET_STATUS: {
 +              DBG(1, "USB_REQ_GET_STATUS()\n");
 +              service_tx_status_request(control_request_ptr);
 +              handled = 1;
 +                                                       } break;
-+              
++
 +/* case USB_REQ_SYNC_FRAME:
 +              break; */
-+              
-+      default: 
++
++      default:
 +              break;
 +    }
-+      
++
 +    if ( !handled ) {
 +              handled=forward_to_driver(control_request_ptr);
 +    }
-+      
++
 +      /* now tx! */
 +    return handled;
 +}
 +
 +/**
-+ * Service a zero data request. 
++ * Service a zero data request.
 + * Called for USB_REQ_SET_INTERFACE, USB_REQ_SET_CONFIGURATION,
 + * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE.
-+ *  
++ *
 + * @param dev_context the controller instance
 + * @param control_request_ptr the control request to service.
 + * @warning USB_REQ_SET_ADDRESS should be executed QUICKLY
 + * @see is_zerodata_request
 + */
-+int service_zero_data_request(struct nomadik_udc* dev_context, 
-+                                                        struct usb_ctrlrequest *control_request_ptr) 
++int service_zero_data_request(struct nomadik_udc* dev_context,
++                                                        struct usb_ctrlrequest *control_request_ptr)
 +{
-+      
++
 +    int handled=1; /* handled, DO NOT not pass down */
 +    const uint8_t* base_addr = (uint8_t*)udc_base_addr;
-+    const uint8_t bRecip=control_request_ptr->bRequestType 
++    const uint8_t bRecip=control_request_ptr->bRequestType
 +              & USB_RECIP_MASK;
-+      
++
 +    DBG(4, "<==\n");
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]); 
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->end[0]);
 +#endif
-+      
++
 +    /* non standard requests are piped to the gadget */
 +    if ( USB_TYPE_STANDARD!=(control_request_ptr->bRequestType&USB_TYPE_MASK )) {
 +              return forward_to_driver(control_request_ptr);
 +    }
-+    
-+    /* zero data phase */     
++
++    /* zero data phase */
 +    switch (control_request_ptr->bRequest) {
-+              
++
 +      case USB_REQ_SET_INTERFACE:
 +              DBG(1, "USB_REQ_SET_INTERFACE()\n");
 +              handled=0; /* pass it to the gadget */
-+              break;       
-+              
++              break;
++
 +      case USB_REQ_SET_CONFIGURATION:
-+              
++
 +              /* remember state & handle on the end status stage interrupt */
 +              DBG(1, "USB_REQ_SET_CONFIGURATION()\n");
 +              dev_context->set_config_flag = 1;
 +              handled=0; /* pass it to the gadget */
 +              break;
-+              
++
 +      case USB_REQ_SET_ADDRESS:
 +              /* remember state & handle on the end status stage interrupt */
 +              DBG(1, "USB_REQ_SET_ADDRESS(0x%x)\n",(uint8_t)
 +                      (control_request_ptr->wValue & 0x7f));
-+              
++
 +              dev_context->set_address_flag = 1;
 +              dev_context->address = (uint8_t)(control_request_ptr->wValue & 0x7f);
 +              break;
-+              
++
 +      case USB_REQ_CLEAR_FEATURE:
 +              DBG(1, "USB_REQ_CLEAR_FEATURE()\n");
-+              
++
 +              switch(bRecip) {
 +              case USB_RECIP_DEVICE:
 +                      DBG(3, "USB_RECIP_DEVICE()\n");
@@ -203915,19 +205049,19 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      {
 +                              const uint8_t bEnd = (uint8_t)control_request_ptr->wIndex & 0x7f ;
 +                              struct nomadik_ep* end_ptr=&dev_context->end[ bEnd ];
-+                              
-+                              DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );                     
++
++                              DBG(-1, "CLEAR_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );
 +                              nomadik_ep_set_halt( &end_ptr->ep, 0);
 +                              /* select ep0 again */
-+                              MUSB_SELECTEND(base_addr, 0);                   
++                              MUSB_SELECTEND(base_addr, 0);
 +                      } break;
 +              default:
-+                      break;          
++                      break;
 +              }
 +              break; /* END: CLEAR_FEATURE */
-+              
++
 +              case USB_REQ_SET_FEATURE:
-+                      DBG(3, "USB_REQ_SET_FEATURE()\n");              
++                      DBG(3, "USB_REQ_SET_FEATURE()\n");
 +                      switch(bRecip) {
 +                      case USB_RECIP_DEVICE:
 +                              DBG(3, "USB_RECIP_DEVICE()\n");
@@ -203941,7 +205075,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                                              handled=-EINVAL;
 +                                      } else {
 +                                              uint16_t wTest;
-+                                              
++
 +                                              DBG(3, "ENTERING TESTMODE\n");
 +                                              dev_context->test_mode_flag = 1;
 +                                              wTest = (uint8_t)control_request_ptr->wIndex >> 8;
@@ -203980,39 +205114,39 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                                      break;
 +                              case 5:
 +                                      break;
-+                                      
++
 +                              }
 +                              break;
-+                              
++
 +                              case USB_RECIP_INTERFACE:
 +                                      DBG(3, "USB_RECIP_INTERFACE()\n");
 +                                      break;
-+                                      
++
 +                              case USB_RECIP_ENDPOINT:
 +                                      {
 +                                              const uint8_t bEnd = (uint8_t)control_request_ptr->wIndex & 0x7f ;
 +                                              struct nomadik_ep* end_ptr=&dev_context->end[ bEnd ];
-+                                              
-+                                              DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );                        
++
++                                              DBG(3, "SET_FEATURE: USB_RECIP_ENDPOINT() %d\n", bEnd );
 +                                              nomadik_ep_set_halt(&end_ptr->ep, 1);
-+                                              
++
 +                                              /* select ep0 again */
 +                                              MUSB_SELECTEND(base_addr, 0);
 +                                      } break;
-+                                      
++
 +                      }
 +                      break; /* END: SET_FEATURE */
-+                      
++
 +                      default:
 +                              handled=0;
 +                              break;
 +    }
-+      
++
 +    /* standard request not handed by this code go to the gadget */
 +    if ( !handled ) {
 +              handled=forward_to_driver(control_request_ptr);
 +    }
-+      
++
 +    DBG(4, "==>\n");
 +    return handled;
 +}
@@ -204024,85 +205158,85 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * IRQ on ep0 has occourred.
 + * @warning Executed @ interrupt time; complete CANNOT sleep.
 + */
-+void mgc_complete_ep0_request(void) 
++void mgc_complete_ep0_request(void)
 +{
 +      struct usb_request *reqptr;
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_LOCKED(&dev_context->end[0]); 
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_LOCKED(&dev_context->end[0]);
 +#endif
-+      
++
 +      spin_lock( &dev_context->end[0].lock );
 +      reqptr=udc_current_request( &dev_context->end[0] );
-+      
++
 +      /* this is interrupt code, it cannot sleep! */
 +      if ( reqptr ) {
-+              list_del( &reqptr->list );      
-+              INIT_LIST_HEAD( &dev_context->end[0].req_list );        
-+              
++              list_del( &reqptr->list );
++              INIT_LIST_HEAD( &dev_context->end[0].req_list );
++
 +              spin_unlock( &dev_context->end[0].lock );
 +              if ( reqptr->complete ) {
-+                      reqptr->complete(&dev_context->end[0].ep, 
++                      reqptr->complete(&dev_context->end[0].ep,
 +                              reqptr);
 +              }
 +      } else {
 +              spin_unlock( &dev_context->end[0].lock );
 +      }
-+      
++
 +      dev_context->end0_stage = MUSB_END0_STAGE_SETUP;
 +}
 +
 +/**
-+ * handle the completition interrupt on endpoint 0. 
++ * handle the completition interrupt on endpoint 0.
 + */
-+void handle_ep0_completition_irq(void) 
++void handle_ep0_completition_irq(void)
 +{
 +      const uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +      struct nomadik_ep* end_ptr = &(dev_context->end[0]);
 +      struct usb_request *reqptr=udc_current_request(end_ptr);
-+      
++
 +      DBG(3, "<==\n");
-+      DBG(4, "post event interrupts ep0stage=%s\n", 
++      DBG(4, "post event interrupts ep0stage=%s\n",
 +              decode_ep0stage(dev_context->end0_stage));
-+      switch (dev_context->end0_stage) {      
-+              
++      switch (dev_context->end0_stage) {
++
 +              /* end of sequence #2 (RX state) or #3 (no data) */
-+      case MUSB_END0_STAGE_STATUSIN:      
++      case MUSB_END0_STAGE_STATUSIN:
 +              DBG(3, "MUSB_END0_STAGE_STATUSIN request\n");
-+              
-+              /* update address (if needed) only @ the end of the 
++
++              /* update address (if needed) only @ the end of the
 +               * status phase per standard. The guide is WRONG!
 +               */
-+              if(dev_context->set_address_flag) {         
++              if(dev_context->set_address_flag) {
 +                      dev_context->set_address_flag = 0;
-+                      MUSB_WRITE8(base_addr, MUSB_O_HDRC_FADDR, dev_context->address);                
++                      MUSB_WRITE8(base_addr, MUSB_O_HDRC_FADDR, dev_context->address);
 +              }
-+              
++
 +              /* enter test mode if needed */
 +              if(dev_context->test_mode_flag) {
 +                      DBG(3, "entering TESTMODE\n");
 +                      if (MUSB_M_TEST_PACKET == dev_context->test_mode_value) {
-+                              udc_load_fifo(base_addr, 0, sizeof(musb_test_pkt), 
++                              udc_load_fifo(base_addr, 0, sizeof(musb_test_pkt),
 +                                      musb_test_pkt);
 +                      }
-+                      
++
 +                      spin_lock(&dev_context->lock);
 +                      MUSB_SELECTEND(base_addr, 0); /* select ep0 */
-+                      MUSB_WRITE8(base_addr, MUSB_O_HDRC_TESTMODE, 
++                      MUSB_WRITE8(base_addr, MUSB_O_HDRC_TESTMODE,
 +                              dev_context->test_mode_value);
 +                      spin_unlock(&dev_context->lock);
-+              }           
-+              
++              }
++
 +              DBG(2, "completing posted request (if any)\n");
 +              mgc_complete_ep0_request();
 +              break;
-+              
++
 +              /* sequence #1: write to host (TX state)  */
 +      case MUSB_END0_STAGE_STATUSOUT:
-+              DBG(2, "completing posted request (if any)\n");     
++              DBG(2, "completing posted request (if any)\n");
 +              mgc_complete_ep0_request();
 +              break;
-+              
++
 +      case MUSB_END0_STAGE_TX:
 +              DBG(2, "TX changeing ep status\n");
 +              if(reqptr->actual < reqptr->length)
@@ -204119,14 +205253,14 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      dev_context->end0_stage=MUSB_END0_STAGE_STATUSIN;
 +              }
 +              break;
-+              
++
 +      default: /* IT WAS STALLED */
-+              DBG(2, "recovering from stall? ep0stage=%s\n", 
++              DBG(2, "recovering from stall? ep0stage=%s\n",
 +                      decode_ep0stage(dev_context->end0_stage));
-+              dev_context->end0_stage = MUSB_END0_STAGE_SETUP;                    
++              dev_context->end0_stage = MUSB_END0_STAGE_SETUP;
 +              break;
 +      }
-+      
++
 +      DBG(4, "==>\n");
 +}
 +
@@ -204135,39 +205269,39 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +
 +/**
 + * Handle ep0 in receive state. Called to start a receie and on each interrupt
-+ * when receiving data on ep0. 
++ * when receiving data on ep0.
 + */
 +int ep0_rxstate(void) {
 +      const uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +      struct nomadik_ep* end_ptr = &(dev_context->end[0]);
 +      struct usb_request *reqptr=udc_current_request(end_ptr);
-+      
++
 +      /* nothign for now */
 +      DBG(4, "<==\n");
-+      
++
 +      if ( reqptr->actual==0 ) {
 +              /* ack the request first */
 +              DBG(4, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) );
 +              spin_lock(&dev_context->lock);
 +              MUSB_SELECTEND(base_addr, 0);
-+              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
++              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
 +                      MUSB_M_CSR0_P_SVDRXPKTRDY);
 +              spin_unlock(&dev_context->lock);
 +      }
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_LOCKED(&end_ptr->lock); 
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_LOCKED(&end_ptr->lock);
 +#endif
-+      
-+      DBG(4, "==>\n");        
-+      
++
++      DBG(4, "==>\n");
++
 +      return 0;
 +}
 +
 +/**
 + * Handle ep0 in transmit state. Called to start a receie and on each interrupt
-+ * when transmitting data on ep0. 
++ * when transmitting data on ep0.
 + */
 +int ep0_txstate(void) {
 +      unsigned long flags;
@@ -204175,150 +205309,150 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      struct nomadik_ep* end_ptr = &(dev_context->end[0]);
 +      struct usb_request *reqptr=udc_current_request(end_ptr);
 +      uint16_t csrval = MUSB_M_CSR0_TXPKTRDY;
-+      uint8_t* fifo_source; 
-+      uint8_t fifo_count; 
-+      
-+      DBG(4, "<==\n"); 
-+      
++      uint8_t* fifo_source;
++      uint8_t fifo_count;
++
++      DBG(4, "<==\n");
++
 +#ifdef MUSB_PARANOID
 +      if ( !dev_context || !reqptr )  {
-+              ERR("dev_context=%p, reqptr=%p", dev_context, reqptr); 
++              ERR("dev_context=%p, reqptr=%p", dev_context, reqptr);
 +              return -EINVAL;
 +      }
 +#endif
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      ASSERT_SPINLOCK_LOCKED(&end_ptr->lock); 
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++      ASSERT_SPINLOCK_LOCKED(&end_ptr->lock);
 +#endif
-+      
++
 +      spin_lock_irqsave(&dev_context->lock, flags);
 +      MUSB_SELECTEND(base_addr, 0);
-+      
++
 +      if ( reqptr->actual==0 ) {
 +              /* ack the request first */
 +              DBG(4, "acking request %s\n", decode_csr0(MUSB_M_CSR0_P_SVDRXPKTRDY) );
-+              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
++              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
 +                      MUSB_M_CSR0_P_SVDRXPKTRDY);
 +      }
-+      
-+      /* load the data */             
++
++      /* load the data */
 +      fifo_source = (uint8_t*)reqptr->buf+reqptr->actual;
 +      fifo_count =min((int)MUSB_END0_FIFOSIZE, (int)(reqptr->length-reqptr->actual));
 +      udc_load_fifo(base_addr, 0, fifo_count, fifo_source);
 +      reqptr->actual+=fifo_count; /* done */
-+      
++
 +      /* update the flags */
 +      if ( fifo_count < MUSB_MAX_END0_PACKET ) {
 +              csrval |= MUSB_M_CSR0_P_DATAEND;
 +              reqptr->status=0; /* done */
-+      }       
-+      
-+      /* send it out! (this will trigger the ep0 completition IRQ) 
++      }
++
++      /* send it out! (this will trigger the ep0 completition IRQ)
 +       * serviced in interrupt_complete()  */
-+      DBG(4, "wrote fifo_count=%d bytes, csrval=%s\n", fifo_count, 
++      DBG(4, "wrote fifo_count=%d bytes, csrval=%s\n", fifo_count,
 +              decode_csr0(csrval) );
 +      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
 +      spin_unlock_irqrestore(&dev_context->lock, flags);
-+      
-+      DBG(4, "==>\n"); 
++
++      DBG(4, "==>\n");
 +      return 0;
 +}
 +
 +/**
-+ * Read a FULL header packet from the hardware. The buffer starts with 
++ * Read a FULL header packet from the hardware. The buffer starts with
 + * struct usb_ctrlrequest (fields are converted to device specific
 + * byte order).
 + *
 + * @param wcount>0
-+ * @return 0 when the packet is complete, a negative number when an error 
++ * @return 0 when the packet is complete, a negative number when an error
 + * occurred, a positive number when still there are bytes to read.
 + */
 +int udc_read_control_request(struct nomadik_udc* dev_context, uint16_t wcount) {
 +      const uint8_t* base_ptr = ( u8  *)udc_base_addr;
 +      struct t_udc_end0_buffer* end0_buffer_ptr=(struct t_udc_end0_buffer*)dev_context->end0_buffer_ptr;
 +      struct usb_ctrlrequest* control_req_ptr=(struct usb_ctrlrequest*)end0_buffer_ptr;
-+      
++
 +      DBG(3, "<==\n");
-+      DBG(4,"wcount=%u, end0_buffer_ptr->count=%u\n", wcount, 
++      DBG(4,"wcount=%u, end0_buffer_ptr->count=%u\n", wcount,
 +              end0_buffer_ptr->count);
-+      
++
 +      /* what did u call me for?? */
 +      if (!wcount) {
 +              return -EINVAL;
 +      }
-+      
++
 +      /* buffer overrun, it should never happen */
 +      if ( wcount>(MUSB_MAX_END0_PACKET-sizeof(struct usb_ctrlrequest)) ) {
-+              ERR("buffer overrun! wcount=%d\n", wcount ); 
-+              return -EINVAL; 
-+      }       
-+      
++              ERR("buffer overrun! wcount=%d\n", wcount );
++              return -EINVAL;
++      }
++
 +      /* need to have at least enough bytes for the control request
-+       * comment this out to enable fifo size < 8 bytes 
++       * comment this out to enable fifo size < 8 bytes
 +       */
 +      if ( wcount<sizeof(struct usb_ctrlrequest) ) {
 +              ERR("wcount=%d<sizeof(struct usb_ctrlrequest)=%d\n",
-+                      wcount, (int)sizeof(struct usb_ctrlrequest)); 
-+              return -EINVAL; 
++                      wcount, (int)sizeof(struct usb_ctrlrequest));
++              return -EINVAL;
 +      }
-+      
-+#ifdef MUSB_PARANOID 
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
++
++#ifdef MUSB_PARANOID
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
 +#endif
-+      
++
 +      spin_lock(&dev_context->lock);
 +      MUSB_SELECTEND(base_ptr, 0); /* select ep0 */
-+      
++
 +      /* count=0 means that I'm reading the USB standard header:
-+       * that's the first thing I need to read from the FIFO (8 bytes). 
++       * that's the first thing I need to read from the FIFO (8 bytes).
 +       */
 +      if ( 0==end0_buffer_ptr->count ) {
 +              DBG(4, "reading header\n" );
-+              udc_unload_fifo(base_ptr, 0, sizeof(struct usb_ctrlrequest), 
++              udc_unload_fifo(base_ptr, 0, sizeof(struct usb_ctrlrequest),
 +                      (uint8_t*)control_req_ptr);
 +              wcount-=sizeof(struct usb_ctrlrequest);
 +              DBG(6, "header read\n");
-+              
-+              /* data from the USB bus must be converted from LSB to 
-+               * host-specific byte ordering; the control request header 
-+               * tell me the payload length etc. 
++
++              /* data from the USB bus must be converted from LSB to
++               * host-specific byte ordering; the control request header
++               * tell me the payload length etc.
 +               */
 +              le16_to_cpus( control_req_ptr->wLength );
 +              le16_to_cpus( control_req_ptr->wIndex );
 +              le16_to_cpus( control_req_ptr->wValue );
-+              
-+              DBG(4, "bRequest=%02x, kind=%s, wValue=%04x, wIndex=%04x, wLength=%04x\n", 
-+                      control_req_ptr->bRequest, decode_request(control_req_ptr), 
-+                      control_req_ptr->wValue, control_req_ptr->wIndex, 
++
++              DBG(4, "bRequest=%02x, kind=%s, wValue=%04x, wIndex=%04x, wLength=%04x\n",
++                      control_req_ptr->bRequest, decode_request(control_req_ptr),
++                      control_req_ptr->wValue, control_req_ptr->wIndex,
 +                      control_req_ptr->wLength);
-+              
-+              if( control_req_ptr->bRequestType & USB_DIR_IN ) { 
++
++              if( control_req_ptr->bRequestType & USB_DIR_IN ) {
 +                      /* write to host: up to wLength bytes */
 +                      end0_buffer_ptr->count=0;
 +                      dev_context->end0_stage = MUSB_END0_STAGE_TX;
-+              } else if( control_req_ptr->bRequestType & USB_DIR_OUT ) { 
++              } else if( control_req_ptr->bRequestType & USB_DIR_OUT ) {
 +                      /* out to function: wLength to go for the payload */
 +                      end0_buffer_ptr->count=control_req_ptr->wLength;
 +                      dev_context->end0_stage = MUSB_END0_STAGE_RX;
-+              } 
++              }
 +      }
-+      
-+      if ( wcount>0 ) {    
++
++      if ( wcount>0 ) {
 +              /* now Im reading the rest of it, this will never be executed I guess */
 +              uint16_t offset=sizeof(struct usb_ctrlrequest)+ /* read past the header */
-+                      (control_req_ptr->wLength)-(end0_buffer_ptr->count);    
++                      (control_req_ptr->wLength)-(end0_buffer_ptr->count);
 +              udc_unload_fifo(base_ptr, 0, wcount, &end0_buffer_ptr->data[offset]);
 +              end0_buffer_ptr->count-=wcount;
 +      }
-+      
-+      DBG(5, "end0_buffer_ptr->count=%d, ep0stage=%s, %s\n", 
-+              end0_buffer_ptr->count, decode_ep0stage(dev_context->end0_stage), 
-+              (end0_buffer_ptr->count)?"still to go":"header completed"); 
++
++      DBG(5, "end0_buffer_ptr->count=%d, ep0stage=%s, %s\n",
++              end0_buffer_ptr->count, decode_ep0stage(dev_context->end0_stage),
++              (end0_buffer_ptr->count)?"still to go":"header completed");
 +      DBG(3, "==>\n");
-+      
++
 +      spin_unlock(&dev_context->lock);
-+      
++
 +      /* 0 header completed, <0 error, >0 bytes to go*/
 +      return (end0_buffer_ptr->count);
 +}
@@ -204326,13 +205460,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/* ---------------------------------------------------------------------- */
 +
 +/**
-+ * Handle ep0 interrupt of a device, lock & release dev_context. This is the main 
++ * Handle ep0 interrupt of a device, lock & release dev_context. This is the main
 + * entry point of the gadget Ep0 handling code.
 + * @param dev_context the controller
 + */
 +uint8_t udc_ep0_irq(void)
 +{
-+      
++
 +      uint16_t csrval; /* */
 +      uint16_t wcount; /* bytes available */
 +      const uint8_t* base_addr = (uint8_t*)udc_base_addr;
@@ -204341,24 +205475,24 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      MUSB_SELECTEND(base_addr, 0); /* select ep0 */
 +      csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0, 0);
 +      wcount = MUSB_READCSR8(base_addr, MUSB_O_HDRC_COUNT0, 0);
-+      
++
 +      /* I sent a stall.. need to acknowledge it now.. */
-+      if(csrval & MUSB_M_CSR0_P_SENTSTALL) {    
-+              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
-+                      csrval & ~MUSB_M_CSR0_P_SENTSTALL );    
-+              dev_context->end0_stage=MUSB_END0_STAGE_SETUP;  
++      if(csrval & MUSB_M_CSR0_P_SENTSTALL) {
++              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
++                      csrval & ~MUSB_M_CSR0_P_SENTSTALL );
++              dev_context->end0_stage=MUSB_END0_STAGE_SETUP;
 +      }
-+      
++
 +      /* setup ended prematurely, abort it  */
-+      if (csrval & MUSB_M_CSR0_P_SETUPEND) {  
++      if (csrval & MUSB_M_CSR0_P_SETUPEND) {
 +              /* clearing it */
-+              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
++              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
 +                      MUSB_M_CSR0_P_SVDSETUPEND );
-+              dev_context->end0_stage=MUSB_END0_STAGE_SETUP;  
++              dev_context->end0_stage=MUSB_END0_STAGE_SETUP;
 +      }
-+      
-+      spin_unlock(&dev_context->lock);    
-+      
++
++      spin_unlock(&dev_context->lock);
++
 +      /* handle completition interrupt */
 +      if ( !csrval && !wcount ) {
 +              handle_ep0_completition_irq();
@@ -204371,65 +205505,65 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              if(!dev_context->set_config_flag)
 +                      mgc_complete_ep0_request();
 +              break;
-+      }    
-+      switch( dev_context->end0_stage ) {     
-+      /* im alrewady writing to host, TX state, 
++      }
++      switch( dev_context->end0_stage ) {
++      /* im alrewady writing to host, TX state,
 +              sequence #1 initiated during the setup */
 +      case MUSB_END0_STAGE_TX:
 +              if (  csrval & MUSB_M_CSR0_TXPKTRDY  ) {
 +                      ep0_txstate();
 +              } break;
-+              
-+              /* im alrewady receiving from host, RX state, 
++
++              /* im alrewady receiving from host, RX state,
 +              sequence #2 initiated during the setup */
-+      case MUSB_END0_STAGE_RX: 
++      case MUSB_END0_STAGE_RX:
 +              if (  csrval & MUSB_M_CSR0_RXPKTRDY  ) {
-+                      ep0_rxstate();      
++                      ep0_rxstate();
 +              }
 +              break;
-+              
++
 +              /* received from host, RX State, header */
-+      case MUSB_END0_STAGE_SETUP:     
-+              if ( csrval & MUSB_M_CSR0_RXPKTRDY ) { 
++      case MUSB_END0_STAGE_SETUP:
++              if ( csrval & MUSB_M_CSR0_RXPKTRDY ) {
 +                      int count=0, handled=0;
-+                      
++
 +                      count=udc_read_control_request(dev_context, wcount);
-+                      if ( count<0 ) { 
++                      if ( count<0 ) {
 +                              /* ack the request */
 +                              ERR("error reading the control request: this is bad (tm)\n");
 +                      } else if ( 0==count ) { /* I got the full packet, GREAT! */
 +                              struct usb_ctrlrequest *control_request_ptr=(struct usb_ctrlrequest*)
 +                                      dev_context->end0_buffer_ptr;
-+                              
++
 +                              /* sequence #3 */
 +                              if ( is_zerodata_request(control_request_ptr) ) {
 +                                      uint16_t csrval= MUSB_M_CSR0_P_SVDRXPKTRDY
 +                                              | MUSB_M_CSR0_P_DATAEND;
-+                                      
-+                                      handled=service_zero_data_request(dev_context, 
++
++                                      handled=service_zero_data_request(dev_context,
 +                                              control_request_ptr);
-+                                      if ( handled<0 && handled!=-EOPNOTSUPP ) {                      
-+                                              csrval |= MUSB_M_CSR0_P_SENDSTALL;    
++                                      if ( handled<0 && handled!=-EOPNOTSUPP ) {
++                                              csrval |= MUSB_M_CSR0_P_SENDSTALL;
 +                                      }
-+                                      
++
 +                                      dev_context->end0_stage = MUSB_END0_STAGE_STATUSIN;
-+                                      
++
 +                                      /* ack the request */
-+                                      DBG(3, "handled=%d, csrval=%s, ep0stage=%s\n", handled, 
-+                                              decode_csr0(csrval), 
++                                      DBG(3, "handled=%d, csrval=%s, ep0stage=%s\n", handled,
++                                              decode_csr0(csrval),
 +                                              decode_ep0stage(dev_context->end0_stage) );
-+                                      
++
 +                                      if(!dev_context->set_config_flag)
 +                                      {
 +                                              spin_lock(&dev_context->lock);
 +                                              MUSB_SELECTEND(base_addr, 0);
-+                                              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);   
++                                              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
 +                                              spin_unlock(&dev_context->lock);
 +                                      }
 +                              } else {
 +                                      /* sequence #1 */
 +                                      if ( is_tx_request(control_request_ptr) ) {
-+                                              /* write to host, a request is posted on ep0 */                                             
++                                              /* write to host, a request is posted on ep0 */
 +                                              dev_context->end0_stage=MUSB_END0_STAGE_TX;
 +                                              handled=service_tx_request(control_request_ptr);
 +                                              /* sequence #2, a request is posted on ep0 */
@@ -204437,27 +205571,27 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                                              dev_context->end0_stage=MUSB_END0_STAGE_RX;
 +                                              handled=service_rx_request(control_request_ptr);
 +                                      }
-+                                      
++
 +                                      if ( handled<0 ) {
 +                                              /* stall it!!! application stall */
 +                                              spin_lock(&dev_context->lock);
 +                                              MUSB_SELECTEND(base_addr, 0);
-+                                              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, 
++                                              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0,
 +                                                      MUSB_M_CSR0_P_SVDRXPKTRDY | MUSB_M_CSR0_P_SENDSTALL);
 +                                              spin_unlock(&dev_context->lock);
-+                                      }                                                                       
++                                      }
 +                              }
-+                              
-+                      }                       
++
++                      }
 +              } else {
-+                      
++
 +              }
 +              break;
-+              
-+              
++
++
 +              /* handle the application stall on Ep0 */
-+      default: 
-+              {           
++      default:
++              {
 +                      uint16_t csrval = MUSB_M_CSR0_P_SENDSTALL;
 +                      switch ( dev_context->end0_stage & ~MUSB_END0_STAGE_STALL_BIT ) {
 +                      case MUSB_END0_STAGE_TX:
@@ -204467,19 +205601,19 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                              csrval|=MUSB_M_CSR0_RXPKTRDY;
 +                              break;
 +                      }
-+                      
-+                      DBG(3, "Application stall from ep0stage=%s\n", 
++
++                      DBG(3, "Application stall from ep0stage=%s\n",
 +                              decode_ep0stage(dev_context->end0_stage));
 +                      spin_lock(&dev_context->lock);
 +                      MUSB_SELECTEND(base_addr, 0);
-+                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);   
-+                      spin_unlock(&dev_context->lock);                 
-+                      
-+                      dev_context->end0_stage = MUSB_END0_STAGE_SETUP;        
-+              } 
++                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
++                      spin_unlock(&dev_context->lock);
++
++                      dev_context->end0_stage = MUSB_END0_STAGE_SETUP;
++              }
 +              break;
-+    } 
-+      
++    }
++
 +    return 1;
 +}
 +
@@ -204495,15 +205629,15 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +inline int get_ep_packet_size(struct nomadik_udc* dev_context, uint8_t bEnd)
 +{
 +    int size=dev_context->end[bEnd].maxpacket;
-+      
++
 +      if ( (USB_ENDPOINT_XFER_BULK == dev_context->end[bEnd].bmAttributes)
-+              && dev_context->bulk_split) 
++              && dev_context->bulk_split)
 +      {
 +              size=dev_context->end[bEnd].maxpacket;
-+    } 
-+      
-+    return size;      
-+}             
++    }
++
++    return size;
++}
 +
 +
 +inline struct usb_request* udc_current_request( struct nomadik_ep * end_ptr) {
@@ -204514,33 +205648,33 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +/**
 + * Queue requests to endpoints for execution.
 + * @param ep the endpoint the request shall be queued to
-+ * @param req_ptr the request 
++ * @param req_ptr the request
 + * @param gfp_flags memory flags
 + */
 +int nomadik_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
 +                                       gfp_t gfp_flags)
 +{
 +      unsigned long lockflags;
-+      
++
 +      struct nomadik_ep       *ep = container_of(_ep, struct nomadik_ep, ep);
 +      struct nomadik_req      *req_ptr = container_of(_req, struct nomadik_req, req);
 +      const uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +    const uint8_t bEnd=EP_NUMBER(ep);
 +      int             is_iso = 0;
-+      
++
 +      /* catch various bogus parameters */
 +      if (!req_ptr || !req_ptr->req.complete || !req_ptr->req.buf
 +              /*|| !list_empty(&req_ptr->completion_list)*/) {
 +              ERR("%s, bad params\n", __FUNCTION__);
 +      return -EINVAL;
 +      }
-+      
++
 +      if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
 +              if (req_ptr->req.length > ep->ep.maxpacket)
 +                      return -EMSGSIZE;
 +              is_iso = 1;
 +      }
-+      
++
 +      /* this isn't bogus, but NOMADIK DMA isn't the only hardware to
 +       * have a hard time with partial packet reads...  reject it.
 +       */
@@ -204552,10 +205686,10 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              ERR("%s, no partial packet OUT reads\n", __FUNCTION__);
 +              return -EMSGSIZE;
 +      }
-+      
++
 +      if (!dev_context->driver || dev_context->gadget.speed == USB_SPEED_UNKNOWN)
 +              return -ESHUTDOWN;
-+      
++
 +      if (use_dma && ep->has_dma) {
 +              if (req_ptr->req.dma == DMA_ADDR_INVALID) {
 +                      req_ptr->req.dma = dma_map_single(
@@ -204576,44 +205710,44 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      req_ptr->mapped = 0;
 +              }
 +      }
-+      
++
 +      DBG(2,"%s queue req %p, len %d buf %p\n",
 +              ep->ep.name, _req, _req->length, _req->buf);
-+      
-+      
-+      
++
++
++
 +      /* request is mine now... */
-+    req_ptr->req.actual=0;    
-+    req_ptr->req.status=-EINPROGRESS;    
-+    req_ptr->end_number=bEnd;    
++    req_ptr->req.actual=0;
++    req_ptr->req.status=-EINPROGRESS;
++    req_ptr->end_number=bEnd;
 +      req_ptr->is_tx=ep->is_tx;
-+      
++
 +      /* for now... */
 +    INIT_LIST_HEAD( &req_ptr->req.list );
-+      
++
 +      /* lock the endpoint */
 +      EP_SPIN_LOCK_IRQSAVE(ep, lockflags);
-+      
++
 +    /* add req_ptr to the list */
 +    list_add_tail( &(req_ptr->req.list), &(ep->req_list) );
 +      /* it this is not the head of the queue, done... */
 +    if ( req_ptr!=(struct nomadik_req*)udc_current_request(ep) ) {
-+              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );     
++              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );
 +              return 0;
 +      }
-+      
++
 +#ifdef MUSB_PARANOID
 +      if ( bEnd==ReqEnd ) {
 +              ReqCount++;
 +      }
-+      
++
 +      if ( ReqCount>=ReqCap ) {
 +              WARN("ReqCount=%d on ep%d\n", ReqCount, bEnd);
-+              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );  
++              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );
 +              return 0;
 +      }
 +#endif
-+      
++
 +      /* start the request otherwise; the EP MUST BE UNLOCKED */
 +      if ( bEnd==0 ) {
 +              if(dev_context->set_config_flag)
@@ -204623,46 +205757,46 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      spin_lock(&dev_context->lock);
 +                      MUSB_SELECTEND(base_addr, 0);
 +                      csrval= MUSB_M_CSR0_P_SVDRXPKTRDY | MUSB_M_CSR0_P_DATAEND;
-+                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);   
++                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, csrval);
 +                      spin_unlock(&dev_context->lock);
 +              }
-+              
-+              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );      
-+              
-+              
++
++              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );
++
++
 +              switch ( dev_context->end0_stage )
-+              {                                               
-+              case MUSB_END0_STAGE_TX: 
-+                      
++              {
++              case MUSB_END0_STAGE_TX:
++
 +                      ep0_txstate(); /* sequence #1, TX State */
 +                      break;
-+                      
-+                      
++
++
 +              case MUSB_END0_STAGE_RX:
-+                      
-+                      ep0_rxstate(); /* sequence #2, RX State */          
++
++                      ep0_rxstate(); /* sequence #2, RX State */
 +                      break;
-+                      
++
 +                      /* certain gadged may keep ep0 busy; g_file_storage
 +                      does it after a set_config command.*/
 +              default: {
-+                      
-+                      mdelay(5);              
-+                      
++
++                      mdelay(5);
++
 +                      req_ptr->req.status=(req_ptr->req.actual==req_ptr->req.length)
 +                              ? 0 : -EINVAL;
 +                      mgc_complete_ep0_request();
-+                               } 
++                               }
 +                      break;
-+                      
++
 +              }
-+              
++
 +      } else
 +      {
 +              udc_restart_request(dev_context, (struct usb_request *)req_ptr);
 +              EP_SPIN_UNLOCK_IRQRESTORE( ep,lockflags );
 +      }
-+      
++
 +    DBG(4, "==>\n");
 +    return 0;
 +}
@@ -204677,55 +205811,55 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      DBG(3, "<== restarting (%s) request req_ptr=%p on ep=%d\n",
 +              ((struct nomadik_req*)req_ptr)->is_tx ? "tx" : "rx",
 +              req_ptr, ((struct nomadik_req*)req_ptr)->end_number);
-+      
++
 +#ifdef MUSB_PARANOID
 +      if ( !req_ptr ) {
 +              ERR("null req_ptr\n");
-+              return;    
++              return;
 +      }
 +#endif
-+      
++
 +      if( ((struct nomadik_req*)req_ptr)->is_tx ) {
-+              txstate(dev_context, (struct nomadik_req*)req_ptr);             
++              txstate(dev_context, (struct nomadik_req*)req_ptr);
 +      } else {
-+              rxstate(dev_context, (struct nomadik_req*)req_ptr);  
-+      }               
++              rxstate(dev_context, (struct nomadik_req*)req_ptr);
++      }
 +}
 +
 +/**
 + * Dequeue a request
 + * @param ep the endpoint
 + * @param req_ptr the request to dequeue
-+ * @return 0 if success, or negative when error 
++ * @return 0 if success, or negative when error
 + */
 +int nomadik_ep_dequeue(struct usb_ep *ep, struct usb_request *req_ptr)
 +{
 +      struct nomadik_ep * end_ptr =( struct nomadik_ep *)ep;
-+      
++
 +      DBG(4, "<==\n" );
 +      DBG(3, "dequeuing from nEnd=0x%x, end_ptr=%p, req_ptr=%p\n", \
-+              EP_NUMBER(end_ptr), end_ptr, req_ptr); 
-+      
-+      
++              EP_NUMBER(end_ptr), end_ptr, req_ptr);
++
++
 +      /* flush the request returning -EINVAL; syncronnous */
 +      EP_SPIN_LOCK( end_ptr );
 +      req_ptr->status=-EINVAL;
 +      if ( req_ptr->complete ) {
 +              list_del( &req_ptr->list );
 +              EP_SPIN_UNLOCK( end_ptr );
-+              req_ptr->complete((struct usb_ep *)end_ptr, req_ptr);    
++              req_ptr->complete((struct usb_ep *)end_ptr, req_ptr);
 +      } else {
-+              EP_SPIN_UNLOCK( end_ptr );      
++              EP_SPIN_UNLOCK( end_ptr );
 +      }
-+      
++
 +      return 0;
 +}
 +
 +
 +
 +/**
-+ * An endpoint is transmitting data. This can be called either from 
-+ * the IRQ routine or from GadgetQueue to kickstart a request on an 
++ * An endpoint is transmitting data. This can be called either from
++ * the IRQ routine or from GadgetQueue to kickstart a request on an
 + * endpoint.
 + *
 + * @warning ep locked & IRQ disabled
@@ -204738,86 +205872,86 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      struct nomadik_ep* end_ptr;
 +      struct usb_request *reqptr;
 +      uint16_t fifo_count = 0, csrval;
-+      const uint8_t* base_addr = (uint8_t*)udc_base_addr;     
-+      
++      const uint8_t* base_addr = (uint8_t*)udc_base_addr;
++
 +      DBG(4, "<==\n");
-+      
-+#ifdef MUSB_PARANOID 
++
++#ifdef MUSB_PARANOID
 +      if ( !req ) {
 +              ERR("cannot call txstate without request\n");
 +              return;
 +      }
 +#endif
-+      
++
 +      bEnd=req->end_number;
 +      reqptr=&req->req;
 +      end_ptr=&(dev_context->end[req->end_number]);
-+      
-+      fifo_count = min(get_ep_packet_size(dev_context, bEnd), 
++
++      fifo_count = min(get_ep_packet_size(dev_context, bEnd),
 +              (int)(reqptr->length-reqptr->actual));
 +      /* read TXCSR before */
-+      MUSB_SELECTEND(base_addr, bEnd);    
++      MUSB_SELECTEND(base_addr, bEnd);
 +      csrval=MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
-+      
++
 +      if (USB_ENDPOINT_XFER_ISOC == end_ptr->bmAttributes) {
 +              csrval |= MUSB_M_TXCSR_ISO;
 +      }
-+      
-+#ifdef MUSB_PARANOID 
++
++#ifdef MUSB_PARANOID
 +      if ( reqptr->length-reqptr->actual<0 ) {
 +              ERR("NEGATIVE FIFOCOUNT! reqptr->actual=%d, fifo_count=%d, reqptr->length=%d\n", \
 +                      reqptr->actual, fifo_count, reqptr->length);
 +              fifo_count=0;
 +      }
-+      
++
 +      if ( reqptr->actual+fifo_count>reqptr->length ) {
 +              ERR("trying to write PAST length! reqptr->actual=%d, fifo_count=%d, reqptr->length=%d\n", \
 +                      reqptr->actual, fifo_count, reqptr->length);
 +              fifo_count=reqptr->length-reqptr->actual;
 +      }
 +#endif
-+      
++
 +      DBG(3, "bEnd=0x%x, end_ptr->maxpacket=0x%x, fifo_count=%d, %s\n", \
 +              bEnd, end_ptr->maxpacket, fifo_count, dump_usb_request(reqptr) );
-+      
-+      
++
++
 +      /* stalled?? */
-+      if ( csrval & MUSB_M_TXCSR_P_SENDSTALL ) {      
++      if ( csrval & MUSB_M_TXCSR_P_SENDSTALL ) {
 +              DBG(2, "completing stalled request reqptr=%p\n", reqptr);
 +              list_del( &reqptr->list );
-+              udc_complete_request(reqptr, 0); 
++              udc_complete_request(reqptr, 0);
 +              return;
 +      }
-+      
-+      
-+#ifdef MUSB_NO_ZEROPACKET_KLUDGE 
++
++
++#ifdef MUSB_NO_ZEROPACKET_KLUDGE
 +      if ( !fifo_count ) {
-+              DBG(2, "==> Skipping zero packet\n");   
++              DBG(2, "==> Skipping zero packet\n");
 +      }
 +#endif
-+      
-+      udc_load_fifo(base_addr, bEnd, fifo_count, 
-+              (uint8_t*)(reqptr->buf+reqptr->actual));        
++
++      udc_load_fifo(base_addr, bEnd, fifo_count,
++              (uint8_t*)(reqptr->buf+reqptr->actual));
 +      reqptr->actual+=fifo_count;
-+      
-+      
-+      
++
++
++
 +      csrval = MUSB_M_TXCSR_MODE | MUSB_M_TXCSR_TXPKTRDY; /* add my stuff */
-+      
-+      
++
++
 +      /* now write out the thing */
-+      DBG(3, "xmit a packet reqptr->length=%d, reqptr->actual=%d, \n", 
++      DBG(3, "xmit a packet reqptr->length=%d, reqptr->actual=%d, \n",
 +              reqptr->length, reqptr->actual);
-+      
-+      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval);                
-+      
++
++      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval);
++
 +      DBG(4, "==>\n");
 +}
 +
 +/**
 + * Data ready for a request; called from IRQ; no need to disable the
 + * IRQS bc they are already disabled. The end point CANNOT be locked
-+ * when entering this routine because it would deadlock. By design, 
++ * when entering this routine because it would deadlock. By design,
 + * this is called only after txstate has been called.
 + *
 + * @param dev_context
@@ -204829,32 +205963,32 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    struct usb_request *reqptr;
 +    uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +    struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]);
-+      
++
 +    DBG(4, "<== bEnd=%d\n", bEnd );
-+      
-+      do {                            
-+              spin_lock_irqsave(&dev_context->lock, flags); 
++
++      do {
++              spin_lock_irqsave(&dev_context->lock, flags);
 +              MUSB_SELECTEND(base_addr, bEnd);
 +              csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd);
 +              DBG(1, "udc_ep_tx_irq bEnd = %d txcsr = 0x%x\n",bEnd,csrval);
-+              
++
 +              if (csrval & MUSB_M_TXCSR_P_SENTSTALL) {
 +                      csrval &= ~MUSB_M_TXCSR_P_SENTSTALL;
-+                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval);            
-+                      
-+                      DBG(2, "request was stalled, completing it\n");                 
++                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval);
++
++                      DBG(2, "request was stalled, completing it\n");
 +                      reqptr=udc_current_request(end_ptr);
 +                      if ( reqptr ) {
 +                              list_del( &reqptr->list );
-+                              spin_unlock_irqrestore(&dev_context->lock, flags);                              
-+                              udc_complete_request(reqptr, -EOPNOTSUPP); /* complete */           
++                              spin_unlock_irqrestore(&dev_context->lock, flags);
++                              udc_complete_request(reqptr, -EOPNOTSUPP); /* complete */
 +                      } else {
 +                              WARN("Acking sent stall, but no request!\n");
-+                      }                       
-+                      
++                      }
++
 +                      break;
 +              }
-+              
++
 +              if(csrval & MUSB_M_TXCSR_P_UNDERRUN) {
 +#ifdef NMDK_CONFIG_PROC_FS
 +                      dev_context->end[bEnd].dwMissedTxPackets++;
@@ -204862,64 +205996,64 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      csrval &= ~MUSB_M_TXCSR_P_UNDERRUN;
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval);
 +                      DBG(2, "underrun on ep%d\n", bEnd);
-+              }       
-+              
-+              reqptr=udc_current_request(end_ptr);    
-+              if ( reqptr ) {         
-+                      
-+                  /* the zero flag request the transmission of a zero data pkt 
++              }
++
++              reqptr=udc_current_request(end_ptr);
++              if ( reqptr ) {
++
++                  /* the zero flag request the transmission of a zero data pkt
 +                   * (when required). The zero flag is reset to zero,
 +                       * after the zero packet has been submitted. */
 +                      if ( reqptr->actual==reqptr->length ) {
-+                              
++
 +                              if ( reqptr->zero &&
-+                                      ( reqptr->length && (reqptr->length%get_ep_packet_size(dev_context, bEnd))==0 ) 
++                                      ( reqptr->length && (reqptr->length%get_ep_packet_size(dev_context, bEnd))==0 )
 +                                      && !(csrval & MUSB_M_TXCSR_P_SENTSTALL)
-+                                      ) { 
-+                                      const uint16_t csrval=MUSB_M_TXCSR_MODE 
++                                      ) {
++                                      const uint16_t csrval=MUSB_M_TXCSR_MODE
 +                                              | MUSB_M_TXCSR_TXPKTRDY;
-+                                      
++
 +                                      reqptr->zero=0;
-+                                      
++
 +                                      DBG(3, "sending zero pkt\n");
-+                                      
-+                                      MUSB_SELECTEND(base_addr, bEnd);                                        
++
++                                      MUSB_SELECTEND(base_addr, bEnd);
 +                                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, bEnd, csrval);
-+                                      spin_unlock_irqrestore(&dev_context->lock, flags);      
++                                      spin_unlock_irqrestore(&dev_context->lock, flags);
 +                                      break;
-+                              } 
-+                              
-+                              list_del( &reqptr->list );                              
++                              }
++
++                              list_del( &reqptr->list );
 +                              udc_complete_request(reqptr, 0); /* async complete */
-+                              
++
 +                              /* kickstart next request if available */
-+                              reqptr=(end_ptr->binactive) ? NULL 
-+                                      : udc_current_request(end_ptr);             
++                              reqptr=(end_ptr->binactive) ? NULL
++                                      : udc_current_request(end_ptr);
 +                              if ( !reqptr ) {
-+                                      DBG(3, "bEnd=0x%x idle now\n", bEnd);                                   
-+                                      DBG( 2, "bEnd=0x%x idle now\n", bEnd);                                  
++                                      DBG(3, "bEnd=0x%x idle now\n", bEnd);
++                                      DBG( 2, "bEnd=0x%x idle now\n", bEnd);
 +                                      break;
-+                              }       
++                              }
 +                      }
-+                      
++
 +                      /* txstate unlock the ep before writing */
 +                      txstate(dev_context, (struct nomadik_req*)reqptr);
 +              }
-+              
++
 +      } while (0);
-+      
-+      spin_unlock_irqrestore(&dev_context->lock, flags);      
++
++      spin_unlock_irqrestore(&dev_context->lock, flags);
 +    DBG(2, "==>\n" );
 +}
 +
 +/* ------------------------------------------------------------ */
 +
 +/**
-+ * Receving on an endpoint. Called from the IRQ routine and when 
++ * Receving on an endpoint. Called from the IRQ routine and when
 + * starting receving.
 + * @warning ep locked & IRQ disabled
 + * @param dev_context the controller
-+ * @param req the request 
++ * @param req the request
 + * @see udc_ep_rx_irq
 + */
 +void rxstate(struct nomadik_udc* dev_context, struct nomadik_req* req)
@@ -204930,48 +206064,48 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    const uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +    struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]);
 +    uint16_t fifo_count = 0, wcount=end_ptr->maxpacket;
-+      
-+      
++
++
 +    MUSB_SELECTEND(base_addr, bEnd);
 +    csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd);
 +    if ( csrval& MUSB_M_RXCSR_RXPKTRDY ) {
-+              
++
 +              /* this also handle residual (if any) */
-+              wcount = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd);                          
-+              if ( reqptr->actual < reqptr->length ) {        
-+                      
-+                      fifo_count = (uint16_t)min((int)wcount, 
++              wcount = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd);
++              if ( reqptr->actual < reqptr->length ) {
++
++                      fifo_count = (uint16_t)min((int)wcount,
 +                              (int)(reqptr->length - reqptr->actual));
-+                      udc_unload_fifo(base_addr, bEnd, fifo_count, 
++                      udc_unload_fifo(base_addr, bEnd, fifo_count,
 +                              (uint8_t*)(reqptr->buf + reqptr->actual));
 +                      reqptr->actual += fifo_count;
-+                      
++
 +                      DBG(3, "fifo_count=%d, bEnd=0x%x, end_ptr->maxpacket=0x%x, wcount=0x%x, %s\n",\
 +                              fifo_count, bEnd, end_ptr->maxpacket, wcount, dump_usb_request(reqptr));
-+                      
++
 +                      /* ack the read! */
 +                      csrval &= ~MUSB_M_RXCSR_RXPKTRDY;
 +                      MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval);
-+              }           
++              }
 +    }
-+      
++
 +      /* reach the end or short packet detected */
-+      if ( reqptr->actual==reqptr->length || wcount<end_ptr->maxpacket ) {    
++      if ( reqptr->actual==reqptr->length || wcount<end_ptr->maxpacket ) {
 +              reqptr->status=0;
-+              
-+              DBG(3, "completing reqptr=%p on bEnd=0x%x\n", reqptr, bEnd); 
++
++              DBG(3, "completing reqptr=%p on bEnd=0x%x\n", reqptr, bEnd);
 +              list_del( &reqptr->list );
-+              DBG(3, "queuing completion\n"); 
++              DBG(3, "queuing completion\n");
 +              udc_complete_request(reqptr, reqptr->status); /* async complete */
 +      }
-+      
++
 +      DBG(2, "==>");
 +}
 +
 +/**
 + * Data ready for a request; called from IRQ
 + * @param dev_context the controller
-+ * @param req the request 
++ * @param req the request
 + */
 +void udc_ep_rx_irq(uint8_t bEnd)
 +{
@@ -204980,13 +206114,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    struct usb_request* reqptr=NULL;
 +    uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +    struct nomadik_ep* end_ptr = &(dev_context->end[bEnd]);
-+    
++
 +    DBG(1, "<==\n" );
-+      
++
 +      /* executed from interrupt no need to disable them */
-+      spin_lock_irqsave(&dev_context->lock, flags); 
++      spin_lock_irqsave(&dev_context->lock, flags);
 +      MUSB_SELECTEND(base_addr, bEnd);
-+      csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd);            
++      csrval = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd);
 +      if(csrval & MUSB_M_RXCSR_P_SENTSTALL) {
 +              csrval &= ~MUSB_M_RXCSR_P_SENTSTALL;
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval);
@@ -204994,7 +206128,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              spin_unlock_irqrestore(&dev_context->lock, flags);
 +              return;
 +      }
-+      
++
 +      if(csrval & MUSB_M_RXCSR_P_OVERRUN) {
 +#ifdef NMDK_CONFIG_PROC_FS
 +              dev_context->end[bEnd].dwMissedRxPackets++;
@@ -205003,23 +206137,23 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, bEnd, csrval);
 +              DBG(2, "Received overrun on ep%d\n", bEnd);
 +      }
-+      
++
 +#ifdef NMDK_CONFIG_PROC_FS
 +      if(csrval & MUSB_M_RXCSR_INCOMPRX) {
 +              dev_context->end[bEnd].dwErrorRxPackets++;
 +      }
 +#endif
-+      
++
 +      /* analyze request if the ep is not inactive */
-+      reqptr=(end_ptr->binactive) ? NULL : udc_current_request(end_ptr);                  
++      reqptr=(end_ptr->binactive) ? NULL : udc_current_request(end_ptr);
 +      if ( reqptr ) {
-+              DBG( 1, "Going into rxstate\n"); 
++              DBG( 1, "Going into rxstate\n");
 +              rxstate(dev_context, (struct nomadik_req*)reqptr);
-+      } else {        
-+              DBG(3, "Rx: bytes waiting on ep=0x%x\n", bEnd); 
-+              DBG(1,  "Rx: bytes waiting on ep=0x%x\n", bEnd); 
-+      }       
-+      
++      } else {
++              DBG(3, "Rx: bytes waiting on ep=0x%x\n", bEnd);
++              DBG(1,  "Rx: bytes waiting on ep=0x%x\n", bEnd);
++      }
++
 +      spin_unlock_irqrestore(&dev_context->lock, flags);
 +    DBG(4, "==>\n" );
 +}
@@ -205028,7 +206162,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +*
 +*/
 +
-+/** 
++/**
 + * @pre dev_context!=NULL
 + */
 +void udc_resume(void) {
@@ -205048,45 +206182,45 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    }
 +}
 +
-+/** 
++/**
 + * @pre dev_context!=NULL
 + */
 +void udc_disconnect_isr(void) {
-+    DBG(4, "<==\n" );    
++    DBG(4, "<==\n" );
 +    if( dev_context->driver && dev_context->driver->disconnect) {
 +              dev_context->driver->disconnect(& dev_context->gadget );
 +    }
-+    DBG(4, "==>\n" );   
-+      
++    DBG(4, "==>\n" );
++
 +}
 +
 +/**
 + *
 + * @pre dev_context!=NULL
 + */
-+void musb_reset_isr(void) 
++void musb_reset_isr(void)
 +{
 +    const uint8_t* base_addr = (uint8_t*)udc_base_addr;
 +    uint8_t devctl = MUSB_READ8(base_addr, MUSB_O_HDRC_DEVCTL);
 +    DBG(4, "<==\n");
-+      
-+    DBG(3, "<== mode=%s, addr=%x\n", (devctl&MUSB_M_DEVCTL_HM)?"host":"function", 
++
++    DBG(3, "<== mode=%s, addr=%x\n", (devctl&MUSB_M_DEVCTL_HM)?"host":"function",
 +              MUSB_READ8(base_addr, MUSB_O_HDRC_FADDR));
-+      
++
 +    /* HR does NOT clear itself */
 +    if(devctl & MUSB_M_DEVCTL_HR) {
-+              
++
 +              MUSB_WRITE8(base_addr, MUSB_O_HDRC_DEVCTL, MUSB_M_DEVCTL_SESSION);
 +    }
-+    
++
 +    /* unconfigured */
 +    dev_context->address=0;
 +    dev_context->end0_stage=MUSB_END0_STAGE_SETUP;
 +    if ( dev_context->driver ) {
-+              
++
 +              uint8_t bEnd;
-+              
-+              uint8_t power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER);       
++
++              uint8_t power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER);
 +              dev_context->gadget.speed = (power & MUSB_M_POWER_HSMODE)? USB_SPEED_HIGH : USB_SPEED_FULL;
 +              /* disable the endpoints */
 +              for(bEnd = 1; bEnd < dev_context->end_count; bEnd++)
@@ -205094,7 +206228,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      nomadik_ep_disable(&dev_context->end[bEnd].ep);
 +              }
 +              (dev_context->end[0]).binactive = MUSB_GADGET_EP_ACTIVE;
-+              
++
 +    }
 +    DBG(4, "==>\n");
 +}
@@ -205115,35 +206249,35 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    unsigned long flags;
 +    uint8_t* base_addr = (u8 *)udc_base_addr;
 +    int nEnd = EP_NUMBER(ep);
-+      
++
 +    DBG(4, "<==\n" );
-+      
++
 +#ifdef MUSB_PARANOID
 +    if (!dev_context) {
 +              ERR("Gadget not initialized, dev_context=NULL\n");
 +        return;
 +    }
-+      
++
 +      if ( nEnd<0 ) {
 +              ERR("invalid endpoint ep=%p\n", ep);
 +        return;
 +    }
-+      
-+      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
++
++      ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
 +#endif
-+      
++
 +    spin_lock_irqsave(&(dev_context->lock), flags);
 +    MUSB_SELECTEND(base_addr, (uint8_t)nEnd);
-+      
++
 +      /* disable interrupts */
 +    intr_txe = MUSB_READ16(base_addr, MUSB_O_HDRC_INTRTXE);
 +    MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe & ~(1 << nEnd));
-+      
++
 +    if(nEnd) {
 +        csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)nEnd);
 +        MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)nEnd, csr);
 +        MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_TXCSR, (uint8_t)nEnd, csr);
-+              
++
 +        csr = MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)nEnd);
 +              csr |= MUSB_M_RXCSR_FLUSHFIFO;
 +        MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_RXCSR, (uint8_t)nEnd, csr);
@@ -205151,11 +206285,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    } else {
 +              MUSB_WRITECSR16(base_addr, MUSB_O_HDRC_CSR0, 0, MUSB_M_CSR0_FLUSHFIFO);
 +    }
-+      
++
 +    /* re-enable interrupt */
 +    MUSB_WRITE16(base_addr, MUSB_O_HDRC_INTRTXE, intr_txe);
 +    spin_unlock_irqrestore(&(dev_context->lock), flags);
-+      
++
 +    DBG(4, "==>\n" );
 +}
 +
@@ -205171,25 +206305,25 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +    int result = 0;
 +    uint8_t* base_addr= (u8 *)udc_base_addr;
 +    int bEnd = EP_NUMBER(ep);
-+      
++
 +    DBG(4, "<==\n" );
-+      
++
 +#ifdef MUSB_PARANOID
-+    ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock); 
-+      
++    ASSERT_SPINLOCK_UNLOCKED(&dev_context->lock);
++
 +    if( MUSB_GadgetFindEnd(ep)<0 ) {
 +              ERR("invalid endpoint ep=%p\n", ep);
 +        return -EINVAL;
 +    }
 +#endif
-+      
++
 +    spin_lock_irqsave(&(dev_context->lock), flags);
-+    MUSB_SELECTEND(base_addr, bEnd);    
-+    result = MUSB_READCSR16(base_addr, 
-+              (bEnd)? MUSB_O_HDRC_RXCOUNT:MUSB_O_HDRC_COUNT0, 
++    MUSB_SELECTEND(base_addr, bEnd);
++    result = MUSB_READCSR16(base_addr,
++              (bEnd)? MUSB_O_HDRC_RXCOUNT:MUSB_O_HDRC_COUNT0,
 +              bEnd);
 +    spin_unlock_irqrestore(&(dev_context->lock), flags);
-+      
++
 +    DBG(4, "==> %d\n", result);
 +    return result;
 +}
@@ -205208,11 +206342,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +decode_request(struct usb_ctrlrequest *req)
 +{
 +    static char buf [8];
-+      
++
 +    sprintf(buf, "%s%s",( USB_TYPE_STANDARD==(req->bRequestType&USB_TYPE_MASK )?"S":"N" ),
-+              is_tx_request(req) ? "TX" 
-+              : is_rx_request(req) ? "RX" 
-+              : is_zerodata_request(req) ? "Z" 
++              is_tx_request(req) ? "TX"
++              : is_rx_request(req) ? "RX"
++              : is_zerodata_request(req) ? "Z"
 +              : "-" );
 +    return buf;
 +}
@@ -205221,12 +206355,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + */
 +static char *decode_csr0(uint16_t csr0) {
 +    static char buf[64];
-+    sprintf(buf, "(%s%s%s%s)", 
++    sprintf(buf, "(%s%s%s%s)",
 +              csr0&MUSB_M_CSR0_TXPKTRDY ? "[TXPKTRDY]":"",
 +              csr0&MUSB_M_CSR0_P_SVDRXPKTRDY ? "[SVDRXPKTRDY]":"",
 +              csr0&MUSB_M_CSR0_P_SENDSTALL ? "[stalled]":"",
-+              csr0&MUSB_M_CSR0_P_DATAEND ? "[dataend]":""); 
-+    return buf;  
++              csr0&MUSB_M_CSR0_P_DATAEND ? "[dataend]":"");
++    return buf;
 +}
 +
 +/* Decode a value to binary.
@@ -205234,11 +206368,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +static char *decode_bits(uint16_t value) {
 +    int i=0;
 +    static char buf[64];
-+    
++
 +    for (; i<16;i++) {
-+              buf[15-i]=(value&(1<<i))?'1':'0';    
++              buf[15-i]=(value&(1<<i))?'1':'0';
 +    }
-+    
++
 +    return buf;
 +}
 +
@@ -205246,13 +206380,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + */
 +static char *decode_txcsr(uint16_t txcsr) {
 +    static char buf[256];
-+    sprintf(buf, "%s (%s%s%s%s)", 
++    sprintf(buf, "%s (%s%s%s%s)",
 +              decode_bits(txcsr),
 +              txcsr&MUSB_M_TXCSR_TXPKTRDY ? "[TXPKTRDY]":"",
 +              txcsr&MUSB_M_TXCSR_AUTOSET ? "[MUSB_M_TXCSR_AUTOSET]":"",
 +              txcsr&MUSB_M_TXCSR_DMAENAB ? "[MUSB_M_TXCSR_DMAENAB]":"",
-+              txcsr&MUSB_M_TXCSR_DMAMODE ? "[MUSB_M_TXCSR_DMAMODE]":""); 
-+    return buf;  
++              txcsr&MUSB_M_TXCSR_DMAMODE ? "[MUSB_M_TXCSR_DMAMODE]":"");
++    return buf;
 +}
 +
 +/*
@@ -205267,7 +206401,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +static char *decode_ep0stage(uint8_t stage) {
 +    static char buff[64];
 +    uint8_t stallbit=stage&MUSB_END0_STAGE_STALL_BIT;
-+    
++
 +    stage=stage&~stage&MUSB_END0_STAGE_STALL_BIT;
 +    sprintf(buff, "%s%s", (stallbit)? "stall-" : "",
 +              (stage==MUSB_END0_STAGE_SETUP)
@@ -205277,7 +206411,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      (stage==MUSB_END0_STAGE_RX)
 +              ? "rx" :
 +      (stage==MUSB_END0_STAGE_STATUSIN)
-+              ? "statusin" : 
++              ? "statusin" :
 +      (stage==MUSB_END0_STAGE_STATUSOUT)
 +              ? "statusout" : "error");
 +    return buff;
@@ -205295,14 +206429,14 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 + * Dump core registers whose reads are non-destructive.
 + * @param base_addr
 + * @param multipoint
-+ * @param bEnd 
++ * @param bEnd
 + */
 +void udc_dump_regs(uint8_t* base_addr, int multipoint, uint8_t bEnd)
 +{
-+      
-+      
-+    MUSB_SELECTEND(base_addr, bEnd);    
-+      
++
++
++    MUSB_SELECTEND(base_addr, bEnd);
++
 +    if(!bEnd) {
 +              printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n",
 +                      MUSB_READCSR16(base_addr, MUSB_O_HDRC_CSR0, 0),
@@ -205323,7 +206457,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      MUSB_READCSR8(base_addr, MUSB_O_HDRC_TXINTERVAL, bEnd),
 +                      MUSB_READCSR16(base_addr, MUSB_O_HDRC_RXCOUNT, bEnd));
 +    }
-+    
++
 +    if( multipoint) {
 +              printk(KERN_INFO "    TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n",
 +                      MUSB_READ8(base_addr, MUSB_BUSCTL_OFFSET(bEnd, MUSB_O_HDRC_TXFUNCADDR)),
@@ -205340,21 +206474,21 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +
 +
 +/**
-+ * Enable the Controller 
++ * Enable the Controller
 + */
 +void musb_enable(void)
 +{
 +    uint8_t* udc_base = (uint8_t*)udc_base_addr;
-+      
++
 +    DBG(4, "<==\n");
-+      
++
 +      /*  Set INT enable registers, enable interrupts */
 +    MUSB_WRITE16(udc_base, MUSB_O_HDRC_INTRTXE, dev_context->end_mask);
 +    MUSB_WRITE16(udc_base, MUSB_O_HDRC_INTRRXE, dev_context->end_mask & 0xfffe);
 +      /* don't enable suspend mode! */
-+      MUSB_WRITE8(udc_base, MUSB_O_HDRC_INTRUSBE, 0xf7);      
-+      
-+      
++      MUSB_WRITE8(udc_base, MUSB_O_HDRC_INTRUSBE, 0xf7);
++
++
 +      DBG(3, "%s INTRUSBE reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRUSBE));
 +      DBG(3, "%s INTRTXE  reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRTXE));
 +      DBG(3, "%s INTRRXE  reg:0x%x \n", __FUNCTION__,MUSB_READ8(udc_base, MUSB_O_HDRC_INTRRXE));
@@ -205363,32 +206497,32 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +
 +
 +/**
-+ * Register the gadget driver. Used by the gadget when 
++ * Register the gadget driver. Used by the gadget when
 + * registering themselves with the controller.
 + *
 + *
 + * @param driver the gadget driver
-+ * @return <0 if error, 0 if everything is fine 
-+ */  
++ * @return <0 if error, 0 if everything is fine
++ */
 +int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 +{
 +      int retval;
-+      
++
 +      DBG(4, "<==\n");
-+      
-+      
++
++
 +      dev_context->driver=driver;
-+      
++
 +      do {
 +              struct usb_gadget *gadget = &dev_context->gadget;
 +              u8 *base_addr = ( u8 *)udc_base_addr;
-+              
++
 +              uint8_t power = MUSB_READ8(base_addr, MUSB_O_HDRC_POWER);
-+              
++
 +              gadget->name = driver->function;
 +              driver->driver.bus=0;
 +              gadget->dev.driver=&driver->driver;
-+              
++
 +              retval = device_add(&gadget->dev);
 +              if(retval)
 +              {
@@ -205396,12 +206530,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                              driver->driver.name, retval);
 +                      return retval;
 +              }
-+              
++
 +              gadget->speed = (power & MUSB_M_POWER_HSMODE) ? USB_SPEED_HIGH : USB_SPEED_FULL;
 +              gadget->is_dualspeed=1;
-+              
++
 +              retval=driver->bind( gadget );
-+              
++
 +              DBG(2, "bind complete with retval = %d\n",retval);
 +              if (retval) {
 +                      ERR("bind to driver %s failed --> %d\n",
@@ -205411,16 +206545,16 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +                      dev_context->driver = NULL;
 +                      return(retval);
 +              }
-+              
++
 +              DBG(2, "bind complete 2\n");
-+              
-+              musb_enable();  
++
++              musb_enable();
 +      } while (0);
 +      return 0;
 +}
 +
 +/**
-+ * Unregister the gadget driver. Used by the gadget when 
++ * Unregister the gadget driver. Used by the gadget when
 + * unregistering themselves from the controller.
 + *
 + * @param driver the gadget driver to unregister
@@ -205428,22 +206562,22 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 +{
 +    DBG(4, "<==\n" );
-+      
-+      
-+    INFO("unregistering gadget %s\n", driver->function); 
-+      
++
++
++    INFO("unregistering gadget %s\n", driver->function);
++
 +      /* shall I flush/abort the pending requests?? */
 +    if ( dev_context->driver ) {
-+              struct usb_gadget *gadget=&dev_context->gadget;         
-+              driver->unbind( gadget );                               
-+              
++              struct usb_gadget *gadget=&dev_context->gadget;
++              driver->unbind( gadget );
++
 +              gadget->dev.driver = NULL;
 +              dev_context->driver = NULL;
 +              device_del(&gadget->dev);
-+              
++
 +              DBG(4, "unregister driver\n" );
 +    }
-+    
++
 +    return 0;
 +}
 +
@@ -205462,7 +206596,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +      DECLARE_COMPLETION(done);
 +      if (!dev_context)
 +              return -ENODEV;
-+      
++
 +      dev_context->done = &done;
 +      nomadik_release_udc();
 +      return 0;
@@ -205470,9 +206604,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.c ../new/linux-2.6.20/
 +
 +EXPORT_SYMBOL(usb_gadget_register_driver);
 +EXPORT_SYMBOL(usb_gadget_unregister_driver);
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h
---- linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h      2008-09-17 13:23:34.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h
 @@ -0,0 +1,663 @@
 +/*
 + * linux/drivers/usb/nomadik/nomadik_udc.h
@@ -205491,7 +206624,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +#define       DMA_ADDR_INVALID        (~(dma_addr_t)0)
@@ -205522,7 +206655,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +
 +
 +/*
-+ *     MUSBMHDRC Register map 
++ *     MUSBMHDRC Register map
 + */
 +
 +/* Common USB registers */
@@ -205532,11 +206665,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +
 +#define MUSB_O_HDRC_INTRTX             0x02   /* 16-bit */
 +#define MUSB_O_HDRC_INTRRX       0x04
-+#define MUSB_O_HDRC_INTRTXE      0x06  
-+#define MUSB_O_HDRC_INTRRXE      0x08  
++#define MUSB_O_HDRC_INTRTXE      0x06
++#define MUSB_O_HDRC_INTRRXE      0x08
 +#define MUSB_O_HDRC_INTRUSB      0x0A   /* 8 bit */
 +#define MUSB_O_HDRC_INTRUSBE     0x0B   /* 8 bit */
-+#define MUSB_O_HDRC_FRAME        0x0C  
++#define MUSB_O_HDRC_FRAME        0x0C
 +#define MUSB_O_HDRC_INDEX        0x0E   /* 8 bit */
 +#define MUSB_O_HDRC_TESTMODE     0x0F   /* 8 bit */
 +
@@ -205591,7 +206724,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +
 +/* POWER */
 +
-+#define MUSB_M_POWER_ISOUPDATE   0x80 
++#define MUSB_M_POWER_ISOUPDATE   0x80
 +#define       MUSB_M_POWER_SOFTCONN    0x40
 +#define       MUSB_M_POWER_HSENAB          0x20
 +#define       MUSB_M_POWER_HSMODE          0x10
@@ -205605,7 +206738,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +#define MUSB_M_INTR_RESUME       0x02
 +#define MUSB_M_INTR_RESET        0x04
 +#define MUSB_M_INTR_BABBLE       0x04
-+#define MUSB_M_INTR_SOF          0x08 
++#define MUSB_M_INTR_SOF          0x08
 +#define MUSB_M_INTR_CONNECT      0x10
 +#define MUSB_M_INTR_DISCONNECT   0x20
 +#define MUSB_M_INTR_SESSREQ      0x40
@@ -205613,7 +206746,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +#define MUSB_M_INTR_EP0          0x01  /* FOR EP0 INTERRUPT */
 +
 +/* DEVCTL */
-+#define MUSB_M_DEVCTL_BDEVICE    0x80   
++#define MUSB_M_DEVCTL_BDEVICE    0x80
 +#define MUSB_M_DEVCTL_FSDEV      0x40
 +#define MUSB_M_DEVCTL_LSDEV      0x20
 +#define MUSB_M_DEVCTL_VBUS       0x18
@@ -205828,7 +206961,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +      u8                                                                              ackwait;
 +      u8                                                                              dma_channel;
 +      u8                                                                              is_tx;
-+      u8                                                                              end_number;     
++      u8                                                                              end_number;
 +      u16                                                                             dma_counter;
 +      int                                                                             lch;
 +      struct nomadik_udc                                              *udc;
@@ -205842,7 +206975,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +      u8                                              end_number;
 +      unsigned                        dma_bytes;
 +      unsigned                        mapped:1;
-+};       
++};
 +
 +struct nomadik_udc{
 +      spinlock_t lock;
@@ -205906,14 +207039,14 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +      DBG(4, "WRITE8(%p, %x, %02x)\n", base_ptr, offset, data); \
 +              wmb(); \
 +                  *(volatile uint8_t*)((unsigned long)base_ptr + offset) = data; \
-+      }   
++      }
 +
 +#undef MUSB_WRITE16
 +#define MUSB_WRITE16(base_ptr, offset, data) { \
 +      DBG(4, "WRITE16(%p, %x, %04x)\n", base_ptr, offset, data); \
 +              wmb(); \
 +                  *(volatile uint16_t*)((unsigned long)base_ptr + offset) = data; \
-+      }   
++      }
 +
 +
 +#undef MUSB_WRITE32
@@ -205921,7 +207054,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +      DBG(4, "WRITE32(%p, %x, %08x)\n", base_ptr, offset, data); \
 +              wmb(); \
 +                  *(volatile uint32_t*)((unsigned long)base_ptr + offset) = data; \
-+      }   
++      }
 +
 +#define MUSB_SELECTEND(base_ptr, end) \
 +    MUSB_WRITE8(base_ptr, MUSB_O_HDRC_INDEX, end)
@@ -205963,7 +207096,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +#define EP_SPIN_LOCK(_ep)     spin_lock( &(( struct nomadik_ep *)(_ep))->lock )
 +#define EP_SPIN_UNLOCK(_ep)   spin_unlock( &(( struct nomadik_ep *)(_ep))->lock )
 +
-+#define EP_SPIN_LOCK_IRQSAVE(_ep, _flags) spin_lock_irqsave(&(( struct nomadik_ep *)(_ep))->lock, _flags )    
++#define EP_SPIN_LOCK_IRQSAVE(_ep, _flags) spin_lock_irqsave(&(( struct nomadik_ep *)(_ep))->lock, _flags )
 +#define EP_SPIN_UNLOCK_IRQRESTORE(_ep, _flags) spin_unlock_irqrestore( &(( struct nomadik_ep *)(_ep))->lock, _flags)
 +
 +#ifdef  USE_DMA
@@ -206064,13 +207197,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +void service_tx_status_request(const struct usb_ctrlrequest *control_request_ptr);
 +int service_zero_data_request(struct nomadik_udc* dev_context, struct usb_ctrlrequest *control_request_ptr);
 +
-+/* 
++/*
 + * Gadget FIFO Operations
 + */
 +int nomadik_ep_fifo_status(struct usb_ep *ep);
 +void nomadik_ep_fifo_flush(struct usb_ep *ep);
 +void udc_unload_fifo(const uint8_t* base_ptr, uint8_t bEnd, uint16_t wcount, uint8_t* dest_ptr);
-+void udc_load_fifo(const uint8_t* base_ptr, uint8_t bEnd, uint16_t wcount, const uint8_t* pSource); 
++void udc_load_fifo(const uint8_t* base_ptr, uint8_t bEnd, uint16_t wcount, const uint8_t* pSource);
 +
 +/*
 + * Gadget Queue Operations
@@ -206134,12 +207267,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/nomadik_udc.h ../new/linux-2.6.20/
 +
 +static struct {
 +      spinlock_t lock;
-+      struct list_head req_list;      
++      struct list_head req_list;
 +} udc_scheduler_queue;
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/drivers/usb/nomadik/otg_func.c
---- linux-2.6.20/drivers/usb/nomadik/otg_func.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/otg_func.c 2008-09-17 13:23:34.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/otg_func.c
 @@ -0,0 +1,196 @@
 +/*
 + * linux/drivers/usb/nomadik/otg_func.c
@@ -206158,11 +207290,11 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +/**************************************************
-+            OTG - HNP and SRP 
++            OTG - HNP and SRP
 +**************************************************/
 +
 +#include <linux/delay.h>
@@ -206186,7 +207318,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +extern uint8_t b_hnp_suspend;
 +extern uint8_t b_hnp_init;
 +extern void otg_disconnect(MGC_LinuxCd *pThis);
-+extern void udc_disconnect_isr(void); 
++extern void udc_disconnect_isr(void);
 +extern void  del_timer_func(void);
 +uint8_t htd;
 +uint8_t host_a_idle=0;
@@ -206214,7 +207346,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +
 +void srp_initiate(void)
 +{
-+      uint8_t* pBase = (uint8_t*)udc_address->pRegs;  
++      uint8_t* pBase = (uint8_t*)udc_address->pRegs;
 +      uint8_t devctl=MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +    MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, (devctl|1));
 +
@@ -206229,13 +207361,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +      int temp = 0;
 +
 +      b_hnp_init=1;
-+    
++
 +      if(result<0)
 +      {
 +              printk("hnp feature failed \n");
 +              return ;
 +      }
-+      
++
 +      temp = MGC_Read8(pBase, MGC_O_HDRC_POWER);
 +      MGC_Write8(pBase, MGC_O_HDRC_POWER, temp | MGC_M_POWER_ENSUSPEND);
 +
@@ -206249,7 +207381,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +      devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +      devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +
-+      printk("devtcl after suspend  %x\n",devctl);    
++      printk("devtcl after suspend  %x\n",devctl);
 +      printk(" hnp_initiate \n ");
 +
 +}
@@ -206258,18 +207390,18 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +void driver_change_mode_handler(uint8_t role)
 +{
 +      uint8_t* pBase = (uint8_t*)udc_address->pRegs;
-+      uint8_t linestate = 0;  
++      uint8_t linestate = 0;
 +      uint8_t devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +      uint8_t power = 0;
 +
 +      /*1=Device to Host), 2= Host to Device */
 +      if ( role == 1){
 +              printk ("Device to Host \n");
-+              
++
 +              MGC_HdrcReadUlpiReg(udc_address, 0x15, &linestate);
 +              printk("line state   %x\n",linestate);
 +              printk("timer deleted \n");
-+      
++
 +              del_timer_func();
 +              devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +
@@ -206282,29 +207414,29 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +              mgc_hdrc_enable(udc_address);
 +
 +              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl | 0x01);
-+              devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);   
++              devctl = MGC_Read8(pBase, MGC_O_HDRC_DEVCTL);
 +              printk("devtcl setting host request and session  %x\n",devctl);
 +
-+              
++
 +              MGC_HdrcReadUlpiReg(udc_address, 0x15, &linestate);
 +              printk("line state end  %x\n",linestate);
-+              role=0; 
++              role=0;
 +      }
-+      /* Host to Device */    
++      /* Host to Device */
 +      else
-+      {       
++      {
 +              uint8_t power;
 +              printk ("Host to Device\n");
-+              
++
 +              MGC_HdrcReadUlpiReg(udc_address, 0x13, &htd);
 +                printk("temp in host to device%x \n",htd);
-+              
++
 +              del_timer_func();
 +              MGC_Write8(pBase, MGC_O_HDRC_DEVCTL, devctl & ~MGC_M_DEVCTL_HR);
 +              power=MGC_Read8(pBase, MGC_O_HDRC_POWER);
 +        MGC_Write8(pBase, MGC_O_HDRC_POWER,power | MGC_M_POWER_SOFTCONN );
 +              del_timer_func();
-+              
++
 +              MGC_HdrcReadUlpiReg(udc_address, 0x13, &htd);
 +        printk("temp in host to device end%x \n",htd);
 +
@@ -206337,9 +207469,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_func.c ../new/linux-2.6.20/dri
 +
 +
 +
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_pwm.c ../new/linux-2.6.20/drivers/usb/nomadik/otg_pwm.c
---- linux-2.6.20/drivers/usb/nomadik/otg_pwm.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/otg_pwm.c  2008-08-08 19:15:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/otg_pwm.c
 @@ -0,0 +1,46 @@
 +/*
 + * linux/drivers/usb/nomadik/otg_pwm.c
@@ -206358,7 +207489,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_pwm.c ../new/linux-2.6.20/driv
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +/***********************************
@@ -206382,14 +207513,13 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/otg_pwm.c ../new/linux-2.6.20/driv
 +{
 +      DBG(2, "<==\n");
 +      printk(" otg_wakeup invoked \n");
-+ 
++
 +    nomadik_gpio_altfuncenable(GPIO_ALT_USB_OTG,"OTG");
 +
 +      direct_bus_init();
 +}
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_arc.h ../new/linux-2.6.20/drivers/usb/nomadik/plat_arc.h
---- linux-2.6.20/drivers/usb/nomadik/plat_arc.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/plat_arc.h 2008-07-28 15:21:12.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/plat_arc.h
 @@ -0,0 +1,92 @@
 +/*
 + * linux/drivers/usb/nomadik/plat_arc.h
@@ -206408,7 +207538,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_arc.h ../new/linux-2.6.20/dri
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__
@@ -206483,9 +207613,8 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_arc.h ../new/linux-2.6.20/dri
 +}
 +
 +#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/drivers/usb/nomadik/plat_cnf.h
---- linux-2.6.20/drivers/usb/nomadik/plat_cnf.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/usb/nomadik/plat_cnf.h 2008-08-08 19:15:36.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/usb/nomadik/plat_cnf.h
 @@ -0,0 +1,208 @@
 +/*
 + * usb/nomadik/plat_cnf.h
@@ -206504,22 +207633,22 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/dri
 + *
 + * 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 
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +#ifndef __MUSB_LINUX_CONFIG_H__
 +#define __MUSB_LINUX_CONFIG_H__
 +
 +/* MUSB_AHB_ID is now passed as argument   */
-+ 
++
 +#ifdef MUSB_STATIC_CONFIG
 +
 +/*
-+ * Get core configuration from a header converted (by cfg_conv) 
++ * Get core configuration from a header converted (by cfg_conv)
 + * from the Verilog config file generated by the core config utility
 + */
 +/** Core configuration */
-+#ifdef MUSB_HDR_CCNF_FILE 
++#ifdef MUSB_HDR_CCNF_FILE
 +#include CONFIG_USB_INVENTRA_MUSB_HDR_CCNF_FILE
 +#else
 +
@@ -206527,12 +207656,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/dri
 +#define MUSB_C_NUM_EPS 16
 +#endif
 +
-+/* 
++/*
 + * Handle dynamic FIFO sizing in a way that doesn't create more code
 + * (but could make your brain hurt)
 + */
 +#ifdef MUSB_C_DYNFIFO_DEF
-+#define MGC_DFIFO_TOTAL (1 << (MUSB_C_RAM_BITS + 2)) 
++#define MGC_DFIFO_TOTAL (1 << (MUSB_C_RAM_BITS + 2))
 +
 +/* values for the SZ field */
 +#define MGC_BLK_SZ 6  /* 512 bytes */
@@ -206551,7 +207680,7 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/dri
 +#define MGC_ISO_RX_SZ 7       /* 1024 bytes for normal-bandwidth */
 +#endif
 +
-+/* 
++/*
 + * Define desires by subtracting all, so impossible ones become negatives
 + */
 +#if MUSB_C_NUM_EPS > 2
@@ -206563,12 +207692,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/dri
 +/* no good; try with a single-buffered bulk */
 +#undef MGC_BLK_DB
 +#define MGC_BLK_DB 0
-+#undef MGC_DFIFO_ISO_TX 
++#undef MGC_DFIFO_ISO_TX
 +#define MGC_DFIFO_ISO_TX (MGC_DFIFO_TOTAL - (1 << (MGC_ISO_TX_SZ+4)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3))))
 +#endif
 +#if MGC_DFIFO_ISO_TX < 0
 +/* still no good; try single-buffered isoch Tx */
-+#undef MGC_DFIFO_ISO_TX 
++#undef MGC_DFIFO_ISO_TX
 +#undef MGC_ISO_TX_DB
 +#define MGC_ISO_TX_DB 0
 +#define MGC_DFIFO_ISO_TX (MGC_DFIFO_TOTAL - (1 << (MGC_ISO_TX_SZ+3)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3))))
@@ -206583,12 +207712,12 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/dri
 +/* no good; try with a single-buffered bulk */
 +#undef MGC_BLK_DB
 +#define MGC_BLK_DB 0
-+#undef MGC_DFIFO_ISO_RX 
++#undef MGC_DFIFO_ISO_RX
 +#define MGC_DFIFO_ISO_RX (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - (1 << (MGC_ISO_RX_SZ+4)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3))))
 +#endif
 +#if MGC_DFIFO_ISO_RX < 0
 +/* still no good; try single-buffered isoch Rx */
-+#undef MGC_DFIFO_ISO_RX 
++#undef MGC_DFIFO_ISO_RX
 +#undef MGC_ISO_RX_DB
 +#define MGC_ISO_RX_DB 0
 +#define MGC_DFIFO_ISO_RX (MGC_DFIFO_TOTAL - MGC_DFIFO_ISO_TX_SIZE - (1 << (MGC_ISO_RX_SZ+3)) - (1 << (MGC_BLK_SZ+3+MGC_BLK_DB)) - (1 << (MGC_CTL_SZ+3)) - ((MUSB_C_NUM_EPS - 3) * (1 << (MGC_ALL_SZ+3))))
@@ -206695,10 +207824,25 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/plat_cnf.h ../new/linux-2.6.20/dri
 +extern MUSB_LinuxController MUSB_aLinuxController[];
 +
 +#endif        /* multiple inclusion protection */
-diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/video/amba-clcd.c
---- linux-2.6.20/drivers/video/amba-clcd.c     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/amba-clcd.c      2008-11-19 16:47:04.000000000 +0530
-@@ -9,6 +9,10 @@
+--- linux-2.6.20.orig/drivers/video/Makefile
++++ linux-2.6.20/drivers/video/Makefile
+@@ -28,10 +28,11 @@ obj-$(CONFIG_FB_CLPS711X)         += clp
+ obj-$(CONFIG_FB_CYBER)            += cyberfb.o
+ obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
+ obj-$(CONFIG_FB_PM2)              += pm2fb.o
+ obj-$(CONFIG_FB_PM3)            += pm3fb.o
++obj-$(CONFIG_FB_NOMADIK_ACCLN)          += nomadik/
+ obj-$(CONFIG_FB_MATROX)                 += matrox/
+ obj-$(CONFIG_FB_RIVA)           += riva/ vgastate.o
+ obj-$(CONFIG_FB_NVIDIA)                 += nvidia/
+ obj-$(CONFIG_FB_ATY)            += aty/ macmodes.o
+ obj-$(CONFIG_FB_ATY128)                 += aty/ macmodes.o
+--- linux-2.6.20.orig/drivers/video/amba-clcd.c
++++ linux-2.6.20/drivers/video/amba-clcd.c
+@@ -7,10 +7,14 @@
+  * This file is subject to the terms and conditions of the GNU General Public
+  * License.  See the file COPYING in the main directory of this archive
   * for more details.
   *
   *  ARM PrimeCell PL110 Color LCD Controller
@@ -206709,7 +207853,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
   */
  #include <linux/module.h>
  #include <linux/kernel.h>
-@@ -24,18 +28,28 @@
+ #include <linux/errno.h>
+ #include <linux/string.h>
+@@ -22,22 +26,32 @@
+ #include <linux/ioport.h>
+ #include <linux/list.h>
  #include <linux/amba/bus.h>
  #include <linux/amba/clcd.h>
  #include <linux/clk.h>
@@ -206744,7 +207892,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
  static inline void clcdfb_sleep(unsigned int ms)
  {
        if (in_atomic()) {
-@@ -117,6 +131,7 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
+               mdelay(ms);
+       } else {
+@@ -115,10 +129,11 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
+ {
+       int ret = 0;
  
        memset(&var->transp, 0, sizeof(var->transp));
  
@@ -206752,7 +207904,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
        var->red.msb_right = 0;
        var->green.msb_right = 0;
        var->blue.msb_right = 0;
-@@ -140,9 +155,12 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
+       switch (var->bits_per_pixel) {
+@@ -138,13 +153,16 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
+               var->blue.length = 5;
+               /*
                 * Green length can be 5 or 6 depending whether
                 * we're operating in RGB555 or RGB565 mode.
                 */
@@ -206767,7 +207923,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
        case 32:
                if (fb->panel->cntl & CNTL_LCDTFT) {
                        var->red.length         = 8;
-@@ -161,14 +179,23 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
+                       var->green.length       = 8;
+                       var->blue.length        = 8;
+@@ -159,18 +177,27 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
+        * >= 16bpp displays have separate colour component bitfields
+        * encoded in the pixel data.  Calculate their position from
         * the bitfield length defined above.
         */
        if (ret == 0 && var->bits_per_pixel >= 16) {
@@ -206792,7 +207952,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
                }
        }
  
-@@ -207,6 +234,7 @@ static int clcdfb_set_par(struct fb_info
+       return ret;
+ }
+@@ -205,10 +232,11 @@ static int clcdfb_set_par(struct fb_info
+       if (fb->fb.var.bits_per_pixel <= 8)
+               fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
        else
                fb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
  
@@ -206800,7 +207964,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
        fb->board->decode(fb, &regs);
  
        clcdfb_disable(fb);
-@@ -244,10 +272,6 @@ static inline u32 convert_bitfield(int v
+       writel(regs.tim0, fb->regs + CLCD_TIM0);
+@@ -242,14 +270,10 @@ static inline u32 convert_bitfield(int v
+       unsigned int mask = (1 << bf->length) - 1;
        return (val >> (16 - bf->length) & mask) << bf->offset;
  }
  
@@ -206811,7 +207979,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
  static int
  clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
                 unsigned int blue, unsigned int transp, struct fb_info *info)
-@@ -263,11 +287,19 @@ clcdfb_setcolreg(unsigned int regno, uns
+ {
+       struct clcd_fb *fb = to_clcd(info);
+@@ -261,15 +285,23 @@ clcdfb_setcolreg(unsigned int regno, uns
+                                 convert_bitfield(red, &fb->fb.var.red);
        if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
                int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3);
                u32 val, mask, newval;
@@ -206833,7 +208005,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
                /*
                 * 3.2.11: if we're configured for big endian
                 * byte order, the palette entries are swapped.
-@@ -282,14 +314,24 @@ clcdfb_setcolreg(unsigned int regno, uns
+                */
+               if (fb->clcd_cntl & CNTL_BEBO)
+@@ -280,27 +312,38 @@ clcdfb_setcolreg(unsigned int regno, uns
+                       mask = 0x0000ffff;
+               } else {
                        mask = 0xffff0000;
                }
  
@@ -206859,7 +208035,8 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
   *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
   *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
   *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
-@@ -298,7 +340,8 @@ clcdfb_setcolreg(unsigned int regno, uns
+  *  to e.g. a video mode which doesn't support it. Implements VESA suspend
+  *  and powerdown modes on hardware that supports disabling hsync/vsync:
   *    blank_mode == 2: suspend vsync
   *    blank_mode == 3: suspend hsync
   *    blank_mode == 4: powerdown
@@ -206869,7 +208046,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
  static int clcdfb_blank(int blank_mode, struct fb_info *info)
  {
        struct clcd_fb *fb = to_clcd(info);
-@@ -311,8 +354,7 @@ static int clcdfb_blank(int blank_mode, 
+       if (blank_mode != 0) {
+@@ -309,12 +352,11 @@ static int clcdfb_blank(int blank_mode, 
+               clcdfb_enable(fb, fb->clcd_cntl);
+       }
        return 0;
  }
  
@@ -206879,7 +208060,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
  {
        struct clcd_fb *fb = to_clcd(info);
        unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT;
-@@ -363,7 +405,7 @@ static int clcdfb_register(struct clcd_f
+       int ret = -EINVAL;
+@@ -361,11 +403,11 @@ static int clcdfb_register(struct clcd_f
+       fb->fb.fbops            = &clcdfb_ops;
        fb->fb.flags            = FBINFO_FLAG_DEFAULT;
        fb->fb.pseudo_palette   = fb->cmap;
  
@@ -206888,7 +208073,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
        fb->fb.fix.type         = FB_TYPE_PACKED_PIXELS;
        fb->fb.fix.type_aux     = 0;
        fb->fb.fix.xpanstep     = 0;
-@@ -432,6 +474,26 @@ static int clcdfb_register(struct clcd_f
+       fb->fb.fix.ypanstep     = 0;
+       fb->fb.fix.ywrapstep    = 0;
+@@ -430,10 +472,30 @@ static int clcdfb_register(struct clcd_f
+       clk_put(fb->clk);
+  out:
        return ret;
  }
  
@@ -206915,7 +208104,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
  static int clcdfb_probe(struct amba_device *dev, void *id)
  {
        struct clcd_board *board = dev->dev.platform_data;
-@@ -449,7 +511,8 @@ static int clcdfb_probe(struct amba_devi
+       struct clcd_fb *fb;
+       int ret;
+@@ -447,11 +509,12 @@ static int clcdfb_probe(struct amba_devi
+               goto out;
+       }
  
        fb = kmalloc(sizeof(struct clcd_fb), GFP_KERNEL);
        if (!fb) {
@@ -206925,7 +208118,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
                ret = -ENOMEM;
                goto free_region;
        }
-@@ -481,6 +544,7 @@ static int clcdfb_remove(struct amba_dev
+       memset(fb, 0, sizeof(struct clcd_fb));
+@@ -479,10 +542,11 @@ static int clcdfb_probe(struct amba_devi
+ static int clcdfb_remove(struct amba_device *dev)
  {
        struct clcd_fb *fb = amba_get_drvdata(dev);
  
@@ -206933,7 +208130,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
        amba_set_drvdata(dev, NULL);
  
        clcdfb_disable(fb);
-@@ -499,8 +563,8 @@ static int clcdfb_remove(struct amba_dev
+       unregister_framebuffer(&fb->fb);
+       iounmap(fb->regs);
+@@ -497,12 +561,12 @@ static int clcdfb_remove(struct amba_dev
+       return 0;
+ }
  
  static struct amba_id clcdfb_id_table[] = {
        {
@@ -206944,7 +208145,11 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
        },
        { 0, 0 },
  };
-@@ -512,6 +576,11 @@ static struct amba_driver clcd_driver = 
+ static struct amba_driver clcd_driver = {
+@@ -510,10 +574,15 @@ static struct amba_driver clcd_driver = 
+               .name   = "clcd-pl11x",
+       },
        .probe          = clcdfb_probe,
        .remove         = clcdfb_remove,
        .id_table       = clcdfb_id_table,
@@ -206956,10 +208161,13 @@ diff -Nauprw linux-2.6.20/drivers/video/amba-clcd.c ../new/linux-2.6.20/drivers/
  };
  
  static int __init amba_clcdfb_init(void)
-diff -Nauprw linux-2.6.20/drivers/video/fbmem.c ../new/linux-2.6.20/drivers/video/fbmem.c
---- linux-2.6.20/drivers/video/fbmem.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/fbmem.c  2007-11-21 11:51:41.000000000 +0530
-@@ -234,7 +234,6 @@ static void fb_set_logo_directpalette(st
+ {
+       if (fb_get_options("ambafb", NULL))
+--- linux-2.6.20.orig/drivers/video/fbmem.c
++++ linux-2.6.20/drivers/video/fbmem.c
+@@ -232,11 +232,10 @@ static void fb_set_logo_directpalette(st
+                                            const struct linux_logo *logo,
+                                            u32 *palette)
  {
        int redshift, greenshift, blueshift;
        int i;
@@ -206967,20 +208175,28 @@ diff -Nauprw linux-2.6.20/drivers/video/fbmem.c ../new/linux-2.6.20/drivers/vide
        redshift = info->var.red.offset;
        greenshift = info->var.green.offset;
        blueshift = info->var.blue.offset;
-diff -Nauprw linux-2.6.20/drivers/video/Makefile ../new/linux-2.6.20/drivers/video/Makefile
---- linux-2.6.20/drivers/video/Makefile        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/Makefile 2007-11-21 11:51:42.000000000 +0530
-@@ -30,6 +30,7 @@ obj-$(CONFIG_FB_CYBER2000)        += cyb
- obj-$(CONFIG_FB_PM2)              += pm2fb.o
- obj-$(CONFIG_FB_PM3)            += pm3fb.o
  
-+obj-$(CONFIG_FB_NOMADIK_ACCLN)          += nomadik/
- obj-$(CONFIG_FB_MATROX)                 += matrox/
- obj-$(CONFIG_FB_RIVA)           += riva/ vgastate.o
- obj-$(CONFIG_FB_NVIDIA)                 += nvidia/
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/debug.h
---- linux-2.6.20/drivers/video/nomadik/hcl/debug.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/debug.h      2007-11-21 11:51:42.000000000 +0530
+       for (i = 32; i < logo->clutsize; i++)
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/Makefile
+@@ -0,0 +1,15 @@
++#
++# Makefile for the Nomadik framebuffer driver
++#
++ifdef CONFIG_FB_NOMADIK_ACCLN
++CFLAGS += -D__STN_8815 -D__RELEASE
++
++obj-$(CONFIG_FB_NOMADIK_ACCLN)    += nomadikfb.o
++#obj-m    += nomadikfb.ko
++
++endif
++
++nomadikfb-y                       := sga_main.o sga_ioctlfns.o hcl/sga.o hcl/sga_irq.o
++
++
++nomadikfb-objs                    := $(nomadikfb-y)
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/debug.h
 @@ -0,0 +1,313 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -207029,10 +208245,10 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +#define DBG_HCL_MAJOR_ID 2
 +#define DBG_HCL_MINOR_ID 0
 +
-+ 
++
 +/* Store a submitter ID, unique for each HCL. */
 +
-+typedef enum 
++typedef enum
 +{
 +    UNKNOWN_HCL_DBG_ID,
 +    APPLI_DBG_ID,
@@ -207075,7 +208291,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +    HASH_HCL_DBG_ID,
 +    RNG_HCL_DBG_ID,
 +    MSHC_HCL_DBG_ID,
-+    SKE_HCL_DBG_ID,  
++    SKE_HCL_DBG_ID,
 +    SGA_HCL_DBG_ID,
 +    CRYP_HCL_DBG_ID,
 +    HPI_HCL_DBG_ID
@@ -207089,7 +208305,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +#define DEBUG_LEVEL4 DBGL_HCL_DEV
 +
 +
-+typedef enum 
++typedef enum
 +{
 + DBGL_OFF                             = 0,
 + DBGL_PUBLIC_FUNC_IN  = MASK_BIT0,
@@ -207126,13 +208342,13 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +} t_dbg_level;
 +
 +
-+ 
-+#ifdef __DEBUG  
-+ 
++
++#ifdef __DEBUG
++
 +/*--------------------------------------------------------------------------*
 + * Macro                                                                                                                      *
 + *--------------------------------------------------------------------------*/
-+ 
++
 +/* Begin of Private definitions */
 +
 +/*
@@ -207167,22 +208383,22 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +#define DBGEXIT1(cr,ch,p1)                                                                                            \
 +        ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), 0, 0, 0, 0, 0,cr):              \
-+          (0)     
-+          
++          (0)
++
 +#define DBGEXIT2(cr,ch,p1,p2)                                                                                     \
 +        ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), 0, 0, 0, 0,cr):            \
-+          (0)     
-+          
++          (0)
++
 +#define DBGEXIT3(cr,ch,p1,p2,p3)                                                                                  \
 +        ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), 0, 0, 0,cr):          \
 +          (0)
-+          
++
 +#define DBGEXIT4(cr,ch,p1,p2,p3,p4)                                                                               \
 +        ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), 0, 0,cr):                \
-+          (0)                     
++          (0)
 +
 +
 +#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5)                                                                            \
@@ -207193,35 +208409,35 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6)                                                                     \
 +        ((DBGL_PUBLIC_FUNC_OUT & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Exiting",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), (unsigned long)(p6),cr):        \
-+          (0)         
-+          
++          (0)
++
 +/* Enter macro's */
 +
 +#define DBGENTER0()                                                                 \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                  \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, 0, "Entering Function",0, 0, 0, 0, 0, 0, 0):     \
-+          (0)     
++          (0)
 +
 +#define DBGENTER1(ch,p1)                                                            \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                  \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), 0, 0, 0, 0, 0,0):   \
 +          (0)
-+          
++
 +#define DBGENTER2(ch,p1,p2)                                                         \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                  \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), 0, 0, 0, 0, 0):  \
 +          (0)
-+          
++
 +#define DBGENTER3(ch,p1,p2,p3)                                                      \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                  \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), 0, 0, 0, 0): \
 +          (0)
-+          
++
 +#define DBGENTER4(ch,p1,p2,p3,p4)                                                   \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                  \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), 0, 0, 0):\
-+          (0) 
-+          
++          (0)
++
 +#define DBGENTER5(ch,p1,p2,p3,p4,p5)                                                 \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), 0, 0):\
@@ -207230,7 +208446,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6)                                              \
 +          ((DBGL_PUBLIC_FUNC_IN & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                   \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "Entering Function",(unsigned long)(p1), (unsigned long)(p2), (unsigned long)(p3), (unsigned long)(p4), (unsigned long)(p5), (unsigned long)(p6), 0):\
-+          (0)                                             
++          (0)
 +
 +
 +#define DBGEXIT  DBGEXIT0
@@ -207240,44 +208456,44 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +          ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                        \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",0, 0, 0, 0, 0, 0, 0):                   \
 +          (0)
-+          
++
 +#define DBGPRINTHEX(dbg_level,ch, uint32)                                                         \
 +          ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                        \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",(unsigned long)uint32, 0, 0, 0, 0, 0, 0):   \
-+          (0) 
++          (0)
 +
 +#define DBGPRINTDEC(dbg_level,ch, uint32)                                                         \
 +          ((dbg_level & MY_DEBUG_LEVEL_VAR_NAME) != DBGL_OFF)?                        \
 +          logMsg(MY_DEBUG_ID, DBGFUNCNAME, ch, "",(unsigned long)uint32, 0, 0, 0, 0, 0, 0):   \
-+          (0)                 
++          (0)
 +
 +#endif /* __DEBUG */
 +
 +#ifdef __RELEASE
 +
-+#define DBGEXIT(cr)  
-+#define DBGEXIT0(cr) 
-+#define DBGEXIT1(cr,ch,p1) 
-+#define DBGEXIT2(cr,ch,p1,p2) 
-+#define DBGEXIT3(cr,ch,p1,p2,p3) 
-+#define DBGEXIT4(cr,ch,p1,p2,p3,p4) 
-+#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5)  
-+#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6) 
++#define DBGEXIT(cr)
++#define DBGEXIT0(cr)
++#define DBGEXIT1(cr,ch,p1)
++#define DBGEXIT2(cr,ch,p1,p2)
++#define DBGEXIT3(cr,ch,p1,p2,p3)
++#define DBGEXIT4(cr,ch,p1,p2,p3,p4)
++#define DBGEXIT5(cr,ch,p1,p2,p3,p4,p5)
++#define DBGEXIT6(cr,ch,p1,p2,p3,p4,p5,p6)
 +
-+#define DBGENTER() 
++#define DBGENTER()
 +#define DBGENTER0()
-+#define DBGENTER1(ch,p1)                              
-+#define DBGENTER2(ch,p1,p2)                           
-+#define DBGENTER3(ch,p1,p2,p3)                        
-+#define DBGENTER4(ch,p1,p2,p3,p4)             
-+#define DBGENTER5(ch,p1,p2,p3,p4,p5)  
-+#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6)       
++#define DBGENTER1(ch,p1)
++#define DBGENTER2(ch,p1,p2)
++#define DBGENTER3(ch,p1,p2,p3)
++#define DBGENTER4(ch,p1,p2,p3,p4)
++#define DBGENTER5(ch,p1,p2,p3,p4,p5)
++#define DBGENTER6(ch,p1,p2,p3,p4,p5,p6)
 +
 +
 +
-+#define DBGPRINT(dbg_level,dbg_string)             
-+#define DBGPRINTHEX(dbg_level,dbg_string,uint32) 
-+#define DBGPRINTDEC(dbg_level,dbg_string,uint32) 
++#define DBGPRINT(dbg_level,dbg_string)
++#define DBGPRINTHEX(dbg_level,dbg_string,uint32)
++#define DBGPRINTDEC(dbg_level,dbg_string,uint32)
 +
 +#endif /* __RELEASE  */
 +
@@ -207295,9 +208511,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/debug.h ../new/linux-2.6.20/
 +/* End of file - debug.h */
 +
 +
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h
---- linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h
 @@ -0,0 +1,286 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -207317,14 +208532,14 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 + * Description        : Basic definitions
 + *
 + *****************************************************************************/
-+ 
++
 +#ifndef _HCL_DEFS_H
 +#define _HCL_DEFS_H
 +
 +#include "platform_os.h"
 +
 +/*-----------------------------------------------------------------------------
-+ * Type definition                                                               
++ * Type definition
 + *---------------------------------------------------------------------------*/
 +typedef unsigned char t_uint8;
 +typedef signed char t_sint8;
@@ -207343,7 +208558,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +
 +typedef unsigned int t_bitfield;
 +
-+#if !defined(FALSE) &&  !defined(TRUE)   
++#if !defined(FALSE) &&  !defined(TRUE)
 +typedef enum {FALSE, TRUE} t_bool;
 +#else /* FALSE & TRUE already defined */
 +typedef enum {BOOL_FALSE, BOOL_TRUE} t_bool;
@@ -207360,10 +208575,10 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +
 +/*
 + * Global frequency enumuration
-+ * Added to avoid frequency conversion function which is required to convert one HCL 
++ * Added to avoid frequency conversion function which is required to convert one HCL
 + * frequency enumuration values to another HCL frequency enumuration values.
 + */
-+ 
++
 +typedef enum {
 +      HCL_FREQ_NOT_SUPPORTED=-1,
 +      HCL_FREQ_8KHZ ,
@@ -207398,7 +208613,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +      HCL_FREQ_22MHZ,
 +      HCL_FREQ_24MHZ,
 +      HCL_FREQ_48MHZ
-+} t_frequency; 
++} t_frequency;
 +
 +
 +
@@ -207423,7 +208638,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +
 +
 +/*-----------------------------------------------------------------------------
-+ * Keyword definition 
++ * Keyword definition
 + *---------------------------------------------------------------------------*/
 +#define PUBLIC        /* Extern by default */
 +#define PRIVATE      static
@@ -207474,42 +208689,42 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +#define MASK_NULL8    0x00
 +#define MASK_NULL16   0x0000
 +#define MASK_NULL32   0x00000000
-+#define MASK_ALL8     0xFF 
-+#define MASK_ALL16    0xFFFF 
++#define MASK_ALL8     0xFF
++#define MASK_ALL16    0xFFFF
 +#define MASK_ALL32    0xFFFFFFFF
 +
 +#define MASK_BIT0     (1UL<<0)
-+#define MASK_BIT1     (1UL<<1) 
-+#define MASK_BIT2     (1UL<<2) 
-+#define MASK_BIT3     (1UL<<3) 
-+#define MASK_BIT4     (1UL<<4) 
-+#define MASK_BIT5     (1UL<<5) 
-+#define MASK_BIT6     (1UL<<6) 
-+#define MASK_BIT7     (1UL<<7) 
-+#define MASK_BIT8     (1UL<<8) 
-+#define MASK_BIT9     (1UL<<9) 
-+#define MASK_BIT10    (1UL<<10) 
-+#define MASK_BIT11    (1UL<<11) 
-+#define MASK_BIT12    (1UL<<12) 
-+#define MASK_BIT13    (1UL<<13) 
-+#define MASK_BIT14    (1UL<<14) 
-+#define MASK_BIT15    (1UL<<15) 
-+#define MASK_BIT16    (1UL<<16) 
-+#define MASK_BIT17    (1UL<<17) 
-+#define MASK_BIT18    (1UL<<18) 
-+#define MASK_BIT19    (1UL<<19) 
-+#define MASK_BIT20    (1UL<<20) 
++#define MASK_BIT1     (1UL<<1)
++#define MASK_BIT2     (1UL<<2)
++#define MASK_BIT3     (1UL<<3)
++#define MASK_BIT4     (1UL<<4)
++#define MASK_BIT5     (1UL<<5)
++#define MASK_BIT6     (1UL<<6)
++#define MASK_BIT7     (1UL<<7)
++#define MASK_BIT8     (1UL<<8)
++#define MASK_BIT9     (1UL<<9)
++#define MASK_BIT10    (1UL<<10)
++#define MASK_BIT11    (1UL<<11)
++#define MASK_BIT12    (1UL<<12)
++#define MASK_BIT13    (1UL<<13)
++#define MASK_BIT14    (1UL<<14)
++#define MASK_BIT15    (1UL<<15)
++#define MASK_BIT16    (1UL<<16)
++#define MASK_BIT17    (1UL<<17)
++#define MASK_BIT18    (1UL<<18)
++#define MASK_BIT19    (1UL<<19)
++#define MASK_BIT20    (1UL<<20)
 +#define MASK_BIT21    (1UL<<21)
-+#define MASK_BIT22    (1UL<<22) 
-+#define MASK_BIT23    (1UL<<23) 
-+#define MASK_BIT24    (1UL<<24) 
-+#define MASK_BIT25    (1UL<<25) 
-+#define MASK_BIT26    (1UL<<26) 
-+#define MASK_BIT27    (1UL<<27) 
-+#define MASK_BIT28    (1UL<<28) 
-+#define MASK_BIT29    (1UL<<29) 
++#define MASK_BIT22    (1UL<<22)
++#define MASK_BIT23    (1UL<<23)
++#define MASK_BIT24    (1UL<<24)
++#define MASK_BIT25    (1UL<<25)
++#define MASK_BIT26    (1UL<<26)
++#define MASK_BIT27    (1UL<<27)
++#define MASK_BIT28    (1UL<<28)
++#define MASK_BIT29    (1UL<<29)
 +#define MASK_BIT30    (1UL<<30)
-+#define MASK_BIT31    (1UL<<31) 
++#define MASK_BIT31    (1UL<<31)
 +
 +/*-----------------------------------------------------------------------------
 + * quartet shift definition
@@ -207544,7 +208759,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +#define MASK_BYTE1      (MASK_BYTE << SHIFT_BYTE1)
 +#define MASK_BYTE2      (MASK_BYTE << SHIFT_BYTE2)
 +#define MASK_BYTE3      (MASK_BYTE << SHIFT_BYTE3)
-+ 
++
 +/*-----------------------------------------------------------------------------
 + * Halfword shift definition
 + *---------------------------------------------------------------------------*/
@@ -207559,8 +208774,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 + *---------------------------------------------------------------------------*/
 + #define ONE_KB        (1024)
 + #define ONE_MB        (ONE_KB * ONE_KB)
-+ 
-+ 
++
++
 +/*-----------------------------------------------------------------------------
 + * Address translation macros declaration
 + *---------------------------------------------------------------------------*/
@@ -207585,9 +208800,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/hcl_defs.h ../new/linux-2.6.
 +#endif /* _HCL_DEFS_H */
 +
 +/* End of file hcl_defs.h */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h
---- linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h        2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h
 @@ -0,0 +1,79 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -207668,9 +208882,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/platform_os.h ../new/linux-2
 +typedef signed long long t_sint64;
 +
 +#endif /* __INC_PLATFORM_OS_H */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.c ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.c
---- linux-2.6.20/drivers/video/nomadik/hcl/sga.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.c        2008-10-06 12:06:22.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/sga.c
 @@ -0,0 +1,3161 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -210833,9 +212046,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.c ../new/linux-2.6.20/dr
 +    DBGEXIT0(SGA_OK);
 +    return(SGA_OK);
 +}
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.h
---- linux-2.6.20/drivers/video/nomadik/hcl/sga.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga.h        2008-10-06 12:06:22.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/sga.h
 @@ -0,0 +1,937 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -210852,7 +212064,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.h ../new/linux-2.6.20/dr
 + * You should have received a copy of the GNU Lesser General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
-+ * Description        : Public Header file of Smart Graphic Accelarator (SGA) module 
++ * Description        : Public Header file of Smart Graphic Accelarator (SGA) module
 + *
 + *****************************************************************************/
 +#ifndef _SGA_H_
@@ -211774,9 +212986,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga.h ../new/linux-2.6.20/dr
 +}   /* allow C++ to use these headers */
 +#endif /* __cplusplus */
 +#endif /* _SGA_H_ */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c
---- linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c    2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c
 @@ -0,0 +1,206 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -211793,7 +213004,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 + * You should have received a copy of the GNU Lesser General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
-+ * Description        : This module provides interrupt routines for the 
++ * Description        : This module provides interrupt routines for the
 + *                            NOMADIK SGA Controller
 + *****************************************************************************/
 +/*--------------------------------------------------------------------------*
@@ -211818,17 +213029,17 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 +PRIVATE t_sga_registers *gp_sga_registers;
 +
 +/****************************************************************************
-+* NAME:        SGA_SetBaseAddress()                                                                                           
++* NAME:        SGA_SetBaseAddress()
 +*---------------------------------------------------------------------------*
-+* DESCRIPTION   : This routine initializes SGA HCL.           
-+* PARAMETERS    :                                                                                     
-+* IN            : t_logical_address  base_address     
++* DESCRIPTION   : This routine initializes SGA HCL.
++* PARAMETERS    :
++* IN            : t_logical_address  base_address
 +* INOUT         : None
 +* OUT           : None
-+* RETURN VALUE  : none                                                                                        
++* RETURN VALUE  : none
 +* TYPE       : Public
 +*---------------------------------------------------------------------------
-+* REENTRANCY: NA                                                                                                              
++* REENTRANCY: NA
 +*****************************************************************************/
 +PUBLIC void SGA_SetBaseAddress(t_logical_address base_address)
 +{
@@ -211840,7 +213051,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 +* NAME:     SGA_EnableIRQSrc()
 +*---------------------------------------------------------------------------
 +* DESCRIPTION   :This routine allows to enable a specific interrupt
-+* PARAMETERS    :                                                                                     
++* PARAMETERS    :
 +* IN            : t_sga_int_to_core  core   define the processor to route this
 +*                                           interrupt
 +*                 irq_src: ORed value of interrupt sources to be enabled.
@@ -211850,7 +213061,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 +* RETURN VALUE  : none
 +* TYPE          : Public
 +*--------------------------------------------------------------------------
-+*REENTRANCY: NA                                                                                                               
++*REENTRANCY: NA
 +*****************************************************************************/
 +PUBLIC void SGA_EnableIRQSrc(IN t_sga_int_to_core core, IN t_sga_irq_src irq_src)
 +{
@@ -211870,7 +213081,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 +* NAME:     SGA_DisableIRQSrc()
 +*---------------------------------------------------------------------------
 +* DESCRIPTION   :This routine allows to disable a specific interrupt
-+* PARAMETERS    :                                                                                     
++* PARAMETERS    :
 +* IN            :t_sga_int_to_core  core   define the processor to route this
 +*                                           interrupt
 +*                irq_src: ORed value of interrupt sources to be disabled.
@@ -211880,7 +213091,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 +* RETURN VALUE  : none
 +* TYPE          : Public
 +*--------------------------------------------------------------------------
-+*REENTRANCY: NA                                                                                                               
++*REENTRANCY: NA
 +*****************************************************************************/
 +PUBLIC void SGA_DisableIRQSrc(IN t_sga_int_to_core core, IN t_sga_irq_src irq_src)
 +{
@@ -211984,9 +213195,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.c ../new/linux-2.6.2
 +        }
 +    }
 +}
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h
---- linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h    2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h
 @@ -0,0 +1,99 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -212003,7 +213213,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h ../new/linux-2.6.2
 + * You should have received a copy of the GNU Lesser General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
-+ * Description        : Public Header file of Smart Graphics Accelerator  
++ * Description        : Public Header file of Smart Graphics Accelerator
 + *                            module containing interrupts APIs
 + *****************************************************************************/
 +
@@ -212056,9 +213266,9 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h ../new/linux-2.6.2
 +#define    SGA_IRQ_SRC_INT_21              0x8000000
 +#define    SGA_IRQ_SRC_INT_22              0x10000000
 +#define    SGA_IRQ_SRC_INT_23              0x20000000
-+#define    SGA_IRQ_SRC_INT_24              0x40000000    
++#define    SGA_IRQ_SRC_INT_24              0x40000000
 +#define    SGA_IRQ_SRC_INT_25              0x80000000
-+#define    SGA_IRQ_SRC_ALL                 0xFFFFFFFF    
++#define    SGA_IRQ_SRC_ALL                 0xFFFFFFFF
 +
 +
 +typedef enum
@@ -212087,9 +213297,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irq.h ../new/linux-2.6.2
 +#endif  /* __cplusplus              */
 +
 +#endif        /* _SGA_IRQ_H_               */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h
---- linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h
 @@ -0,0 +1,239 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -212106,7 +213315,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 + * You should have received a copy of the GNU Lesser General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
-+ * Description        : Private Header file of SGA Controller module 
++ * Description        : Private Header file of SGA Controller module
 + *
 + *****************************************************************************/
 +
@@ -212137,8 +213346,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +
 +#define SGA_WRITE_FIELD(reg_name,mask,shift,value) \
 +                  (reg_name = ((reg_name & ~mask) | (value << shift)))
-+                  
-+                  
++
++
 +#define SGA_READ_FIELD(reg_name,mask,shift)    ((reg_name & mask) >> shift )
 +
 +
@@ -212146,7 +213355,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +/*-----------------------------------------------------------------------------
 +      SGA Registers Description
 +-----------------------------------------------------------------------------*/
-+typedef volatile struct  
++typedef volatile struct
 +{
 +    t_uint32  sga_instr;    /* Manual instruction input register   0x0  */
 +    t_uint32  sga_gcr;      /* Global configuration register       0x04 */
@@ -212177,11 +213386,11 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +    t_uint32  sga_periphid0; /* Pheripheral Identification 0       0x7E0 */
 +    t_uint32  sga_periphid1; /* Pheripheral Identification 1       0x7E4 */
 +    t_uint32  sga_periphid2; /* Pheripheral Identification 2       0x7E8 */
-+    t_uint32  sga_periphid3; /* Pheripheral Identification 3       0x7EC */        
++    t_uint32  sga_periphid3; /* Pheripheral Identification 3       0x7EC */
 +    t_uint32  sga_pcellid0;  /* Pcell identification 0             0x7F0 */
 +    t_uint32  sga_pcellid1;  /* Pcell identification 1             0x7F4 */
 +    t_uint32  sga_pcellid2;  /* Pcell identification 2             0x7F8 */
-+    t_uint32  sga_pcellid3;  /* Pcell identification 3             0x7Fc */    
++    t_uint32  sga_pcellid3;  /* Pcell identification 3             0x7Fc */
 +}t_sga_registers;
 +
 +
@@ -212189,12 +213398,12 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +      SGA Global Configuration register fields description
 +-----------------------------------------------------------------------------*/
 +   /*Shift values for Golbal configuration register */
-+#define  SGA_GCR_INTCMOD_SHIFT      0  /*Interrupt clear mode select bit */   
++#define  SGA_GCR_INTCMOD_SHIFT      0  /*Interrupt clear mode select bit */
 +#define  SGA_GCR_FCLKGEN_SHIFT      1  /*FCLK clock gating enable bit    */
 +#define  SGA_GCR_HCLKGEN_SHIFT      2  /*Hclk Clock gating enable bit    */
 +#define  SGA_GCR_INTCMOD1_SHIFT     3  /*Interrupt clear mode select     */
 +   /*Mask values for Golbal configuration register */
-+#define  SGA_GCR_INTCMOD_MASK       MASK_BIT0  /*Interrupt clear mode select bit */   
++#define  SGA_GCR_INTCMOD_MASK       MASK_BIT0  /*Interrupt clear mode select bit */
 +#define  SGA_GCR_FCLKGEN_MASK       MASK_BIT1  /*FCLK clock gating enable bit    */
 +#define  SGA_GCR_HCLKGEN_MASK       MASK_BIT2  /*Hclk Clock gating enable bit    */
 +#define  SGA_GCR_INTCMOD1_MASK      MASK_BIT3  /*Interrupt clear mode select     */
@@ -212253,14 +213462,14 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +   /*Shift values for Controller status register */
 +
 +
-+ 
++
 +/*-----------------------------------------------------------------------------
 +      SGA Controller Debug  register fields description
 +-----------------------------------------------------------------------------*/
 +   /*Shift values for Controller Debug register */
-+#define SGA_DEBUG_TPIPE_SHIFT       0          /*Total Pipe Empty bit  */    
++#define SGA_DEBUG_TPIPE_SHIFT       0          /*Total Pipe Empty bit  */
 +#define SGA_DEBUG_SPIPE_SHIFT       1          /*Source Pipe Empty bit */
-+#define SGA_DEBUG_AHBME_SHIFT       2          /*AHB Master empty bit  */   
++#define SGA_DEBUG_AHBME_SHIFT       2          /*AHB Master empty bit  */
 +#define SGA_DEBUG_DDMAFSME_SHIFT    3          /*Destination DMAFSM flows empty bit*/
 +#define SGA_DEBUG_SDMAFSME_SHIFT    4          /*Source DMAFSM flows empty  bit */
 +#define SGA_DEBUG_CACBNK2_SHIFT     5          /*Cache Bank 0 empty bit */
@@ -212272,8 +213481,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +#define SGA_DEBUG_PIXOP_SHIFT       11         /*Pixel Operator empty bit */
 +#define SGA_DEBUG_SFIFOWRE_SHIFT    12         /*Source FIFO write empty bit*/
 +#define SGA_DEBUG_COLCONV_SHIFT     13         /*Colour conversion empty bit*/
-+#define SGA_DEBUG_PIXBIL_SHIFT      14         /*Pixel Bilinear Operator Empty bit  */       
-+#define SGA_DEBUG_TRSOP_SHIFT       15         /*Transparency operator empty bit*/ 
++#define SGA_DEBUG_PIXBIL_SHIFT      14         /*Pixel Bilinear Operator Empty bit  */
++#define SGA_DEBUG_TRSOP_SHIFT       15         /*Transparency operator empty bit*/
 +#define SGA_DEBUG_PIXSER_SHIFT      16         /*Pixel Serialiser Operator Empty bit */
 +#define SGA_DEBUG_DEPATEX_SHIFT     17         /*Depacker Texture Empty bit */
 +#define SGA_DEBUG_CACHEPE_SHIFT     18         /*Cache Texture empty flow bit */
@@ -212292,9 +213501,9 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +#define SGA_DEBUG_TRIOPE_SHIFT      31         /*Traingle Operator empty bit */
 +
 +   /*Mask values for Controller Debug register */
-+#define SGA_DEBUG_TPIPE_MASK       MASK_BIT0          /*Total Pipe Empty bit  */    
++#define SGA_DEBUG_TPIPE_MASK       MASK_BIT0          /*Total Pipe Empty bit  */
 +#define SGA_DEBUG_SPIPE_MASK       MASK_BIT1          /*Source Pipe Empty bit */
-+#define SGA_DEBUG_AHBME_MASK       MASK_BIT2          /*AHB Master empty bit  */   
++#define SGA_DEBUG_AHBME_MASK       MASK_BIT2          /*AHB Master empty bit  */
 +#define SGA_DEBUG_DDMAFSME_MASK    MASK_BIT3          /*Destination DMAFSM flows empty bit*/
 +#define SGA_DEBUG_SDMAFSME_MASK    MASK_BIT4          /*Source DMAFSM flows empty  bit */
 +#define SGA_DEBUG_CACBNK2_MASK     MASK_BIT5          /*Cache Bank 0 empty bit */
@@ -212306,8 +213515,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +#define SGA_DEBUG_PIXOP_MASK       MASK_BIT11         /*Pixel Operator empty bit */
 +#define SGA_DEBUG_SFIFOWRE_MASK    MASK_BIT12         /*Source FIFO write empty bit*/
 +#define SGA_DEBUG_COLCONV_MASK     MASK_BIT13         /*Colour conversion empty bit*/
-+#define SGA_DEBUG_PIXBIL_MASK      MASK_BIT14         /*Pixel Bilinear Operator Empty bit  */       
-+#define SGA_DEBUG_TRSOP_MASK       MASK_BIT15         /*Transparency operator empty bit*/ 
++#define SGA_DEBUG_PIXBIL_MASK      MASK_BIT14         /*Pixel Bilinear Operator Empty bit  */
++#define SGA_DEBUG_TRSOP_MASK       MASK_BIT15         /*Transparency operator empty bit*/
 +#define SGA_DEBUG_PIXSER_MASK      MASK_BIT16         /*Pixel Serialiser Operator Empty bit */
 +#define SGA_DEBUG_DEPATEX_MASK     MASK_BIT17         /*Depacker Texture Empty bit */
 +#define SGA_DEBUG_CACHEPE_MASK     MASK_BIT18         /*Cache Texture empty flow bit */
@@ -212330,9 +213539,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_irqp.h ../new/linux-2.6.
 +
 +/* End of file sga_irqp.h */
 +
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h
---- linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h      2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h
 @@ -0,0 +1,175 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -212349,7 +213557,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h ../new/linux-2.6.20/
 + * You should have received a copy of the GNU Lesser General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
-+ * Description        : Private Header file of Smart Graphics Accelerator  
++ * Description        : Private Header file of Smart Graphics Accelerator
 + *                            module containing interrupts APIs
 + *****************************************************************************/
 +#ifndef _SGA_P_H_
@@ -212388,7 +213596,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h ../new/linux-2.6.20/
 +#define   SET_INSTR_TEST_REG   0x88000000
 +#define   CLR_INSTR_TEST_REG   0x89000000
 +#define   TST_INSTR_TEST_REG   0x8A000000
-+#define   WAIT_INSTR_TEST_REG  0x8B000000     
++#define   WAIT_INSTR_TEST_REG  0x8B000000
 +
 +#define  IN0_BASE_ADD_MSB      0xA0000000
 +#define  IN0_BASE_ADD          0xA1000000
@@ -212509,28 +213717,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/hcl/sga_p.h ../new/linux-2.6.20/
 +#endif /* __cplusplus */
 +#endif /* _SGA_H_ */
 +
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/Makefile ../new/linux-2.6.20/drivers/video/nomadik/Makefile
---- linux-2.6.20/drivers/video/nomadik/Makefile        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/Makefile 2007-11-21 11:51:42.000000000 +0530
-@@ -0,0 +1,15 @@
-+#
-+# Makefile for the Nomadik framebuffer driver
-+#
-+ifdef CONFIG_FB_NOMADIK_ACCLN
-+CFLAGS += -D__STN_8815 -D__RELEASE
-+
-+obj-$(CONFIG_FB_NOMADIK_ACCLN)    += nomadikfb.o
-+#obj-m    += nomadikfb.ko
-+
-+endif
-+
-+nomadikfb-y                       := sga_main.o sga_ioctlfns.o hcl/sga.o hcl/sga_irq.o
-+                                  
-+
-+nomadikfb-objs                    := $(nomadikfb-y)
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_defs.h ../new/linux-2.6.20/drivers/video/nomadik/sga_defs.h
---- linux-2.6.20/drivers/video/nomadik/sga_defs.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_defs.h       2008-10-06 12:06:23.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_defs.h
 @@ -0,0 +1,87 @@
 +/*******************************************************************************
 +** Copyright 2007, STMicroelectronics
@@ -212567,13 +213755,13 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_defs.h ../new/linux-2.6.20/d
 +#define SGA_DRV_VERSION "rel_1_5"
 +
 +//-----------------------------------------------------------------------------
-+// Set the BLOCKING_TASKRUN_IOCTL define below if the ioctl should sleep until 
++// Set the BLOCKING_TASKRUN_IOCTL define below if the ioctl should sleep until
 +// the task is complete. If the start batch ioctl should return even if
 +// the task is not completed, then BLOCKING_TASKRUN_IOCTL should be undefined.
 +#define BLOCKING_TASKRUN_IOCTL
 +
 +//-----------------------------------------------------------------------------
-+// Set the ENABLE_SGA_INTERRUPTS define below if SGA interrupts are to be 
++// Set the ENABLE_SGA_INTERRUPTS define below if SGA interrupts are to be
 +// enabled in the driver. If only status of raw interrupts is to be checked
 +// from the library (user level polling), this should remain undefined.
 +//#define ENABLE_SGA_INTERRUPTS
@@ -212619,9 +213807,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_defs.h ../new/linux-2.6.20/d
 +/******************************************************************************/
 +
 +#endif /* _SGA_DEFS_H */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_err.h ../new/linux-2.6.20/drivers/video/nomadik/sga_err.h
---- linux-2.6.20/drivers/video/nomadik/sga_err.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_err.h        2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_err.h
 @@ -0,0 +1,45 @@
 +/*******************************************************************************
 +** Copyright 2007, STMicroelectronics
@@ -212668,9 +213855,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_err.h ../new/linux-2.6.20/dr
 +}t_sgadrv_err;
 +
 +#endif /* _SGA_ERR_H */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_interface.h ../new/linux-2.6.20/drivers/video/nomadik/sga_interface.h
---- linux-2.6.20/drivers/video/nomadik/sga_interface.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_interface.h  2008-10-06 12:06:23.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_interface.h
 @@ -0,0 +1,119 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -212791,9 +213977,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_interface.h ../new/linux-2.6
 +
 +#endif        // __SGA_IOCTL_HEADER_SGA__
 +
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c
---- linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c   2008-11-24 14:06:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c
 @@ -0,0 +1,473 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -213268,9 +214453,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.c ../new/linux-2.6.
 +}
 +
 +// end of sga_ioctlfns.c
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h
---- linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h
 @@ -0,0 +1,50 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -213292,7 +214476,7 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h ../new/linux-2.6.
 + * File                       : sga_ioctlfns.h
 + * Description        : This file contains the ioctl function declarations that are
 + *                            used by the applications. The definition of all the functions
-+ *                            is present in sga_ioctlfns.c. It also contains the internal 
++ *                            is present in sga_ioctlfns.c. It also contains the internal
 + *                            data structures to the driver.
 + * Author             : Anand Bodas
 + * Dept.              : ST/HPC
@@ -213322,9 +214506,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_ioctlfns.h ../new/linux-2.6.
 +
 +#endif
 +
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_main.c ../new/linux-2.6.20/drivers/video/nomadik/sga_main.c
---- linux-2.6.20/drivers/video/nomadik/sga_main.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_main.c       2008-11-24 14:06:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_main.c
 @@ -0,0 +1,651 @@
 +/******************************************************************************
 + * Copyright 2007, STMicroelectronics
@@ -213977,9 +215160,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_main.c ../new/linux-2.6.20/d
 +module_init(SGA_init_module);
 +module_exit(SGA_cleanup_module);
 +
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_main.h ../new/linux-2.6.20/drivers/video/nomadik/sga_main.h
---- linux-2.6.20/drivers/video/nomadik/sga_main.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_main.h       2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_main.h
 @@ -0,0 +1,123 @@
 +/*******************************************************************************
 +** Copyright 2007, STMicroelectronics
@@ -214104,9 +215286,8 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_main.h ../new/linux-2.6.20/d
 +
 +
 +#endif /* _SGA_API_H */
-diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_typs.h ../new/linux-2.6.20/drivers/video/nomadik/sga_typs.h
---- linux-2.6.20/drivers/video/nomadik/sga_typs.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/drivers/video/nomadik/sga_typs.h       2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/drivers/video/nomadik/sga_typs.h
 @@ -0,0 +1,37 @@
 +/*******************************************************************************
 +** Copyright 2007, STMicroelectronics
@@ -214145,10 +215326,11 @@ diff -Nauprw linux-2.6.20/drivers/video/nomadik/sga_typs.h ../new/linux-2.6.20/d
 +typedef long           INT4;
 +
 +#endif /* _SGA_TYPS_H */
-diff -Nauprw linux-2.6.20/fs/Kconfig ../new/linux-2.6.20/fs/Kconfig
---- linux-2.6.20/fs/Kconfig    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/fs/Kconfig     2008-09-17 13:23:34.000000000 +0530
-@@ -1196,6 +1196,10 @@ config EFS_FS
+--- linux-2.6.20.orig/fs/Kconfig
++++ linux-2.6.20/fs/Kconfig
+@@ -1194,10 +1194,14 @@ config EFS_FS
+         about EFS see its home page at <http://aeschi.ch.eu.org/efs/>.
          To compile the EFS file system support as a module, choose M here: the
          module will be called efs.
  
@@ -214159,20 +215341,24 @@ diff -Nauprw linux-2.6.20/fs/Kconfig ../new/linux-2.6.20/fs/Kconfig
  config JFFS_FS
        tristate "Journalling Flash File System (JFFS) support"
        depends on MTD && BLOCK && BROKEN
-diff -Nauprw linux-2.6.20/fs/Makefile ../new/linux-2.6.20/fs/Makefile
---- linux-2.6.20/fs/Makefile   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/fs/Makefile    2008-09-17 13:23:34.000000000 +0530
-@@ -115,3 +115,6 @@ obj-$(CONFIG_HPPFS)                += hppfs/
+       help
+         JFFS is the Journalling Flash File System developed by Axis
+--- linux-2.6.20.orig/fs/Makefile
++++ linux-2.6.20/fs/Makefile
+@@ -113,5 +113,8 @@ obj-$(CONFIG_BEFS_FS)              += befs/
+ obj-$(CONFIG_HOSTFS)          += hostfs/
+ obj-$(CONFIG_HPPFS)           += hppfs/
  obj-$(CONFIG_DEBUG_FS)                += debugfs/
  obj-$(CONFIG_OCFS2_FS)                += ocfs2/
  obj-$(CONFIG_GFS2_FS)           += gfs2/
 +
 +# Patched by YAFFS
 +obj-$(CONFIG_YAFFS_FS)                += yaffs2/
-diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_misc.c
---- linux-2.6.20/fs/proc/proc_misc.c   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/fs/proc/proc_misc.c    2008-07-04 23:45:24.000000000 +0530
-@@ -65,6 +65,7 @@
+--- linux-2.6.20.orig/fs/proc/proc_misc.c
++++ linux-2.6.20/fs/proc/proc_misc.c
+@@ -63,10 +63,11 @@
+  * wrappers, but this needs further analysis wrt potential overflows.
+  */
  extern int get_hardware_list(char *);
  extern int get_stram_list(char *);
  extern int get_filesystem_list(char *);
@@ -214180,7 +215366,11 @@ diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_m
  extern int get_exec_domain_list(char *);
  extern int get_dma_list(char *);
  extern int get_locks_status (char *, char **, off_t, int);
-@@ -612,6 +613,29 @@ static int filesystems_read_proc(char *p
+ static int proc_calc_metrics(char *page, char **start, off_t off,
+@@ -610,10 +611,33 @@ static int filesystems_read_proc(char *p
+ {
+       int len = get_filesystem_list(page);
        return proc_calc_metrics(page, start, off, count, eof, len);
  }
  
@@ -214196,7 +215386,7 @@ diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_m
 +static int busfreq_read_proc(char *page, char **start, off_t off,
 +                          int count, int *eof, void *data)
 +{
-+      int len = nomadik_busfreq_get(page); 
++      int len = nomadik_busfreq_get(page);
 +      return proc_calc_metrics(page, start, off, count, eof, len);
 +}
 +
@@ -214210,7 +215400,11 @@ diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_m
  static int cmdline_read_proc(char *page, char **start, off_t off,
                                 int count, int *eof, void *data)
  {
-@@ -687,11 +711,19 @@ void __init proc_misc_init(void)
+       int len;
+@@ -685,15 +709,23 @@ void __init proc_misc_init(void)
+               {"hardware",    hardware_read_proc},
+ #endif
  #ifdef CONFIG_STRAM_PROC
                {"stram",       stram_read_proc},
  #endif
@@ -214221,11 +215415,11 @@ diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_m
 -              {NULL,}
 +                {
 +                "filesystems", filesystems_read_proc},
-+#ifdef CONFIG_GPIO_PROC   
++#ifdef CONFIG_GPIO_PROC
 +                {
 +                "gpio", gpio_read_proc},
-+#endif 
-+              {"busfreq" , busfreq_read_proc}, 
++#endif
++              {"busfreq" , busfreq_read_proc},
 +                {
 +              "dma", dma_read_proc}, {
 +                "cmdline", cmdline_read_proc}, {
@@ -214235,9 +215429,182 @@ diff -Nauprw linux-2.6.20/fs/proc/proc_misc.c ../new/linux-2.6.20/fs/proc/proc_m
        };
        for (p = simple_ones; p->name; p++)
                create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
-diff -Nauprw linux-2.6.20/fs/yaffs2/devextras.h ../new/linux-2.6.20/fs/yaffs2/devextras.h
---- linux-2.6.20/fs/yaffs2/devextras.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/devextras.h  2008-09-12 12:54:02.000000000 +0530
+       proc_symlink("mounts", NULL, "self/mounts");
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/Kconfig
+@@ -0,0 +1,156 @@
++#
++# YAFFS file system configurations
++#
++
++config YAFFS_FS
++      tristate "YAFFS2 file system support"
++      default n
++      depends on MTD
++      select YAFFS_YAFFS1
++      select YAFFS_YAFFS2
++      help
++        YAFFS2, or Yet Another Flash Filing System, is a filing system
++        optimised for NAND Flash chips.
++
++        To compile the YAFFS2 file system support as a module, choose M
++        here: the module will be called yaffs2.
++
++        If unsure, say N.
++
++        Further information on YAFFS2 is available at
++        <http://www.aleph1.co.uk/yaffs/>.
++
++config YAFFS_YAFFS1
++      bool "512 byte / page devices"
++      depends on YAFFS_FS
++      default y
++      help
++        Enable YAFFS1 support -- yaffs for 512 byte / page devices
++
++        Not needed for 2K-page devices.
++
++        If unsure, say Y.
++
++config YAFFS_9BYTE_TAGS
++      bool "Use older-style on-NAND data format with pageStatus byte"
++      depends on YAFFS_YAFFS1
++      default n
++      help
++
++        Older-style on-NAND data format has a "pageStatus" byte to record
++        chunk/page state.  This byte is zero when the page is discarded.
++        Choose this option if you have existing on-NAND data using this
++        format that you need to continue to support.  New data written
++        also uses the older-style format.  Note: Use of this option
++        generally requires that MTD's oob layout be adjusted to use the
++        older-style format.  See notes on tags formats and MTD versions
++        in yaffs_mtdif1.c.
++
++        If unsure, say N.
++
++config YAFFS_DOES_ECC
++      bool "Lets Yaffs do its own ECC"
++      depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
++      default n
++      help
++        This enables Yaffs to use its own ECC functions instead of using
++        the ones from the generic MTD-NAND driver.
++
++        If unsure, say N.
++
++config YAFFS_ECC_WRONG_ORDER
++      bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
++      depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
++      default n
++      help
++        This makes yaffs_ecc.c use the same ecc byte order as Steven
++        Hill's nand_ecc.c. If not set, then you get the same ecc byte
++        order as SmartMedia.
++
++        If unsure, say N.
++
++config YAFFS_YAFFS2
++      bool "2048 byte (or larger) / page devices"
++      depends on YAFFS_FS
++      default y
++      help
++        Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
++
++        If unsure, say Y.
++
++config YAFFS_AUTO_YAFFS2
++      bool "Autoselect yaffs2 format"
++      depends on YAFFS_YAFFS2
++      default y
++      help
++        Without this, you need to explicitely use yaffs2 as the file
++        system type. With this, you can say "yaffs" and yaffs or yaffs2
++        will be used depending on the device page size (yaffs on
++        512-byte page devices, yaffs2 on 2K page devices).
++
++        If unsure, say Y.
++
++config YAFFS_DISABLE_LAZY_LOAD
++      bool "Disable lazy loading"
++      depends on YAFFS_YAFFS2
++      default n
++      help
++        "Lazy loading" defers loading file details until they are
++        required. This saves mount time, but makes the first look-up
++        a bit longer.
++
++        Lazy loading will only happen if enabled by this option being 'n'
++        and if the appropriate tags are available, else yaffs2 will
++        automatically fall back to immediate loading and do the right
++        thing.
++
++        Lazy laoding will be required by checkpointing.
++
++        Setting this to 'y' will disable lazy loading.
++
++        If unsure, say N.
++
++
++config YAFFS_DISABLE_WIDE_TNODES
++      bool "Turn off wide tnodes"
++      depends on YAFFS_FS
++      default n
++      help
++        Wide tnodes are only used for NAND arrays >=32MB for 512-byte
++        page devices and >=128MB for 2k page devices. They use slightly
++        more RAM but are faster since they eliminate chunk group
++        searching.
++
++        Setting this to 'y' will force tnode width to 16 bits and save
++        memory but make large arrays slower.
++
++        If unsure, say N.
++
++config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
++      bool "Force chunk erase check"
++      depends on YAFFS_FS
++      default n
++      help
++          Normally YAFFS only checks chunks before writing until an erased
++        chunk is found. This helps to detect any partially written
++        chunks that might have happened due to power loss.
++
++        Enabling this forces on the test that chunks are erased in flash
++        before writing to them. This takes more time but is potentially
++        a bit more secure.
++
++        Suggest setting Y during development and ironing out driver
++        issues etc. Suggest setting to N if you want faster writing.
++
++        If unsure, say Y.
++
++config YAFFS_SHORT_NAMES_IN_RAM
++      bool "Cache short names in RAM"
++      depends on YAFFS_FS
++      default y
++      help
++        If this config is set, then short names are stored with the
++        yaffs_Object.  This costs an extra 16 bytes of RAM per object,
++        but makes look-ups faster.
++
++        If unsure, say Y.
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for the linux YAFFS filesystem routines.
++#
++
++obj-$(CONFIG_YAFFS_FS) += yaffs.o
++
++yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
++yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
++yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
++yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/devextras.h
 @@ -0,0 +1,264 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -214503,183 +215870,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/devextras.h ../new/linux-2.6.20/fs/yaffs2/de
 +#endif
 +
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/Kconfig ../new/linux-2.6.20/fs/yaffs2/Kconfig
---- linux-2.6.20/fs/yaffs2/Kconfig     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/Kconfig      2008-09-12 12:54:02.000000000 +0530
-@@ -0,0 +1,156 @@
-+#
-+# YAFFS file system configurations
-+#
-+
-+config YAFFS_FS
-+      tristate "YAFFS2 file system support"
-+      default n
-+      depends on MTD
-+      select YAFFS_YAFFS1
-+      select YAFFS_YAFFS2
-+      help
-+        YAFFS2, or Yet Another Flash Filing System, is a filing system
-+        optimised for NAND Flash chips.
-+
-+        To compile the YAFFS2 file system support as a module, choose M
-+        here: the module will be called yaffs2.
-+
-+        If unsure, say N.
-+
-+        Further information on YAFFS2 is available at
-+        <http://www.aleph1.co.uk/yaffs/>.
-+
-+config YAFFS_YAFFS1
-+      bool "512 byte / page devices"
-+      depends on YAFFS_FS
-+      default y
-+      help
-+        Enable YAFFS1 support -- yaffs for 512 byte / page devices
-+
-+        Not needed for 2K-page devices.
-+
-+        If unsure, say Y.
-+
-+config YAFFS_9BYTE_TAGS
-+      bool "Use older-style on-NAND data format with pageStatus byte"
-+      depends on YAFFS_YAFFS1
-+      default n
-+      help
-+
-+        Older-style on-NAND data format has a "pageStatus" byte to record
-+        chunk/page state.  This byte is zero when the page is discarded.
-+        Choose this option if you have existing on-NAND data using this
-+        format that you need to continue to support.  New data written
-+        also uses the older-style format.  Note: Use of this option
-+        generally requires that MTD's oob layout be adjusted to use the
-+        older-style format.  See notes on tags formats and MTD versions
-+        in yaffs_mtdif1.c.
-+
-+        If unsure, say N.
-+
-+config YAFFS_DOES_ECC
-+      bool "Lets Yaffs do its own ECC"
-+      depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
-+      default n
-+      help
-+        This enables Yaffs to use its own ECC functions instead of using
-+        the ones from the generic MTD-NAND driver.
-+
-+        If unsure, say N.
-+
-+config YAFFS_ECC_WRONG_ORDER
-+      bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
-+      depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
-+      default n
-+      help
-+        This makes yaffs_ecc.c use the same ecc byte order as Steven
-+        Hill's nand_ecc.c. If not set, then you get the same ecc byte
-+        order as SmartMedia.
-+
-+        If unsure, say N.
-+
-+config YAFFS_YAFFS2
-+      bool "2048 byte (or larger) / page devices"
-+      depends on YAFFS_FS
-+      default y
-+      help
-+        Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
-+
-+        If unsure, say Y.
-+
-+config YAFFS_AUTO_YAFFS2
-+      bool "Autoselect yaffs2 format"
-+      depends on YAFFS_YAFFS2
-+      default y
-+      help
-+        Without this, you need to explicitely use yaffs2 as the file
-+        system type. With this, you can say "yaffs" and yaffs or yaffs2
-+        will be used depending on the device page size (yaffs on
-+        512-byte page devices, yaffs2 on 2K page devices).
-+
-+        If unsure, say Y.
-+
-+config YAFFS_DISABLE_LAZY_LOAD
-+      bool "Disable lazy loading"
-+      depends on YAFFS_YAFFS2
-+      default n
-+      help
-+        "Lazy loading" defers loading file details until they are
-+        required. This saves mount time, but makes the first look-up
-+        a bit longer.
-+
-+        Lazy loading will only happen if enabled by this option being 'n'
-+        and if the appropriate tags are available, else yaffs2 will
-+        automatically fall back to immediate loading and do the right
-+        thing.
-+
-+        Lazy laoding will be required by checkpointing.
-+
-+        Setting this to 'y' will disable lazy loading.
-+
-+        If unsure, say N.
-+
-+
-+config YAFFS_DISABLE_WIDE_TNODES
-+      bool "Turn off wide tnodes"
-+      depends on YAFFS_FS
-+      default n
-+      help
-+        Wide tnodes are only used for NAND arrays >=32MB for 512-byte
-+        page devices and >=128MB for 2k page devices. They use slightly
-+        more RAM but are faster since they eliminate chunk group
-+        searching.
-+
-+        Setting this to 'y' will force tnode width to 16 bits and save
-+        memory but make large arrays slower.
-+
-+        If unsure, say N.
-+
-+config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
-+      bool "Force chunk erase check"
-+      depends on YAFFS_FS
-+      default n
-+      help
-+          Normally YAFFS only checks chunks before writing until an erased
-+        chunk is found. This helps to detect any partially written
-+        chunks that might have happened due to power loss.
-+
-+        Enabling this forces on the test that chunks are erased in flash
-+        before writing to them. This takes more time but is potentially
-+        a bit more secure.
-+
-+        Suggest setting Y during development and ironing out driver
-+        issues etc. Suggest setting to N if you want faster writing.
-+
-+        If unsure, say Y.
-+
-+config YAFFS_SHORT_NAMES_IN_RAM
-+      bool "Cache short names in RAM"
-+      depends on YAFFS_FS
-+      default y
-+      help
-+        If this config is set, then short names are stored with the
-+        yaffs_Object.  This costs an extra 16 bytes of RAM per object,
-+        but makes look-ups faster.
-+
-+        If unsure, say Y.
-diff -Nauprw linux-2.6.20/fs/yaffs2/Makefile ../new/linux-2.6.20/fs/yaffs2/Makefile
---- linux-2.6.20/fs/yaffs2/Makefile    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/Makefile     2008-09-12 12:54:02.000000000 +0530
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the linux YAFFS filesystem routines.
-+#
-+
-+obj-$(CONFIG_YAFFS_FS) += yaffs.o
-+
-+yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
-+yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
-+yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
-+yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
-diff -Nauprw linux-2.6.20/fs/yaffs2/moduleconfig.h ../new/linux-2.6.20/fs/yaffs2/moduleconfig.h
---- linux-2.6.20/fs/yaffs2/moduleconfig.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/moduleconfig.h       2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/moduleconfig.h
 @@ -0,0 +1,65 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -214746,9 +215938,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/moduleconfig.h ../new/linux-2.6.20/fs/yaffs2
 +#endif /* YAFFS_OUT_OF_TREE */
 +
 +#endif /* __YAFFS_CONFIG_H__ */
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c
---- linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c    2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c
 @@ -0,0 +1,404 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -215154,9 +216345,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_checkptrw.c ../new/linux-2.6.20/fs/yaf
 +
 +
 +
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h
---- linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h    2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h
 @@ -0,0 +1,35 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -215193,9 +216383,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_checkptrw.h ../new/linux-2.6.20/fs/yaf
 +
 +#endif
 +
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_ecc.c ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.c
---- linux-2.6.20/fs/yaffs2/yaffs_ecc.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.c  2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_ecc.c
 @@ -0,0 +1,331 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -215528,9 +216717,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_ecc.c ../new/linux-2.6.20/fs/yaffs2/ya
 +
 +}
 +
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_ecc.h ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.h
---- linux-2.6.20/fs/yaffs2/yaffs_ecc.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_ecc.h  2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_ecc.h
 @@ -0,0 +1,44 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -215576,9 +216764,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_ecc.h ../new/linux-2.6.20/fs/yaffs2/ya
 +                        yaffs_ECCOther * read_ecc,
 +                        const yaffs_ECCOther * test_ecc);
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_fs.c ../new/linux-2.6.20/fs/yaffs2/yaffs_fs.c
---- linux-2.6.20/fs/yaffs2/yaffs_fs.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_fs.c   2008-09-12 12:54:02.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_fs.c
 @@ -0,0 +1,2297 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -217877,9 +219064,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_fs.c ../new/linux-2.6.20/fs/yaffs2/yaf
 +MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
 +MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006");
 +MODULE_LICENSE("GPL");
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_guts.c ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.c
---- linux-2.6.20/fs/yaffs2/yaffs_guts.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.c 2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_guts.c
 @@ -0,0 +1,7532 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -225413,9 +226599,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_guts.c ../new/linux-2.6.20/fs/yaffs2/y
 +
 +          return YAFFS_OK;
 +}
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_guts.h ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.h
---- linux-2.6.20/fs/yaffs2/yaffs_guts.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_guts.h 2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_guts.h
 @@ -0,0 +1,904 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -226321,10 +227506,253 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_guts.h ../new/linux-2.6.20/fs/yaffs2/y
 +void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
 +
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffsinterface.h ../new/linux-2.6.20/fs/yaffs2/yaffsinterface.h
---- linux-2.6.20/fs/yaffs2/yaffsinterface.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffsinterface.h     2008-09-12 12:54:05.000000000 +0530
-@@ -0,0 +1,21 @@
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif.c
+@@ -0,0 +1,241 @@
++/*
++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
++ *
++ * Copyright (C) 2002-2007 Aleph One Ltd.
++ *   for Toby Churchill Ltd and Brightstar Engineering
++ *
++ * Created by Charles Manning <charles@aleph1.co.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++const char *yaffs_mtdif_c_version =
++    "$Id: yaffs_mtdif.c,v 1.21 2007/12/13 15:35:18 wookey Exp $";
++
++#include "yportenv.h"
++
++
++#include "yaffs_mtdif.h"
++
++#include "linux/mtd/mtd.h"
++#include "linux/types.h"
++#include "linux/time.h"
++#include "linux/mtd/nand.h"
++
++#if (MTD_VERSION_CODE < MTD_VERSION(2,6,18))
++static struct nand_oobinfo yaffs_oobinfo = {
++      .useecc = 1,
++      .eccbytes = 6,
++      .eccpos = {8, 9, 10, 13, 14, 15}
++};
++
++static struct nand_oobinfo yaffs_noeccinfo = {
++      .useecc = 0,
++};
++#endif
++
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
++{
++      oob[0] = spare->tagByte0;
++      oob[1] = spare->tagByte1;
++      oob[2] = spare->tagByte2;
++      oob[3] = spare->tagByte3;
++      oob[4] = spare->tagByte4;
++      oob[5] = spare->tagByte5 & 0x3f;
++      oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
++      oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
++      oob[6] = spare->tagByte6;
++      oob[7] = spare->tagByte7;
++}
++
++static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
++{
++      struct yaffs_NANDSpare *nspare = (struct yaffs_NANDSpare *)spare;
++      spare->tagByte0 = oob[0];
++      spare->tagByte1 = oob[1];
++      spare->tagByte2 = oob[2];
++      spare->tagByte3 = oob[3];
++      spare->tagByte4 = oob[4];
++      spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
++      spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y';
++      spare->pageStatus = oob[5] & 0x40 ? 0xff : 0;
++      spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
++      spare->tagByte6 = oob[6];
++      spare->tagByte7 = oob[7];
++      spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;
++
++      nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
++}
++#endif
++
++int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
++                           const __u8 * data, const yaffs_Spare * spare)
++{
++      struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++      struct mtd_oob_ops ops;
++#endif
++      size_t dummy;
++      int retval = 0;
++
++      loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++      __u8 spareAsBytes[8]; /* OOB */
++
++      if (data && !spare)
++              retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
++                              &dummy, data);
++      else if (spare) {
++              if (dev->useNANDECC) {
++                      translate_spare2oob(spare, spareAsBytes);
++                      ops.mode = MTD_OOB_AUTO;
++                      ops.ooblen = 8; /* temp hack */
++              } else {
++                      ops.mode = MTD_OOB_RAW;
++                      ops.ooblen = YAFFS_BYTES_PER_SPARE;
++              }
++              ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
++              ops.datbuf = (u8 *)data;
++              ops.ooboffs = 0;
++              ops.oobbuf = spareAsBytes;
++              retval = mtd->write_oob(mtd, addr, &ops);
++      }
++#else
++      __u8 *spareAsBytes = (__u8 *) spare;
++
++      if (data && spare) {
++              if (dev->useNANDECC)
++                      retval =
++                          mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
++                                         &dummy, data, spareAsBytes,
++                                         &yaffs_oobinfo);
++              else
++                      retval =
++                          mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
++                                         &dummy, data, spareAsBytes,
++                                         &yaffs_noeccinfo);
++      } else {
++              if (data)
++                      retval =
++                          mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
++                                     data);
++              if (spare)
++                      retval =
++                          mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
++                                         &dummy, spareAsBytes);
++      }
++#endif
++
++      if (retval == 0)
++              return YAFFS_OK;
++      else
++              return YAFFS_FAIL;
++}
++
++int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
++                            yaffs_Spare * spare)
++{
++      struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++      struct mtd_oob_ops ops;
++#endif
++      size_t dummy;
++      int retval = 0;
++
++      loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
++#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
++      __u8 spareAsBytes[8]; /* OOB */
++
++      if (data && !spare)
++              retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
++                              &dummy, data);
++      else if (spare) {
++              if (dev->useNANDECC) {
++                      ops.mode = MTD_OOB_AUTO;
++                      ops.ooblen = 8; /* temp hack */
++              } else {
++                      ops.mode = MTD_OOB_RAW;
++                      ops.ooblen = YAFFS_BYTES_PER_SPARE;
++              }
++              ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
++              ops.datbuf = data;
++              ops.ooboffs = 0;
++              ops.oobbuf = spareAsBytes;
++              retval = mtd->read_oob(mtd, addr, &ops);
++              if (dev->useNANDECC)
++                      translate_oob2spare(spare, spareAsBytes);
++      }
++#else
++      __u8 *spareAsBytes = (__u8 *) spare;
++
++      if (data && spare) {
++              if (dev->useNANDECC) {
++                      /* Careful, this call adds 2 ints */
++                      /* to the end of the spare data.  Calling function */
++                      /* should allocate enough memory for spare, */
++                      /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
++                      retval =
++                          mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
++                                        &dummy, data, spareAsBytes,
++                                        &yaffs_oobinfo);
++              } else {
++                      retval =
++                          mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
++                                        &dummy, data, spareAsBytes,
++                                        &yaffs_noeccinfo);
++              }
++      } else {
++              if (data)
++                      retval =
++                          mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
++                                    data);
++              if (spare)
++                      retval =
++                          mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
++                                        &dummy, spareAsBytes);
++      }
++#endif
++
++      if (retval == 0)
++              return YAFFS_OK;
++      else
++              return YAFFS_FAIL;
++}
++
++int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
++{
++      struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++      __u32 addr =
++          ((loff_t) blockNumber) * dev->nDataBytesPerChunk
++              * dev->nChunksPerBlock;
++      struct erase_info ei;
++      int retval = 0;
++
++      ei.mtd = mtd;
++      ei.addr = addr;
++      ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
++      ei.time = 1000;
++      ei.retries = 2;
++      ei.callback = NULL;
++      ei.priv = (u_long) dev;
++
++      /* Todo finish off the ei if required */
++
++      sema_init(&dev->sem, 0);
++
++      retval = mtd->erase(mtd, &ei);
++
++      if (retval == 0)
++              return YAFFS_OK;
++      else
++              return YAFFS_FAIL;
++}
++
++int nandmtd_InitialiseNAND(yaffs_Device * dev)
++{
++      return YAFFS_OK;
++}
++
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif.h
+@@ -0,0 +1,27 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
 + *
@@ -226340,15 +227768,20 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffsinterface.h ../new/linux-2.6.20/fs/yaff
 + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
 + */
 +
-+#ifndef __YAFFSINTERFACE_H__
-+#define __YAFFSINTERFACE_H__
++#ifndef __YAFFS_MTDIF_H__
++#define __YAFFS_MTDIF_H__
 +
-+int yaffs_Initialise(unsigned nBlocks);
++#include "yaffs_guts.h"
 +
++int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
++                           const __u8 * data, const yaffs_Spare * spare);
++int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
++                            yaffs_Spare * spare);
++int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber);
++int nandmtd_InitialiseNAND(yaffs_Device * dev);
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c       2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c
 @@ -0,0 +1,369 @@
 +/*
 + * YAFFS: Yet another FFS. A NAND-flash specific file system.
@@ -226719,9 +228152,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif1.c ../new/linux-2.6.20/fs/yaffs2
 +}
 +
 +#endif /*MTD_VERSION*/
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h       2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h
 @@ -0,0 +1,28 @@
 +/*
 + * YAFFS: Yet another Flash File System. A NAND-flash specific file system.
@@ -226751,9 +228183,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif1.h ../new/linux-2.6.20/fs/yaffs2
 +      yaffs_BlockState * state, int *sequenceNumber);
 +
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c       2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c
 @@ -0,0 +1,232 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -226987,9 +228418,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif2.c ../new/linux-2.6.20/fs/yaffs2
 +              return YAFFS_FAIL;
 +}
 +
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h       2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h
 @@ -0,0 +1,29 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -227020,285 +228450,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif2.h ../new/linux-2.6.20/fs/yaffs2
 +                          yaffs_BlockState * state, int *sequenceNumber);
 +
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif.c ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.c
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.c        2008-09-12 12:54:03.000000000 +0530
-@@ -0,0 +1,241 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+const char *yaffs_mtdif_c_version =
-+    "$Id: yaffs_mtdif.c,v 1.21 2007/12/13 15:35:18 wookey Exp $";
-+
-+#include "yportenv.h"
-+
-+
-+#include "yaffs_mtdif.h"
-+
-+#include "linux/mtd/mtd.h"
-+#include "linux/types.h"
-+#include "linux/time.h"
-+#include "linux/mtd/nand.h"
-+
-+#if (MTD_VERSION_CODE < MTD_VERSION(2,6,18))
-+static struct nand_oobinfo yaffs_oobinfo = {
-+      .useecc = 1,
-+      .eccbytes = 6,
-+      .eccpos = {8, 9, 10, 13, 14, 15}
-+};
-+
-+static struct nand_oobinfo yaffs_noeccinfo = {
-+      .useecc = 0,
-+};
-+#endif
-+
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
-+{
-+      oob[0] = spare->tagByte0;
-+      oob[1] = spare->tagByte1;
-+      oob[2] = spare->tagByte2;
-+      oob[3] = spare->tagByte3;
-+      oob[4] = spare->tagByte4;
-+      oob[5] = spare->tagByte5 & 0x3f;
-+      oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
-+      oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
-+      oob[6] = spare->tagByte6;
-+      oob[7] = spare->tagByte7;
-+}
-+
-+static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
-+{
-+      struct yaffs_NANDSpare *nspare = (struct yaffs_NANDSpare *)spare;
-+      spare->tagByte0 = oob[0];
-+      spare->tagByte1 = oob[1];
-+      spare->tagByte2 = oob[2];
-+      spare->tagByte3 = oob[3];
-+      spare->tagByte4 = oob[4];
-+      spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
-+      spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y';
-+      spare->pageStatus = oob[5] & 0x40 ? 0xff : 0;
-+      spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
-+      spare->tagByte6 = oob[6];
-+      spare->tagByte7 = oob[7];
-+      spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;
-+
-+      nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
-+}
-+#endif
-+
-+int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
-+                           const __u8 * data, const yaffs_Spare * spare)
-+{
-+      struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+      struct mtd_oob_ops ops;
-+#endif
-+      size_t dummy;
-+      int retval = 0;
-+
-+      loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+      __u8 spareAsBytes[8]; /* OOB */
-+
-+      if (data && !spare)
-+              retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
-+                              &dummy, data);
-+      else if (spare) {
-+              if (dev->useNANDECC) {
-+                      translate_spare2oob(spare, spareAsBytes);
-+                      ops.mode = MTD_OOB_AUTO;
-+                      ops.ooblen = 8; /* temp hack */
-+              } else {
-+                      ops.mode = MTD_OOB_RAW;
-+                      ops.ooblen = YAFFS_BYTES_PER_SPARE;
-+              }
-+              ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
-+              ops.datbuf = (u8 *)data;
-+              ops.ooboffs = 0;
-+              ops.oobbuf = spareAsBytes;
-+              retval = mtd->write_oob(mtd, addr, &ops);
-+      }
-+#else
-+      __u8 *spareAsBytes = (__u8 *) spare;
-+
-+      if (data && spare) {
-+              if (dev->useNANDECC)
-+                      retval =
-+                          mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+                                         &dummy, data, spareAsBytes,
-+                                         &yaffs_oobinfo);
-+              else
-+                      retval =
-+                          mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+                                         &dummy, data, spareAsBytes,
-+                                         &yaffs_noeccinfo);
-+      } else {
-+              if (data)
-+                      retval =
-+                          mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
-+                                     data);
-+              if (spare)
-+                      retval =
-+                          mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
-+                                         &dummy, spareAsBytes);
-+      }
-+#endif
-+
-+      if (retval == 0)
-+              return YAFFS_OK;
-+      else
-+              return YAFFS_FAIL;
-+}
-+
-+int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
-+                            yaffs_Spare * spare)
-+{
-+      struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+      struct mtd_oob_ops ops;
-+#endif
-+      size_t dummy;
-+      int retval = 0;
-+
-+      loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
-+#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17))
-+      __u8 spareAsBytes[8]; /* OOB */
-+
-+      if (data && !spare)
-+              retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
-+                              &dummy, data);
-+      else if (spare) {
-+              if (dev->useNANDECC) {
-+                      ops.mode = MTD_OOB_AUTO;
-+                      ops.ooblen = 8; /* temp hack */
-+              } else {
-+                      ops.mode = MTD_OOB_RAW;
-+                      ops.ooblen = YAFFS_BYTES_PER_SPARE;
-+              }
-+              ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
-+              ops.datbuf = data;
-+              ops.ooboffs = 0;
-+              ops.oobbuf = spareAsBytes;
-+              retval = mtd->read_oob(mtd, addr, &ops);
-+              if (dev->useNANDECC)
-+                      translate_oob2spare(spare, spareAsBytes);
-+      }
-+#else
-+      __u8 *spareAsBytes = (__u8 *) spare;
-+
-+      if (data && spare) {
-+              if (dev->useNANDECC) {
-+                      /* Careful, this call adds 2 ints */
-+                      /* to the end of the spare data.  Calling function */
-+                      /* should allocate enough memory for spare, */
-+                      /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
-+                      retval =
-+                          mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+                                        &dummy, data, spareAsBytes,
-+                                        &yaffs_oobinfo);
-+              } else {
-+                      retval =
-+                          mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+                                        &dummy, data, spareAsBytes,
-+                                        &yaffs_noeccinfo);
-+              }
-+      } else {
-+              if (data)
-+                      retval =
-+                          mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
-+                                    data);
-+              if (spare)
-+                      retval =
-+                          mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
-+                                        &dummy, spareAsBytes);
-+      }
-+#endif
-+
-+      if (retval == 0)
-+              return YAFFS_OK;
-+      else
-+              return YAFFS_FAIL;
-+}
-+
-+int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
-+{
-+      struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+      __u32 addr =
-+          ((loff_t) blockNumber) * dev->nDataBytesPerChunk
-+              * dev->nChunksPerBlock;
-+      struct erase_info ei;
-+      int retval = 0;
-+
-+      ei.mtd = mtd;
-+      ei.addr = addr;
-+      ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
-+      ei.time = 1000;
-+      ei.retries = 2;
-+      ei.callback = NULL;
-+      ei.priv = (u_long) dev;
-+
-+      /* Todo finish off the ei if required */
-+
-+      sema_init(&dev->sem, 0);
-+
-+      retval = mtd->erase(mtd, &ei);
-+
-+      if (retval == 0)
-+              return YAFFS_OK;
-+      else
-+              return YAFFS_FAIL;
-+}
-+
-+int nandmtd_InitialiseNAND(yaffs_Device * dev)
-+{
-+      return YAFFS_OK;
-+}
-+
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_mtdif.h ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.h
---- linux-2.6.20/fs/yaffs2/yaffs_mtdif.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_mtdif.h        2008-09-12 12:54:03.000000000 +0530
-@@ -0,0 +1,27 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+#ifndef __YAFFS_MTDIF_H__
-+#define __YAFFS_MTDIF_H__
-+
-+#include "yaffs_guts.h"
-+
-+int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
-+                           const __u8 * data, const yaffs_Spare * spare);
-+int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
-+                            yaffs_Spare * spare);
-+int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber);
-+int nandmtd_InitialiseNAND(yaffs_Device * dev);
-+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.c ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.c
---- linux-2.6.20/fs/yaffs2/yaffs_nand.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.c 2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_nand.c
 @@ -0,0 +1,134 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -227434,52 +228587,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.c ../new/linux-2.6.20/fs/yaffs2/y
 +
 +
 +
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h ../new/linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h
---- linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h   2008-09-12 12:54:04.000000000 +0530
-@@ -0,0 +1,39 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+/* Interface to emulated NAND functions (2k page size) */
-+
-+#ifndef __YAFFS_NANDEMUL2K_H__
-+#define __YAFFS_NANDEMUL2K_H__
-+
-+#include "yaffs_guts.h"
-+
-+int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
-+                                      int chunkInNAND, const __u8 * data,
-+                                      yaffs_ExtendedTags * tags);
-+int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
-+                                       int chunkInNAND, __u8 * data,
-+                                       yaffs_ExtendedTags * tags);
-+int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
-+int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
-+                            yaffs_BlockState * state, int *sequenceNumber);
-+int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
-+                              int blockInNAND);
-+int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
-+int nandemul2k_GetBytesPerChunk(void);
-+int nandemul2k_GetChunksPerBlock(void);
-+int nandemul2k_GetNumberOfBlocks(void);
-+
-+#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.h ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.h
---- linux-2.6.20/fs/yaffs2/yaffs_nand.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_nand.h 2008-09-12 12:54:03.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_nand.h
 @@ -0,0 +1,44 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -227525,9 +228634,50 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_nand.h ../new/linux-2.6.20/fs/yaffs2/y
 +
 +#endif
 +
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c
---- linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c  2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_nandemul2k.h
+@@ -0,0 +1,39 @@
++/*
++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
++ *
++ * Copyright (C) 2002-2007 Aleph One Ltd.
++ *   for Toby Churchill Ltd and Brightstar Engineering
++ *
++ * Created by Charles Manning <charles@aleph1.co.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 2.1 as
++ * published by the Free Software Foundation.
++ *
++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
++ */
++
++/* Interface to emulated NAND functions (2k page size) */
++
++#ifndef __YAFFS_NANDEMUL2K_H__
++#define __YAFFS_NANDEMUL2K_H__
++
++#include "yaffs_guts.h"
++
++int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
++                                      int chunkInNAND, const __u8 * data,
++                                      yaffs_ExtendedTags * tags);
++int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
++                                       int chunkInNAND, __u8 * data,
++                                       yaffs_ExtendedTags * tags);
++int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
++int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
++                            yaffs_BlockState * state, int *sequenceNumber);
++int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
++                              int blockInNAND);
++int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
++int nandemul2k_GetBytesPerChunk(void);
++int nandemul2k_GetChunksPerBlock(void);
++int nandemul2k_GetNumberOfBlocks(void);
++
++#endif
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c
 @@ -0,0 +1,52 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -227581,9 +228731,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.c ../new/linux-2.6.20/fs/y
 +
 +      }
 +}
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h
---- linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h  2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h
 @@ -0,0 +1,37 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -227622,9 +228771,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags1.h ../new/linux-2.6.20/fs/y
 +void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t);
 +void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt);
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c
---- linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c  2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c
 @@ -0,0 +1,182 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -227808,9 +228956,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags2.c ../new/linux-2.6.20/fs/y
 +      yaffs_DumpTags2(t);
 +
 +}
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h
---- linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h  2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h
 @@ -0,0 +1,38 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -227850,9 +228997,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_packedtags2.h ../new/linux-2.6.20/fs/y
 +void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t);
 +void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt);
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_qsort.c ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.c
---- linux-2.6.20/fs/yaffs2/yaffs_qsort.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.c        2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_qsort.c
 @@ -0,0 +1,160 @@
 +/*
 + * Copyright (c) 1992, 1993
@@ -228014,9 +229160,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_qsort.c ../new/linux-2.6.20/fs/yaffs2/
 +      }
 +/*            yaffs_qsort(pn - r, r / es, es, cmp);*/
 +}
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_qsort.h ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.h
---- linux-2.6.20/fs/yaffs2/yaffs_qsort.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_qsort.h        2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_qsort.h
 @@ -0,0 +1,23 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -228041,9 +229186,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_qsort.h ../new/linux-2.6.20/fs/yaffs2/
 +                   int (*cmp)(const void *, const void *));
 +
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c
---- linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c   2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c
 @@ -0,0 +1,530 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -228575,9 +229719,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagscompat.c ../new/linux-2.6.20/fs/ya
 +
 +      return YAFFS_OK;
 +}
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h
---- linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h   2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h
 @@ -0,0 +1,40 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -228619,9 +229762,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagscompat.h ../new/linux-2.6.20/fs/ya
 +int yaffs_CountBits(__u8 byte);
 +
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c
---- linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c 2008-09-12 12:54:04.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c
 @@ -0,0 +1,28 @@
 +/*
 + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
@@ -228651,9 +229793,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.c ../new/linux-2.6.20/fs/
 +              tags->validMarker1 == 0x55555555);
 +
 +}
-diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h
---- linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h 2008-09-12 12:54:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h
 @@ -0,0 +1,24 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -228679,9 +229820,32 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yaffs_tagsvalidity.h ../new/linux-2.6.20/fs/
 +void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
 +int yaffs_ValidateTags(yaffs_ExtendedTags * tags);
 +#endif
-diff -Nauprw linux-2.6.20/fs/yaffs2/yportenv.h ../new/linux-2.6.20/fs/yaffs2/yportenv.h
---- linux-2.6.20/fs/yaffs2/yportenv.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/fs/yaffs2/yportenv.h   2008-09-12 12:54:05.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yaffsinterface.h
+@@ -0,0 +1,21 @@
++/*
++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
++ *
++ * Copyright (C) 2002-2007 Aleph One Ltd.
++ *   for Toby Churchill Ltd and Brightstar Engineering
++ *
++ * Created by Charles Manning <charles@aleph1.co.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 2.1 as
++ * published by the Free Software Foundation.
++ *
++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
++ */
++
++#ifndef __YAFFSINTERFACE_H__
++#define __YAFFSINTERFACE_H__
++
++int yaffs_Initialise(unsigned nBlocks);
++
++#endif
+--- /dev/null
++++ linux-2.6.20/fs/yaffs2/yportenv.h
 @@ -0,0 +1,200 @@
 +/*
 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
@@ -228883,60 +230047,8 @@ diff -Nauprw linux-2.6.20/fs/yaffs2/yportenv.h ../new/linux-2.6.20/fs/yaffs2/ypo
 +#endif
 +
 +#endif
-diff -Nauprw linux-2.6.20/.gitignore ../new/linux-2.6.20/.gitignore
---- linux-2.6.20/.gitignore    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/.gitignore     1970-01-01 05:30:00.000000000 +0530
-@@ -1,47 +0,0 @@
--#
--# NOTE! Don't add files that are generated in specific
--# subdirectories here. Add them in the ".gitignore" file
--# in that subdirectory instead.
--#
--# Normal rules
--#
--.*
--*.o
--*.a
--*.s
--*.ko
--*.so
--*.mod.c
--*.i
--*.lst
--*.symtypes
--
--#
--# Top-level generic files
--#
--tags
--TAGS
--vmlinux*
--System.map
--Module.symvers
--
--#
--# Generated include files
--#
--include/asm
--include/asm-*/asm-offsets.h
--include/config
--include/linux/autoconf.h
--include/linux/compile.h
--include/linux/version.h
--include/linux/utsrelease.h
--
--# stgit generated dirs
--patches-*
--
--# quilt's files
--patches
--series
--
--# cscope files
--cscope.*
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h      2008-11-24 14:06:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h
 @@ -0,0 +1,444 @@
 +/* include/asm-arm/arch-nomadik/audiocodec.h
 + *
@@ -229382,9 +230494,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/audiocodec.h ../new/linux
 +#endif                                /* _AUDIOCODEC_H_ */
 +
 +/* End of file audiocodec.h*/
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/bits.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/bits.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/bits.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/bits.h    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/bits.h
 @@ -0,0 +1,61 @@
 +/*
 + * This program is free software; you can redistribute it and/or modify
@@ -229447,9 +230558,49 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/bits.h ../new/linux-2.6.2
 +#endif
 +
 +/*         END */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/debug.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug.h   2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S
+@@ -0,0 +1,38 @@
++/* linux/include/asm-arm/arch-integrator/debug-macro.S
++ *
++ * Debugging macro include header
++ *
++ *  Copyright (C) 1994-1999 Russell King
++ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++*/
++
++#include <linux/amba/serial.h>
++
++              .macro  addruart,rx
++              mrc     p15, 0, \rx, c1, c0
++              tst     \rx, #1                 @ MMU enabled?
++              moveq   \rx, #0xA0000000        @ physical base address
++              movne   \rx, #0xf0000000        @ virtual base
++              addne   \rx, \rx, #0xA0000000 >> 4
++              .endm
++
++              .macro  senduart,rd,rx
++              strb    \rd, [\rx, #UART01x_DR]
++              .endm
++
++              .macro  waituart,rd,rx
++1001:         ldr     \rd, [\rx, #0x18]       @ UARTFLG
++              tst     \rd, #1 << 5            @ UARTFLGUTXFF - 1 when full
++              bne     1001b
++              .endm
++
++              .macro  busyuart,rd,rx
++1001:         ldr     \rd, [\rx, #0x18]       @ UARTFLG
++              tst     \rd, #1 << 3            @ UARTFLGUBUSY - 1 when busy
++              bne     1001b
++              .endm
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/debug.h
 @@ -0,0 +1,148 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/debug-nomadik.h
@@ -229463,9 +230614,9 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug.h ../new/linux-2.6.
 + * Description:  Nomadik debug message strategy include file
 + *
 + * Reference:  Documentation/arm/STM-Nomadik/debug_strategy.txt
-+ * 
++ *
 + * Author : ST Microelectronics
-+ *    
++ *
 + * ---------------------------------------------------------------------
 + */
 +
@@ -229599,51 +230750,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug.h ../new/linux-2.6.
 +#endif                                /* __INC_DBG_H */
 +
 +/* End of file - debug.h */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S
---- linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/debug-macro.S     2007-11-21 11:51:41.000000000 +0530
-@@ -0,0 +1,38 @@
-+/* linux/include/asm-arm/arch-integrator/debug-macro.S
-+ *
-+ * Debugging macro include header
-+ *
-+ *  Copyright (C) 1994-1999 Russell King
-+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+*/
-+
-+#include <linux/amba/serial.h>
-+
-+              .macro  addruart,rx
-+              mrc     p15, 0, \rx, c1, c0
-+              tst     \rx, #1                 @ MMU enabled?
-+              moveq   \rx, #0xA0000000        @ physical base address
-+              movne   \rx, #0xf0000000        @ virtual base
-+              addne   \rx, \rx, #0xA0000000 >> 4
-+              .endm
-+
-+              .macro  senduart,rd,rx
-+              strb    \rd, [\rx, #UART01x_DR]
-+              .endm
-+
-+              .macro  waituart,rd,rx
-+1001:         ldr     \rd, [\rx, #0x18]       @ UARTFLG
-+              tst     \rd, #1 << 5            @ UARTFLGUTXFF - 1 when full
-+              bne     1001b
-+              .endm
-+
-+              .macro  busyuart,rd,rx
-+1001:         ldr     \rd, [\rx, #0x18]       @ UARTFLG
-+              tst     \rd, #1 << 3            @ UARTFLGUBUSY - 1 when busy
-+              bne     1001b
-+              .endm
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/defs.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/defs.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/defs.h    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/defs.h
 @@ -0,0 +1,245 @@
 +/*
 + *  include/asm/arch/defs.h
@@ -229660,7 +230768,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.2
 +
 +#ifndef __ASSEMBLY__
 +/*
-+ * Type definition                                                               
++ * Type definition
 + */
 +#ifndef BITS64        /*to remove conflict with arch/arm/nwfpe/ARM-gcc.h*/
 +typedef unsigned char uint8;
@@ -229687,7 +230795,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.2
 +
 +/*
 + * Global frequency enumuration
-+ * Added to avoid frequency conversion function which is required to convert one HCL 
++ * Added to avoid frequency conversion function which is required to convert one HCL
 + * frequency enumuration values to another HCL frequency enumuration values.
 + */
 +
@@ -229743,7 +230851,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.2
 +} version_t;
 +
 +/*
-+ * Keyword definition 
++ * Keyword definition
 + */
 +#ifndef NULL
 +#define NULL     (0)
@@ -229890,9 +230998,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/defs.h ../new/linux-2.6.2
 +#endif
 +#endif /*__ASSEMBLY__*/
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/dma.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/dma.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/dma.h     2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/dma.h
 @@ -0,0 +1,362 @@
 +/* include/asm-arm/arch-nomadik/dma.h
 + *
@@ -229919,7 +231026,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +
 +#include <asm/arch/defs.h>
 +
-+#define MAX_DMA_CHANNELS      32      
++#define MAX_DMA_CHANNELS      32
 +/* MAX_DMA_CHANNELS can be increased upto 127 if system needs more channels */
 +#define MAX_DMA_LLIS          (MAX_DMA_CHANNELS*4096)
 +/*
@@ -229956,7 +231063,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 + */
 +struct dmach_lli {
 +      union {
-+              struct dmach_lli * p_lli_qh; 
++              struct dmach_lli * p_lli_qh;
 +              dma_addr_t sadr;
 +      } mem1;
 +      union {
@@ -230015,7 +231122,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +};
 +
 +/**
-+ * data structure for default dma peripharal setup 
++ * data structure for default dma peripharal setup
 + */
 +struct dmadev_description {
 +      char * id;
@@ -230024,7 +231131,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +};
 +
 +/**
-+ * data structure for chip specific interface 
++ * data structure for chip specific interface
 + */
 +struct dma_soc_data {
 +      struct dma_struct *dma_chan;
@@ -230035,7 +231142,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +};
 +
 +/**
-+ * Figurative constants and enums used ............... 
++ * Figurative constants and enums used ...............
 + */
 +#define NMDK_DMACH_ENABLE     1UL
 +#define NMDK_DMACH_HALT               1UL<<18
@@ -230143,7 +231250,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +/* ............ Client Driver Interface ...................*/
 +
 +/**
-+ * data structure for client driver interface 
++ * data structure for client driver interface
 + */
 +struct nmdk_dma_info {
 +      u32 mode;               /* operation mode (xfer type/flow cntrl etc)*/
@@ -230185,7 +231292,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +#define DMA_QUEUE_ENABLED             0x040   /*To enable queueing for a channel*/
 +#define DMA_QUEUE_DISABLED            0x000   /*To disable queueing for a channel*/
 +
-+#define DMA_EXCH_PRIORITY_UNDEFINED   0x0000  
++#define DMA_EXCH_PRIORITY_UNDEFINED   0x0000
 +#define DMA_EXCH_PRIORITY_LOW         0x0100
 +#define DMA_EXCH_PRIORITY_NORMAL      0x0200
 +#define DMA_EXCH_PRIORITY_HIGH                0x0400
@@ -230256,9 +231363,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/dma.h ../new/linux-2.6.20
 +#endif        /* __INC_DMA_H */
 +/* End of file - dma.h */
 +
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S
---- linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S     2008-07-04 23:45:25.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S
 @@ -0,0 +1,210 @@
 +/*
 + * include/asm-arm/arch-integrator/entry-macro.S
@@ -230350,7 +231456,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linu
 +      str     \tmp, [\base, #0x7bc]           @ clean data in n way*/
 +1004:
 +      ldr     \base, =NOMADIK_L2CC_BASE
-+      ldr     \tmp, [\base, #0x7bc]           
++      ldr     \tmp, [\base, #0x7bc]
 +      ldr     \base, =0
 +      cmp     \tmp, \base
 +      bne 1004b                               @ loop for completion
@@ -230365,7 +231471,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linu
 +      str     \tmp, [\base, #0x7fc]           @ clean and invalidate data in n way*/
 +1005:
 +      ldr     \base, =NOMADIK_L2CC_BASE
-+      ldr     \tmp, [\base, #0x7fc]           
++      ldr     \tmp, [\base, #0x7fc]
 +      ldr     \base, =0
 +      cmp     \tmp, \base
 +      bne 1005b                               @ loop for completion
@@ -230380,7 +231486,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linu
 +      str     \tmp, [\base, #0x77c]           @ invalidate data in n way*/
 +1006:
 +      ldr     \base, =NOMADIK_L2CC_BASE
-+      ldr     \tmp, [\base, #0x77c]           
++      ldr     \tmp, [\base, #0x77c]
 +      ldr     \base, =0
 +      cmp     \tmp, \base
 +      bne 1006b                               @ loop for completion
@@ -230413,7 +231519,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linu
 +      str     \tmp, [\base, #0x7fc]           @ clean and invalidate data in n way*/
 +2005:
 +      ldr     \base, =IO_ADDRESS(NOMADIK_L2CC_BASE)
-+      ldr     \tmp, [\base, #0x7fc]           
++      ldr     \tmp, [\base, #0x7fc]
 +      ldr     \base, =0
 +      cmp     \tmp, \base
 +      bne 2005b                               @ loop for completion
@@ -230464,15 +231570,14 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/entry-macro.S ../new/linu
 +      str     \tmp, [\base, #0x77c]           @ invalidate data in n way*/
 +1006:
 +      ldr     \base, =NOMADIK_L2CC_BASE
-+      ldr     \tmp, [\base, #0x77c]           
++      ldr     \tmp, [\base, #0x77c]
 +      ldr     \base, =0
 +      cmp     \tmp, \base
 +      bne 1006b                               @ loop for completion
 +#endif
 +      .endm
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/epio.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/epio.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/epio.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/epio.h    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/epio.h
 @@ -0,0 +1,24 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/epio-nomadik.h
@@ -230498,9 +231603,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/epio.h ../new/linux-2.6.2
 +#include <asm/arch/board/epio.h>
 +
 +#endif        /*__ASM_ARM_ARCH_EPIO_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h    2008-09-17 13:23:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h
 @@ -0,0 +1,203 @@
 +/* include/asm-arm/arch-nomadik/fsmc.h
 + *
@@ -230705,9 +231809,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/fsmc.h ../new/linux-2.6.2
 +                                    fsmc_sram_nor_ctrl * p_bank_ctrl);
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h    2008-09-17 13:23:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h
 @@ -0,0 +1,529 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/gpio.h
@@ -230860,7 +231963,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.2
 +} gpio_device_id;
 +
 +/*
-+ * Pin description To be used in SOFTWARE mode: refers to a pin. 
++ * Pin description To be used in SOFTWARE mode: refers to a pin.
 + */
 +typedef enum {
 +      GPIO_PIN_0,
@@ -231044,11 +232147,11 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.2
 +      GPIO_ALT_CCP1,
 +#ifdef CONFIG_NOMADIK_NHK15
 +      GPIO_ALT_ETHERNET,
-+      GPIO_ALT_ETM,   
++      GPIO_ALT_ETM,
 +#endif
 +#ifdef CONFIG_MTD_ONENAND
 +      GPIO_ALT_ONENAND,
-+#endif        
++#endif
 +      GPIO_ALT_FUNMAX         /* Add new alt func before this */
 +} gpio_alt_function;
 +
@@ -231153,7 +232256,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.2
 +/* GPIO behaviour in sleep mode */
 +typedef enum {
 +      GPIO_SLEEP_MODE_LEAVE_UNCHANGED,        /* Parameter will be ignored by the function. */
-+      GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT,      /* GPIO is an input with pull up/down enabled 
++      GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT,      /* GPIO is an input with pull up/down enabled
 +                                                 when in sleep mode. */
 +      GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO      /* GPIO pin  is controlled by GPIO IP. So mode,
 +                                                 direction and data values for GPIO pin in
@@ -231229,7 +232332,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.2
 +};
 +
 +/**
-+ * providing this flag during request_irq tells gpio driver that the requested 
++ * providing this flag during request_irq tells gpio driver that the requested
 + * interrupt handler to be executed in tasklet's context.
 + */
 +#define SA_GPIOINTR_IN_TASKLET                SA_ONSTACK
@@ -231238,9 +232341,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/gpio.h ../new/linux-2.6.2
 +#define GPIOINTR_TASKLET_ENABLED      0x10000000
 +
 +#endif                                /* __INC_GPIO_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h        2008-09-17 13:23:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h
 @@ -0,0 +1,107 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/hardware.h
@@ -231275,8 +232377,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h ../new/linux-2
 +#define IO_SIZE                       0x1FF00000      /* VA Size for IO */
 +#define IO_START              0x10100000      /* PA of IO */
 +
-+/* 
-+ * macro to get at IO space when running virtually 
++/*
++ * macro to get at IO space when running virtually
 + */
 +#define IO_ADDRESS(x) ((x) | IO_BASE)
 +
@@ -231336,7 +232438,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h ../new/linux-2
 +#define SSP_PER_MASK                  0x0fffffff
 +
 +/*
-+ * platform specific other constants 
++ * platform specific other constants
 + */
 +#define UART_CONTROL_MASK_RTSFLOW     0x04000
 +#define UART_CONTROL_MASK_CTSFLOW     0x08000
@@ -231349,9 +232451,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/hardware.h ../new/linux-2
 +#define NOMADIK_MTU1_VA (IO_ADDRESS(NOMADIK_MTU1_BASE))
 +
 +#endif                                /* __ASM_ARCH_HARDWARE_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h     2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h
 @@ -0,0 +1,419 @@
 +/* include/asm-arm/arch-nomadik/i2c.h
 + *
@@ -231496,9 +232597,9 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h ../new/linux-2.6.20
 +typedef enum {
 +      I2C_NO_INDEX,           /* Current transfer is non-indexed      */
 +      I2C_BYTE_INDEX,         /* Current transfer uses 8-bit index    */
-+      I2C_HALF_WORD_LITTLE_ENDIAN,    /* Current transfer uses 16-bit index 
++      I2C_HALF_WORD_LITTLE_ENDIAN,    /* Current transfer uses 16-bit index
 +                                         in little endian mode                */
-+      I2C_HALF_WORD_BIG_ENDIAN        /* Current transfer uses 16-bit index 
++      I2C_HALF_WORD_BIG_ENDIAN        /* Current transfer uses 16-bit index
 +                                         in big endian mode                   */
 +} i2c_index_format_t;
 +
@@ -231772,9 +232873,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/i2c.h ../new/linux-2.6.20
 +                             __u8 * data, int index, int count);
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/io.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/io.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/io.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/io.h      2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/io.h
 @@ -0,0 +1,37 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/io.h
@@ -231813,9 +232913,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/io.h ../new/linux-2.6.20/
 +#define __mem_isa(a)          ((a) + PCI_MEMORY_VADDR)
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h    2007-11-21 11:51:41.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h
 @@ -0,0 +1,137 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/irqs.h
@@ -231854,13 +232953,13 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h ../new/linux-2.6.2
 + * followed by irq requested with SA_IRQPRIORITY_0 to SA_IRQPRIORITY_15.
 + * Standard IRQs requested without priority flag have the lowest priority.
 + *
-+ * When any interrupt is being serviced, and if higher priority interrupt 
++ * When any interrupt is being serviced, and if higher priority interrupt
 + * occures it will be serviced first.
 + *
 + * interrupt priority can also be enabled, disabled or changed at any moment of
-+ * time for a valid pre-requested interrupt by using API "set_irq_type" 
++ * time for a valid pre-requested interrupt by using API "set_irq_type"
 + */
-+#define SA_NMDK_PRIORITYIRQ   (SA_TRIGGER_LOW | SA_TRIGGER_HIGH)              
++#define SA_NMDK_PRIORITYIRQ   (SA_TRIGGER_LOW | SA_TRIGGER_HIGH)
 +#define SA_IRQPRIORITY_1      (0x00100000 | SA_NMDK_PRIORITYIRQ)
 +#define SA_IRQPRIORITY_2      (0x00200000 | SA_NMDK_PRIORITYIRQ)
 +#define SA_IRQPRIORITY_3      (0x00300000 | SA_NMDK_PRIORITYIRQ)
@@ -231878,11 +232977,11 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h ../new/linux-2.6.2
 +#define SA_IRQPRIORITY_15     (0x00f00000 | SA_NMDK_PRIORITYIRQ)
 +#define SA_IRQPRIORITY_MASK   (0x00f00000 | SA_NMDK_PRIORITYIRQ)
 +
-+#define VIC_PRIORITY_LOGIC_ENABLED            
++#define VIC_PRIORITY_LOGIC_ENABLED
 +#define VIC_VECTORED_IRQ_NUM    16    /*maximum available verctored irqs*/
 +#define IRQ_PIC_START         0       /*used by entry_macro.S*/
 +
-+/* 
++/*
 + * Interrupt numbers generic for all Nomadik Chip cuts
 + */
 +#define IRQ_WATCHDOG                  0
@@ -231936,7 +233035,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h ../new/linux-2.6.2
 +/*
 + * Below values need to be checked
 + */
-+#define MAXFIQNUM     31 
++#define MAXFIQNUM     31
 +#define MAXSWINUM     31
 +
 +#define MAX_CHIP_IRQ  ( MAXIRQNUM + 1 )
@@ -231949,14 +233048,13 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/irqs.h ../new/linux-2.6.2
 +/*  Macros to get irqno for GPIO pin and vice-versa*/
 +#define IRQNO_GPIO(x)         ( MAX_CHIP_IRQ  + x )
 +#define GPIO_PIN_FOR_IRQ(x)   ( x - MAX_CHIP_IRQ)
-+#define IRQNO_FOR_DMACH(x)    ( MAX_GPIO_IRQ + x )    
++#define IRQNO_FOR_DMACH(x)    ( MAX_GPIO_IRQ + x )
 +#define DMACH_FOR_IRQNO(x)    ( x - MAX_GPIO_IRQ)
 +
 +#endif /*ASM_ARCH_IRQS_H*/
 +
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/kpd.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/kpd.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/kpd.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/kpd.h     2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/kpd.h
 @@ -0,0 +1,56 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/kpd.h
@@ -232014,9 +233112,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/kpd.h ../new/linux-2.6.20
 +};
 +
 +#endif        /*__ASM_ARM_ARCH_KPD_NOMADIK_H*/
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/memory.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/memory.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/memory.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/memory.h  2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/memory.h
 @@ -0,0 +1,41 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/memory.h
@@ -232059,9 +233156,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/memory.h ../new/linux-2.6
 +#define CONSISTENT_DMA_SIZE   SZ_32M
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h     2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h
 @@ -0,0 +1,234 @@
 +/*
 + *  linux/drivers/mmc/nomadik_mmc.h - ARM PrimeCell MMCI PL180 driver
@@ -232297,335 +233393,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mmc.h ../new/linux-2.6.20
 +};
 +
 +
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/msp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp.h     2008-11-19 16:47:04.000000000 +0530
-@@ -0,0 +1,322 @@
-+/*Copyright 2006, STMicroelectronics
-+ *
-+ *
-+ * 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 NOMADIC_MSP_HEADER
-+#define NOMADIC_MSP_HEADER
-+
-+/* Generic config struct. Use the actual values defined below for global
-+ * control register
-+ */
-+
-+struct msp_generic_config {
-+      unsigned int input_clock_freq;
-+      unsigned int rx_clock_sel;
-+      unsigned int tx_clock_sel;
-+      unsigned int srg_clock_sel;
-+      unsigned int rx_endianess;
-+      unsigned int tx_endianess;
-+      unsigned int rx_frame_sync_pol;
-+      unsigned int tx_frame_sync_pol;
-+      unsigned int rx_frame_sync_sel;
-+      unsigned int tx_frame_sync_sel;
-+      unsigned int rx_unexpect_frame_sync;
-+      unsigned int tx_unexpect_frame_sync;
-+      unsigned int rx_fifo_config;
-+      unsigned int tx_fifo_config;
-+      unsigned int spi_clk_mode;
-+      unsigned int spi_burst_mode;
-+};
-+typedef enum {
-+      MSP_REQUEST_NOT_APPLICABLE = -9,
-+      MSP_BAD_PERIHERAL_ID = -8,
-+      MSP_TRANSMISSION_ON_GOING = -7,
-+      MSP_TRANSMIT_FIFO_TIMEOUT = -6,
-+      MSP_FEATURE_NOT_SUPPORTED = -5,
-+      MSP_NON_AUTHORIZED_MODE = -4,
-+      MSP_NO_ACTIVE_IT_ERROR = -3,
-+      MSP_NOT_CONFIGURED = -2,
-+      MSP_PARAMETER_ERROR = -1,
-+      MSP_OK = 0,
-+      MSP_INTERNAL_EVENT = 1,
-+      MSP_REMAINING_PENDING_EVENTS = 2,
-+      MSP_REMAINING_FILTER_PENDING_EVENTS = 3,
-+      MSP_NO_MORE_PENDING_EVENT = 4,
-+      MSP_NO_MORE_FILTER_PENDING_EVENT = 5,
-+      MSP_NO_PENDING_EVENT_ERROR = 7
-+} t_msp_error;
-+
-+/*** Protocols ***/
-+enum {
-+      MSP_I2S_PROTOCOL,
-+      MSP_PCM_PROTOCOL,
-+      MSP_PCM_COMPAND_PROTOCOL,
-+      MSP_AC97_PROTOCOL,
-+      MSP_MASTER_SPI_PROTOCOL,
-+      MSP_SLAVE_SPI_PROTOCOL,
-+      MSP_INVALID_PROTOCOL
-+};
-+
-+/*** Sample Frequencies ***/
-+/* These are no longer required, frequencies in Hz can be used directly */
-+enum {
-+      MSP_SAMPLE_FREQ_NOT_SUPPORTED = -1,
-+      MSP_SAMPLE_FREQ_8KHZ = 8000,
-+      MSP_SAMPLE_FREQ_12KHZ = 12000,
-+      MSP_SAMPLE_FREQ_16KHZ = 16000,
-+      MSP_SAMPLE_FREQ_24KHZ = 24000,
-+      MSP_SAMPLE_FREQ_32KHZ = 32000,
-+      MSP_SAMPLE_FREQ_44KHZ = 44000,
-+      MSP_SAMPLE_FREQ_48KHZ = 48000,
-+      MSP_SAMPLE_FREQ_64KHZ = 64000,
-+      MSP_SAMPLE_FREQ_88KHZ = 88000,
-+      MSP_SAMPLE_FREQ_96KHZ = 96000,
-+      MSP_SAMPLE_FREQ_22KHZ = 22000,
-+      MSP_SAMPLE_FREQ_11KHZ = 11000
-+};
-+
-+/*** Input Frequencies ***/
-+/* These are no longer required, frequencies in Hz can be used directly */
-+typedef enum {
-+
-+      MSP_INPUT_FREQ_1MHZ  = 1000,
-+      MSP_INPUT_FREQ_2MHZ  = 2000,
-+      MSP_INPUT_FREQ_3MHZ  = 3000,
-+      MSP_INPUT_FREQ_4MHZ  = 4000,
-+      MSP_INPUT_FREQ_5MHZ  = 5000,
-+      MSP_INPUT_FREQ_6MHZ  = 6000,
-+      MSP_INPUT_FREQ_8MHZ  = 8000,
-+      MSP_INPUT_FREQ_11MHZ = 11000,
-+      MSP_INPUT_FREQ_12MHZ = 12000,
-+      MSP_INPUT_FREQ_16MHZ = 16000,
-+      MSP_INPUT_FREQ_22MHZ = 22000,
-+      MSP_INPUT_FREQ_24MHZ = 24000,
-+      MSP_INPUT_FREQ_48MHZ = 48000
-+
-+} t_msp_in_clock_freq;
-+
-+#define MSP_INPUT_FREQ_APB 48000000
-+
-+/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono),
-+ *   32 bits accesses (stereo).
-+ ***/
-+enum
-+{
-+      MSP_MONO,
-+      MSP_STEREO
-+};
-+
-+/* Direction (Transmit/Receive mode) */
-+enum {
-+      MSP_TRANSMIT_MODE,
-+      MSP_RECEIVE_MODE,
-+      MSP_BOTH_T_R_MODE
-+};
-+
-+/* Dma mode should be used for large transfers,
-+ * polling mode should be used for transfers of a few bytes
-+ */
-+enum {
-+      MSP_DMA_MODE,
-+      MSP_POLLING_MODE,
-+      MSP_INTERRUPT_MODE
-+};
-+
-+/* User client for the MSP */
-+typedef enum {
-+      MSP_NO_USER = 0,
-+      MSP_USER_SPI,
-+      MSP_USER_ALSA,
-+      MSP_USER_SAA,
-+}t_msp_user;
-+
-+/*Flag structure for MSPx*/
-+typedef struct {
-+      struct semaphore        lock;
-+      t_msp_user              user;
-+}msp_flag ;
-+
-+
-+/* Transmit and receive configuration register */
-+#define MSP_BIG_ENDIAN           0x00000000
-+#define MSP_LITTLE_ENDIAN        0x00001000
-+#define MSP_UNEXPECTED_FS_ABORT  0x00000000
-+#define MSP_UNEXPECTED_FS_IGNORE 0x00008000
-+#define MSP_NON_MODE_BIT_MASK    0x00009000
-+
-+/* Global configuration register
-+--------------------------------*/
-+#define RX_ENABLE             0x00000001
-+#define RX_FIFO_ENABLE        0x00000002
-+#define RX_SYNC_SRG           0x00000010
-+#define RX_CLK_POL_RISING     0x00000020
-+#define RX_CLK_SEL_SRG        0x00000040
-+#define TX_ENABLE             0x00000100
-+#define TX_FIFO_ENABLE        0x00000200
-+#define TX_SYNC_SRG_PROG      0x00001800
-+#define TX_CLK_POL_RISING     0x00002000
-+#define TX_CLK_SEL_SRG        0x00004000
-+#define TX_EXTRA_DELAY_ENABLE 0x00008000
-+#define SRG_ENABLE            0x00010000
-+#define FRAME_GEN_ENABLE      0x00100000
-+#define SRG_CLK_SEL_APB       0x00000000
-+#define RX_FIFO_SYNC_HI       0x00000000
-+#define TX_FIFO_SYNC_HI       0x00000000
-+#define SPI_CLK_MODE_NORMAL   0x00000000
-+
-+/* SPI Clock Modes enumertion
-+ * SPI clock modes of MSP provides compatibility with
-+ * the SPI protocol.MSP supports 2 SPI transfer formats.
-+ * MSP_ZERO_DELAY_SPI_MODE:MSP transmits data over Tx/Rx
-+ * Lines immediately after MSPTCK/MSPRCK rising/falling edge.
-+ * MSP_HALF_CYCLE_DELY_SPI_MODE:MSP transmits data  one-half cycle
-+ * ahead of the rising/falling edge of the MSPTCK
-+ */
-+enum {
-+      MSP_NON_SPI_PROTOCOL = 0,
-+      MSP_ZERO_DELAY_SPI_MODE = 2,
-+      MSP_HALF_CYCLE_DELY_SPI_MODE = 3
-+};
-+
-+#define MSP_FRAME_SIZE_AUTO -1
-+
-+enum msp_data_size{
-+      MSP_DATA_SIZE_DEFAULT = -1,
-+      MSP_DATA_SIZE_8BIT,
-+      MSP_DATA_SIZE_10BIT,
-+      MSP_DATA_SIZE_12BIT,
-+      MSP_DATA_SIZE_14BIT,
-+      MSP_DATA_SIZE_16BIT,
-+      MSP_DATA_SIZE_20BIT,
-+      MSP_DATA_SIZE_24BIT,
-+      MSP_DATA_SIZE_32BIT,
-+};
-+
-+#define MSP_I2S_SIMPLE_CONFIG { \
-+      MSP_INPUT_FREQ_APB, \
-+      RX_CLK_SEL_SRG, \
-+      TX_CLK_SEL_SRG, \
-+      SRG_CLK_SEL_APB, \
-+      MSP_BIG_ENDIAN, \
-+      MSP_BIG_ENDIAN, \
-+      RX_FIFO_SYNC_LOW, \
-+      TX_FIFO_SYNC_LOW, \
-+      RX_SYNC_SRG, \
-+      TX_SYNC_SRG_PROG, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      RX_FIFO_ENABLE, \
-+      TX_FIFO_ENABLE, \
-+      SPI_CLK_MODE_NORMAL, \
-+      SPI_BURST_MODE_DISABLE \
-+}
-+
-+#define MSP_PCM_SIMPLE_CONFIG { \
-+      MSP_INPUT_FREQ_APB, \
-+      RX_CLK_SEL_SRG, \
-+      TX_CLK_SEL_SRG, \
-+      SRG_CLK_SEL_APB, \
-+      MSP_BIG_ENDIAN, \
-+      MSP_BIG_ENDIAN, \
-+      RX_FIFO_SYNC_HI, \
-+      TX_FIFO_SYNC_HI, \
-+      RX_SYNC_SRG, \
-+      TX_SYNC_SRG_AUTO, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      RX_FIFO_ENABLE, \
-+      TX_FIFO_ENABLE, \
-+      SPI_CLK_MODE_NORMAL, \
-+      SPI_BURST_MODE_DISABLE \
-+}
-+
-+#define MSP_MASTER_SPI_SIMPLE_CONFIG { \
-+      MSP_INPUT_FREQ_APB, \
-+      RX_CLK_SEL_SRG, \
-+      TX_CLK_SEL_SRG, \
-+      SRG_CLK_SEL_APB, \
-+      MSP_BIG_ENDIAN, \
-+      MSP_BIG_ENDIAN, \
-+      RX_FIFO_SYNC_LOW, \
-+      TX_FIFO_SYNC_LOW, \
-+      RX_SYNC_SRG, \
-+      TX_SYNC_SRG_AUTO, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      RX_FIFO_ENABLE, \
-+      TX_FIFO_ENABLE, \
-+      SPI_CLK_MODE_ZERO_DLY, \
-+      SPI_BURST_MODE_DISABLE \
-+}
-+
-+#define MSP_SLAVE_SPI_SIMPLE_CONFIG { \
-+      MSP_INPUT_FREQ_APB, \
-+      RX_CLK_SEL_EXT, \
-+      TX_CLK_SEL_EXT, \
-+      SRG_CLK_SEL_APB, \
-+      MSP_BIG_ENDIAN, \
-+      MSP_BIG_ENDIAN, \
-+      RX_FIFO_SYNC_LOW, \
-+      TX_FIFO_SYNC_LOW, \
-+      RX_SYNC_EXT, \
-+      TX_SYNC_EXT, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      MSP_UNEXPECTED_FS_IGNORE, \
-+      RX_FIFO_ENABLE, \
-+      TX_FIFO_ENABLE, \
-+      SPI_CLK_MODE_ZERO_DLY, \
-+      SPI_BURST_MODE_DISABLE \
-+}
-+
-+#ifdef __KERNEL__
-+/* exported functions */
-+#include<linux/types.h>
-+int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user);
-+int nomadik_msp_send_data(int msp, void *data, size_t bytes);
-+int nomadik_msp_receive_data(int msp, void *data, size_t bytes);
-+int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
-+                              void *rxdata, size_t rxbytes);
-+int nomadik_msp_enable(int msp, int direction, int work_mode,
-+                     int protocol, int frame_freq, int frame_size,
-+                     enum msp_data_size data_size, t_msp_user user);
-+int nomadik_msp_disable(int msp, int direction, t_msp_user user);
-+void nomadik_msp_flush_input(int msp);
-+#endif
-+
-+/***************************************************************************************
-+ *
-+ * User space interface starts here. This is intended for testing only.
-+ *
-+ ***************************************************************************************/
-+struct msp_user_enable {
-+      int direction;
-+      int work_mode;
-+      int protocol;
-+      int frame_freq;
-+      int frame_size;
-+      enum msp_data_size data_size;
-+};
-+
-+#include <linux/ioctl.h>
-+
-+#define MSP_IOC_MAGIC 'M'
-+#define MSP_CONFIGURE _IOW(MSP_IOC_MAGIC, 0, struct msp_generic_config)
-+#define MSP_ENABLE _IOW(MSP_IOC_MAGIC, 1, struct msp_user_enable)
-+#define MSP_DISABLE _IOW(MSP_IOC_MAGIC, 2, int)
-+
-+#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h
 @@ -0,0 +1,343 @@
 +/*
 + * arch/arm/mach-nomadik/msp-spi.h
@@ -232921,7 +233690,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h ../new/linux-2.
 +
 +
 +/*#######################################################################
-+    MSP Interrupt related Macros      
++    MSP Interrupt related Macros
 +#########################################################################
 + */
 +#define DISABLE_ALL_MSP_INTERRUPTS  0x0
@@ -232929,7 +233698,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h ../new/linux-2.
 +#define CLEAR_ALL_MSP_INTERRUPTS  0xEE
 +
 +/*#######################################################################
-+    Default MSP Register Values       
++    Default MSP Register Values
 +#########################################################################
 + */
 +
@@ -232970,9 +233739,333 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/msp-spi.h ../new/linux-2.
 +      )
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h     2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/msp.h
+@@ -0,0 +1,322 @@
++/*Copyright 2006, STMicroelectronics
++ *
++ *
++ * 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 NOMADIC_MSP_HEADER
++#define NOMADIC_MSP_HEADER
++
++/* Generic config struct. Use the actual values defined below for global
++ * control register
++ */
++
++struct msp_generic_config {
++      unsigned int input_clock_freq;
++      unsigned int rx_clock_sel;
++      unsigned int tx_clock_sel;
++      unsigned int srg_clock_sel;
++      unsigned int rx_endianess;
++      unsigned int tx_endianess;
++      unsigned int rx_frame_sync_pol;
++      unsigned int tx_frame_sync_pol;
++      unsigned int rx_frame_sync_sel;
++      unsigned int tx_frame_sync_sel;
++      unsigned int rx_unexpect_frame_sync;
++      unsigned int tx_unexpect_frame_sync;
++      unsigned int rx_fifo_config;
++      unsigned int tx_fifo_config;
++      unsigned int spi_clk_mode;
++      unsigned int spi_burst_mode;
++};
++typedef enum {
++      MSP_REQUEST_NOT_APPLICABLE = -9,
++      MSP_BAD_PERIHERAL_ID = -8,
++      MSP_TRANSMISSION_ON_GOING = -7,
++      MSP_TRANSMIT_FIFO_TIMEOUT = -6,
++      MSP_FEATURE_NOT_SUPPORTED = -5,
++      MSP_NON_AUTHORIZED_MODE = -4,
++      MSP_NO_ACTIVE_IT_ERROR = -3,
++      MSP_NOT_CONFIGURED = -2,
++      MSP_PARAMETER_ERROR = -1,
++      MSP_OK = 0,
++      MSP_INTERNAL_EVENT = 1,
++      MSP_REMAINING_PENDING_EVENTS = 2,
++      MSP_REMAINING_FILTER_PENDING_EVENTS = 3,
++      MSP_NO_MORE_PENDING_EVENT = 4,
++      MSP_NO_MORE_FILTER_PENDING_EVENT = 5,
++      MSP_NO_PENDING_EVENT_ERROR = 7
++} t_msp_error;
++
++/*** Protocols ***/
++enum {
++      MSP_I2S_PROTOCOL,
++      MSP_PCM_PROTOCOL,
++      MSP_PCM_COMPAND_PROTOCOL,
++      MSP_AC97_PROTOCOL,
++      MSP_MASTER_SPI_PROTOCOL,
++      MSP_SLAVE_SPI_PROTOCOL,
++      MSP_INVALID_PROTOCOL
++};
++
++/*** Sample Frequencies ***/
++/* These are no longer required, frequencies in Hz can be used directly */
++enum {
++      MSP_SAMPLE_FREQ_NOT_SUPPORTED = -1,
++      MSP_SAMPLE_FREQ_8KHZ = 8000,
++      MSP_SAMPLE_FREQ_12KHZ = 12000,
++      MSP_SAMPLE_FREQ_16KHZ = 16000,
++      MSP_SAMPLE_FREQ_24KHZ = 24000,
++      MSP_SAMPLE_FREQ_32KHZ = 32000,
++      MSP_SAMPLE_FREQ_44KHZ = 44000,
++      MSP_SAMPLE_FREQ_48KHZ = 48000,
++      MSP_SAMPLE_FREQ_64KHZ = 64000,
++      MSP_SAMPLE_FREQ_88KHZ = 88000,
++      MSP_SAMPLE_FREQ_96KHZ = 96000,
++      MSP_SAMPLE_FREQ_22KHZ = 22000,
++      MSP_SAMPLE_FREQ_11KHZ = 11000
++};
++
++/*** Input Frequencies ***/
++/* These are no longer required, frequencies in Hz can be used directly */
++typedef enum {
++
++      MSP_INPUT_FREQ_1MHZ  = 1000,
++      MSP_INPUT_FREQ_2MHZ  = 2000,
++      MSP_INPUT_FREQ_3MHZ  = 3000,
++      MSP_INPUT_FREQ_4MHZ  = 4000,
++      MSP_INPUT_FREQ_5MHZ  = 5000,
++      MSP_INPUT_FREQ_6MHZ  = 6000,
++      MSP_INPUT_FREQ_8MHZ  = 8000,
++      MSP_INPUT_FREQ_11MHZ = 11000,
++      MSP_INPUT_FREQ_12MHZ = 12000,
++      MSP_INPUT_FREQ_16MHZ = 16000,
++      MSP_INPUT_FREQ_22MHZ = 22000,
++      MSP_INPUT_FREQ_24MHZ = 24000,
++      MSP_INPUT_FREQ_48MHZ = 48000
++
++} t_msp_in_clock_freq;
++
++#define MSP_INPUT_FREQ_APB 48000000
++
++/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono),
++ *   32 bits accesses (stereo).
++ ***/
++enum
++{
++      MSP_MONO,
++      MSP_STEREO
++};
++
++/* Direction (Transmit/Receive mode) */
++enum {
++      MSP_TRANSMIT_MODE,
++      MSP_RECEIVE_MODE,
++      MSP_BOTH_T_R_MODE
++};
++
++/* Dma mode should be used for large transfers,
++ * polling mode should be used for transfers of a few bytes
++ */
++enum {
++      MSP_DMA_MODE,
++      MSP_POLLING_MODE,
++      MSP_INTERRUPT_MODE
++};
++
++/* User client for the MSP */
++typedef enum {
++      MSP_NO_USER = 0,
++      MSP_USER_SPI,
++      MSP_USER_ALSA,
++      MSP_USER_SAA,
++}t_msp_user;
++
++/*Flag structure for MSPx*/
++typedef struct {
++      struct semaphore        lock;
++      t_msp_user              user;
++}msp_flag ;
++
++
++/* Transmit and receive configuration register */
++#define MSP_BIG_ENDIAN           0x00000000
++#define MSP_LITTLE_ENDIAN        0x00001000
++#define MSP_UNEXPECTED_FS_ABORT  0x00000000
++#define MSP_UNEXPECTED_FS_IGNORE 0x00008000
++#define MSP_NON_MODE_BIT_MASK    0x00009000
++
++/* Global configuration register
++--------------------------------*/
++#define RX_ENABLE             0x00000001
++#define RX_FIFO_ENABLE        0x00000002
++#define RX_SYNC_SRG           0x00000010
++#define RX_CLK_POL_RISING     0x00000020
++#define RX_CLK_SEL_SRG        0x00000040
++#define TX_ENABLE             0x00000100
++#define TX_FIFO_ENABLE        0x00000200
++#define TX_SYNC_SRG_PROG      0x00001800
++#define TX_CLK_POL_RISING     0x00002000
++#define TX_CLK_SEL_SRG        0x00004000
++#define TX_EXTRA_DELAY_ENABLE 0x00008000
++#define SRG_ENABLE            0x00010000
++#define FRAME_GEN_ENABLE      0x00100000
++#define SRG_CLK_SEL_APB       0x00000000
++#define RX_FIFO_SYNC_HI       0x00000000
++#define TX_FIFO_SYNC_HI       0x00000000
++#define SPI_CLK_MODE_NORMAL   0x00000000
++
++/* SPI Clock Modes enumertion
++ * SPI clock modes of MSP provides compatibility with
++ * the SPI protocol.MSP supports 2 SPI transfer formats.
++ * MSP_ZERO_DELAY_SPI_MODE:MSP transmits data over Tx/Rx
++ * Lines immediately after MSPTCK/MSPRCK rising/falling edge.
++ * MSP_HALF_CYCLE_DELY_SPI_MODE:MSP transmits data  one-half cycle
++ * ahead of the rising/falling edge of the MSPTCK
++ */
++enum {
++      MSP_NON_SPI_PROTOCOL = 0,
++      MSP_ZERO_DELAY_SPI_MODE = 2,
++      MSP_HALF_CYCLE_DELY_SPI_MODE = 3
++};
++
++#define MSP_FRAME_SIZE_AUTO -1
++
++enum msp_data_size{
++      MSP_DATA_SIZE_DEFAULT = -1,
++      MSP_DATA_SIZE_8BIT,
++      MSP_DATA_SIZE_10BIT,
++      MSP_DATA_SIZE_12BIT,
++      MSP_DATA_SIZE_14BIT,
++      MSP_DATA_SIZE_16BIT,
++      MSP_DATA_SIZE_20BIT,
++      MSP_DATA_SIZE_24BIT,
++      MSP_DATA_SIZE_32BIT,
++};
++
++#define MSP_I2S_SIMPLE_CONFIG { \
++      MSP_INPUT_FREQ_APB, \
++      RX_CLK_SEL_SRG, \
++      TX_CLK_SEL_SRG, \
++      SRG_CLK_SEL_APB, \
++      MSP_BIG_ENDIAN, \
++      MSP_BIG_ENDIAN, \
++      RX_FIFO_SYNC_LOW, \
++      TX_FIFO_SYNC_LOW, \
++      RX_SYNC_SRG, \
++      TX_SYNC_SRG_PROG, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      RX_FIFO_ENABLE, \
++      TX_FIFO_ENABLE, \
++      SPI_CLK_MODE_NORMAL, \
++      SPI_BURST_MODE_DISABLE \
++}
++
++#define MSP_PCM_SIMPLE_CONFIG { \
++      MSP_INPUT_FREQ_APB, \
++      RX_CLK_SEL_SRG, \
++      TX_CLK_SEL_SRG, \
++      SRG_CLK_SEL_APB, \
++      MSP_BIG_ENDIAN, \
++      MSP_BIG_ENDIAN, \
++      RX_FIFO_SYNC_HI, \
++      TX_FIFO_SYNC_HI, \
++      RX_SYNC_SRG, \
++      TX_SYNC_SRG_AUTO, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      RX_FIFO_ENABLE, \
++      TX_FIFO_ENABLE, \
++      SPI_CLK_MODE_NORMAL, \
++      SPI_BURST_MODE_DISABLE \
++}
++
++#define MSP_MASTER_SPI_SIMPLE_CONFIG { \
++      MSP_INPUT_FREQ_APB, \
++      RX_CLK_SEL_SRG, \
++      TX_CLK_SEL_SRG, \
++      SRG_CLK_SEL_APB, \
++      MSP_BIG_ENDIAN, \
++      MSP_BIG_ENDIAN, \
++      RX_FIFO_SYNC_LOW, \
++      TX_FIFO_SYNC_LOW, \
++      RX_SYNC_SRG, \
++      TX_SYNC_SRG_AUTO, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      RX_FIFO_ENABLE, \
++      TX_FIFO_ENABLE, \
++      SPI_CLK_MODE_ZERO_DLY, \
++      SPI_BURST_MODE_DISABLE \
++}
++
++#define MSP_SLAVE_SPI_SIMPLE_CONFIG { \
++      MSP_INPUT_FREQ_APB, \
++      RX_CLK_SEL_EXT, \
++      TX_CLK_SEL_EXT, \
++      SRG_CLK_SEL_APB, \
++      MSP_BIG_ENDIAN, \
++      MSP_BIG_ENDIAN, \
++      RX_FIFO_SYNC_LOW, \
++      TX_FIFO_SYNC_LOW, \
++      RX_SYNC_EXT, \
++      TX_SYNC_EXT, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      MSP_UNEXPECTED_FS_IGNORE, \
++      RX_FIFO_ENABLE, \
++      TX_FIFO_ENABLE, \
++      SPI_CLK_MODE_ZERO_DLY, \
++      SPI_BURST_MODE_DISABLE \
++}
++
++#ifdef __KERNEL__
++/* exported functions */
++#include<linux/types.h>
++int nomadik_msp_configure(int msp, struct msp_generic_config *config, t_msp_user user);
++int nomadik_msp_send_data(int msp, void *data, size_t bytes);
++int nomadik_msp_receive_data(int msp, void *data, size_t bytes);
++int nomadik_msp_transceive_data(int msp, void *txdata, size_t txbytes,
++                              void *rxdata, size_t rxbytes);
++int nomadik_msp_enable(int msp, int direction, int work_mode,
++                     int protocol, int frame_freq, int frame_size,
++                     enum msp_data_size data_size, t_msp_user user);
++int nomadik_msp_disable(int msp, int direction, t_msp_user user);
++void nomadik_msp_flush_input(int msp);
++#endif
++
++/***************************************************************************************
++ *
++ * User space interface starts here. This is intended for testing only.
++ *
++ ***************************************************************************************/
++struct msp_user_enable {
++      int direction;
++      int work_mode;
++      int protocol;
++      int frame_freq;
++      int frame_size;
++      enum msp_data_size data_size;
++};
++
++#include <linux/ioctl.h>
++
++#define MSP_IOC_MAGIC 'M'
++#define MSP_CONFIGURE _IOW(MSP_IOC_MAGIC, 0, struct msp_generic_config)
++#define MSP_ENABLE _IOW(MSP_IOC_MAGIC, 1, struct msp_user_enable)
++#define MSP_DISABLE _IOW(MSP_IOC_MAGIC, 2, int)
++
++#endif
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h
 @@ -0,0 +1,90 @@
 +      /* Header file for Multiple Timer Units.
 +       * mtu.h : Defines for registering & using MTU timers */
@@ -233064,9 +234157,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/mtu.h ../new/linux-2.6.20
 +
 +inline unsigned long mtu_intr_reg_readl(unsigned int timer,
 +                                      unsigned long ctrl_register);
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h       2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h
 @@ -0,0 +1,42 @@
 +#ifndef NMDK_NMDK_NAND_H
 +#define NMDK_NMDK_NAND_H
@@ -233110,9 +234202,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nandflash.h ../new/linux-
 +#define DEFAULT_PATT0_VALUE 0x00100A00
 +
 +#endif                                /*  NMDK_NAND_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h
 @@ -0,0 +1,160 @@
 +/*\r
 + *  linux/include/asm-arm/arch-nomadik/ndk10_devices.h\r
@@ -233274,183 +234365,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h ../new/li
 +\r
 +#endif        /*__ASSEMBLY__*/\r
 +#endif        /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/\r
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h        2008-07-04 23:45:26.000000000 +0530
-@@ -0,0 +1,169 @@
-+/*
-+ *  linux/include/asm-arm/arch-nomadik/ndk15c02_devices.h
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __ASM_ARM_ARCH_NDK15C02_DEVICES_H
-+#define __ASM_ARM_ARCH_NDK15C02_DEVICES_H
-+#ifndef __ASSEMBLY__
-+
-+#include <asm/types.h>
-+
-+/*
-+ * Macros board specific
-+ */
-+#define BOARD_IO_DESC         /*nothing to define */
-+
-+/* Ethernet related board specific declaration*************************/
-+#define NOMADIK_ETH0_BASE       0x33000000    /* ETH0 Base */
-+#define SMC91111_IRQ          GPIO_PIN_106
-+
-+/* MMC related board specific declaration*************************/
-+#define MMCDETECT_IRQ         GPIO_PIN_119
-+#define val_volt 7            /*Value to be written at Touareg register */
-+
-+/* Touchpanel related declaration************************************/
-+#define TOUCHP_IRQ            GPIO_PIN_104    /* PENIRQNO: through CPLD_IT */
-+/*#define TOUCHP_CS0          NOT_KNOWN       * Chip select pin0 */
-+/*#define TOUCHP_CS1          NOT_KNOWN       * Chip select pin1 */
-+#define X_DELTA_MAX           2* 10   /*Max ADC read error limit for Sub- */
-+#define Y_DELTA_MAX           2 *16   /*sequent redings */
-+#define       MAX_12BIT       ((1<<12)-1)
-+#define X_CORR(x, y)          (x)
-+#define Y_CORR(x, y)          (MAX_12BIT - y)
-+
-+/* Keypad related declaration************************************/
-+#define KEYPAD_IRQ            GPIO_PIN_113
-+#define MAX_KPROW               8
-+#define MAX_KPCOL               8
-+
-+/* I2c related board specific declaration************************/
-+#define I2C_CLIENT_BUSID13    0
-+#define I2C_TOUAREG_ADAPTER   1
-+#define I2C_TOUREG_CLIENT_BUSID       0
-+#define I2C_CPLD_CLIENT_BUSID 0
-+/* Addresses for clients on this board*/
-+#define I2C_ADDR_MB        0x50       /* Motherboard*/
-+#define I2C_ADDR_UI_DB     0x51       /* UI Daughterboard*/
-+#define I2C_ADDR_IO_DB1    0x52       /* I/O Expansion daughter board 1*/
-+#define I2C_ADDR_IO_DB2    0x53       /* I/O Expansion daughter board 2*/
-+#define I2C_ADDR_CIF_CAM   0x54       /* CCIR-656 ST CIF Camera (Matisse)*/
-+#define I2C_ADDR_PP_CAM    (0x08>>1)  /* pepperpot camera */
-+#define I2C_ADDR_MEM_EXP   0x55       /* CCIR-656 ST CIF Camera (Matisse)*/
-+#define I2C_ADDR_AC        0x1A       /* Audio codec STw5095*/
-+#define I2C_ADDR_FM_TUNER  0x62       /* FM Tuner (TDA 7701-Brite)*/
-+#define I2C_ADDR_GAS_GAUGE 0x22       /* Gas Gauge (PB700)*/
-+#define I2C_ADDR_CAM_MOD   0x45       /* LITEA Camera Module ?*/
-+#define I2C0_LP_OWNADDR    0x50
-+#define I2C1_LP_OWNADDR    0x60
-+#define I2C_ADDR_TOUAREG   0x2D
-+#define I2C_ADDR_CPLD      0x1C       /* actual 0x38 and 0x39, considered only 7 msbs */
-+#define I2C_ADDR_DENC      0x20
-+
-+/* MSP related board specific declaration************************/
-+#define MSP_DATA_DELAY                 MSP_DELAY_0
-+#define MSP_TX_CLOCK_EDGE      MSP_FALLING_EDGE
-+#define MSP_RX_CLOCK_EDGE      MSP_FALLING_EDGE
-+
-+/*NORflash related board specific declaration*******************/ 
-+#define NMDK_FLASH_BASE       0x30000000
-+#define NMDK_FLASH_WINDOW_SIZE        32 * 1024 * 1024
-+#define NMDK_FLASH_BUSWIDTH   2
-+    
-+#define GET_BANK_WIDTH(val,phys)        \
-+    switch (phys) { \
-+      case NMDK_FLASH_BASE: \
-+              val = NMDK_FLASH_BUSWIDTH;\
-+              break;\
-+      default:\
-+              break;\
-+      }
-+
-+/*NANDflash related board specific declaration*******************/ 
-+#define BOARD_SET_NAND_DATA           \
-+      nand_oob->eccbytes = 12;        \
-+      nand_oob->eccpos[0] = 2;        \
-+      nand_oob->eccpos[1] = 3;        \
-+      nand_oob->eccpos[2] = 4;        \
-+      nand_oob->eccpos[3] = 18;       \
-+      nand_oob->eccpos[4] = 19;       \
-+      nand_oob->eccpos[5] = 20;       \
-+      nand_oob->eccpos[6] = 34;       \
-+      nand_oob->eccpos[7] = 35;       \
-+      nand_oob->eccpos[8] = 36;       \
-+      nand_oob->eccpos[9] = 50;       \
-+      nand_oob->eccpos[10] = 51;      \
-+      nand_oob->eccpos[11] = 52;      \
-+      this->badblockpos = 5;
-+
-+#define       BOARD_SET_NAND_BADBLOCK         \
-+      this->eccsteps = 4;             \
-+      this->badblockpos = 5;
-+
-+/*SVA related board specific declaration*******************/ 
-+#define SVA_HCL_INIT_MEM_SIZE SZ_4M
-+
-+/* CPLD/EPIO related declaration************************************/
-+/* the below defination is w.r.to CPLD version 3.0.1.2 */
-+#define NOMADIK_CPLD_BASE     0x36000000      /* CPLD base */
-+
-+#define COB15_ID      0x00    /* offsets for cpld board registers */
-+#define COB15_CTRL    0x02
-+#define KEYPAD_DATA   0x04
-+#define MSP_CONF      0x06
-+#define UART_CONF     0x08
-+#define SSP_CONF      0x0A
-+#define AUX_GPO1      0x20
-+#define AUX_GPO2      0x22
-+
-+extern u16 nomadik_epio_read_i2c(int reg);
-+extern int nomadik_epio_write_i2c(u16 data, int reg);
-+#define nomadik_epio_read_cob_id()    nomadik_epio_read_i2c(COB15_ID)
-+#define nomadik_epio_read_cob_ctl()   nomadik_epio_read_i2c(COB15_CTRL)
-+#define nomadik_epio_read_keypad()    nomadik_epio_read_i2c(KEYPAD_DATA)
-+#define nomadik_epio_read_msp_conf()  nomadik_epio_read_i2c(MSP_CONF)
-+#define nomadik_epio_read_uart_conf() nomadik_epio_read_i2c(UART_CONF)
-+#define nomadik_epio_read_ssp_conf()  nomadik_epio_read_i2c(SSP_CONF)
-+#define nomadik_epio_read_aux_gpo1()  nomadik_epio_read_i2c(AUX_GPO1)
-+#define nomadik_epio_read_aux_gpo2()  nomadik_epio_read_i2c(AUX_GPO2)
-+#define nomadik_epio_write_cob_ctl(x) nomadik_epio_write_i2c((uint16)x,COB15_CTRL)
-+#define nomadik_epio_write_keypad(x)  nomadik_epio_write_i2c((uint16)x,KEYPAD_DATA)
-+#define nomadik_epio_write_msp_conf(x)        nomadik_epio_write_i2c((uint16)x,MSP_CONF)
-+#define nomadik_epio_write_uart_conf(x)       nomadik_epio_write_i2c((uint16)x,UART_CONF)
-+#define nomadik_epio_write_ssp_conf(x)        nomadik_epio_write_i2c((uint16)x,SSP_CONF)
-+#define nomadik_epio_write_aux_gpo1(x)        nomadik_epio_write_i2c((uint16)x,AUX_GPO1)
-+#define nomadik_epio_write_aux_gpo2(x)        nomadik_epio_write_i2c((uint16)x,AUX_GPO2)
-+
-+/*CPLD Version abstraction constants */
-+#define COB_REV_BITS          0x7000  /*numeric field */
-+#define COB_REV_BITS_POS      12      /*need to roate this much times */
-+#define COB_REV_SUBBITS               0x0000  /*decimal field */
-+#define COB_REV_SUBBITS_POS   0       /*need to roate this much times */
-+#define CPLD_REV_BITS         0x0FF0  /*numeric field */
-+#define CPLD_REV_BITS_POS     4       /*need to roate this much times */
-+#define CPLD_REV_SUBBITS      0x000F  /*decimal field */
-+
-+/* Bits defination for NDK15_CTRL (COB_CTRL) register */
-+#define CPLD_GPIO34           0x0200  /*(1)CPLD sent CC_PWRDETECTn */
-+#define BT_WAKEUP_GPO1                0x0100  /*(1)from AUX_GPO1 CPLD register, bit (0)*/
-+#define DEEPSLEEP_CLK_GPIO106 0x00c0  /*(00)from Nomadik GPIO106 */
-+#define DEEPSLEEP_CLK_GPIO49  0x0040  /*(01)from Nomadik GPIO49 */
-+#define DEEPSLEEP_CLK_GPO1    0x00c0  /*(11)from AUX_GPO1 CPLD register, bit (14)*/
-+#define GPIO106_LAN_IT                0x0030  /*(00) fron ethernet controller*/
-+#define GPIO106_PWRDET                0x0010  /*(01) fron CC_PWRDETECTn(Charge controller)*/
-+#define GPIO106_PM_ITWK               0x0020  /*(10) fron PM_IT_WKUP(Touareg USB insertion)*/
-+#define GPIO106_DIS           0x0030  /*(11) High Z*/
-+#define HPI_GPIO_DIS          0x000c  /*(11) selection for HPI_GPIO disabled*/ 
-+#define BIOS_TCHSCR           0x0002
-+#define USER_LED0             0x0001  /*(1)user led0 on */
-+
-+/* Bits defination for UART_CONF register */
-+#define DBG_UART4W            0x0200  /*(1) select 4 number of wires on the UART interface*/
-+#define DBG_UART0             0x0400  /*(1X00) Enable the UART0 link for the debug RS232 connector */
-+#define DBG_UART1             0x0480  /*(1X01) Enable the UART1 link for the debug RS232 connector */
-+#define DBG_UART2             0x0580  /*(1X11) Enable the UART2 link for the debug RS232 connector */
-+#define MD_UART0              0x0040  /*(1X00) Enable the UART0 link for peripheral in expansion connector (Modem
-\ No newline at end of file
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h
 @@ -0,0 +1,248 @@
 +/*\r
 + *  linux/include/asm-arm/arch-nomadik/ndk15_devices.h\r
@@ -233700,9 +234616,181 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h ../new/li
 +\r
 +#endif        /*__ASSEMBLY__*/\r
 +#endif        /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/\r
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h   2008-11-24 14:06:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ndk15c02_devices.h
+@@ -0,0 +1,169 @@
++/*
++ *  linux/include/asm-arm/arch-nomadik/ndk15c02_devices.h
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#ifndef __ASM_ARM_ARCH_NDK15C02_DEVICES_H
++#define __ASM_ARM_ARCH_NDK15C02_DEVICES_H
++#ifndef __ASSEMBLY__
++
++#include <asm/types.h>
++
++/*
++ * Macros board specific
++ */
++#define BOARD_IO_DESC         /*nothing to define */
++
++/* Ethernet related board specific declaration*************************/
++#define NOMADIK_ETH0_BASE       0x33000000    /* ETH0 Base */
++#define SMC91111_IRQ          GPIO_PIN_106
++
++/* MMC related board specific declaration*************************/
++#define MMCDETECT_IRQ         GPIO_PIN_119
++#define val_volt 7            /*Value to be written at Touareg register */
++
++/* Touchpanel related declaration************************************/
++#define TOUCHP_IRQ            GPIO_PIN_104    /* PENIRQNO: through CPLD_IT */
++/*#define TOUCHP_CS0          NOT_KNOWN       * Chip select pin0 */
++/*#define TOUCHP_CS1          NOT_KNOWN       * Chip select pin1 */
++#define X_DELTA_MAX           2* 10   /*Max ADC read error limit for Sub- */
++#define Y_DELTA_MAX           2 *16   /*sequent redings */
++#define       MAX_12BIT       ((1<<12)-1)
++#define X_CORR(x, y)          (x)
++#define Y_CORR(x, y)          (MAX_12BIT - y)
++
++/* Keypad related declaration************************************/
++#define KEYPAD_IRQ            GPIO_PIN_113
++#define MAX_KPROW               8
++#define MAX_KPCOL               8
++
++/* I2c related board specific declaration************************/
++#define I2C_CLIENT_BUSID13    0
++#define I2C_TOUAREG_ADAPTER   1
++#define I2C_TOUREG_CLIENT_BUSID       0
++#define I2C_CPLD_CLIENT_BUSID 0
++/* Addresses for clients on this board*/
++#define I2C_ADDR_MB        0x50       /* Motherboard*/
++#define I2C_ADDR_UI_DB     0x51       /* UI Daughterboard*/
++#define I2C_ADDR_IO_DB1    0x52       /* I/O Expansion daughter board 1*/
++#define I2C_ADDR_IO_DB2    0x53       /* I/O Expansion daughter board 2*/
++#define I2C_ADDR_CIF_CAM   0x54       /* CCIR-656 ST CIF Camera (Matisse)*/
++#define I2C_ADDR_PP_CAM    (0x08>>1)  /* pepperpot camera */
++#define I2C_ADDR_MEM_EXP   0x55       /* CCIR-656 ST CIF Camera (Matisse)*/
++#define I2C_ADDR_AC        0x1A       /* Audio codec STw5095*/
++#define I2C_ADDR_FM_TUNER  0x62       /* FM Tuner (TDA 7701-Brite)*/
++#define I2C_ADDR_GAS_GAUGE 0x22       /* Gas Gauge (PB700)*/
++#define I2C_ADDR_CAM_MOD   0x45       /* LITEA Camera Module ?*/
++#define I2C0_LP_OWNADDR    0x50
++#define I2C1_LP_OWNADDR    0x60
++#define I2C_ADDR_TOUAREG   0x2D
++#define I2C_ADDR_CPLD      0x1C       /* actual 0x38 and 0x39, considered only 7 msbs */
++#define I2C_ADDR_DENC      0x20
++
++/* MSP related board specific declaration************************/
++#define MSP_DATA_DELAY                 MSP_DELAY_0
++#define MSP_TX_CLOCK_EDGE      MSP_FALLING_EDGE
++#define MSP_RX_CLOCK_EDGE      MSP_FALLING_EDGE
++
++/*NORflash related board specific declaration*******************/
++#define NMDK_FLASH_BASE       0x30000000
++#define NMDK_FLASH_WINDOW_SIZE        32 * 1024 * 1024
++#define NMDK_FLASH_BUSWIDTH   2
++
++#define GET_BANK_WIDTH(val,phys)        \
++    switch (phys) { \
++      case NMDK_FLASH_BASE: \
++              val = NMDK_FLASH_BUSWIDTH;\
++              break;\
++      default:\
++              break;\
++      }
++
++/*NANDflash related board specific declaration*******************/
++#define BOARD_SET_NAND_DATA           \
++      nand_oob->eccbytes = 12;        \
++      nand_oob->eccpos[0] = 2;        \
++      nand_oob->eccpos[1] = 3;        \
++      nand_oob->eccpos[2] = 4;        \
++      nand_oob->eccpos[3] = 18;       \
++      nand_oob->eccpos[4] = 19;       \
++      nand_oob->eccpos[5] = 20;       \
++      nand_oob->eccpos[6] = 34;       \
++      nand_oob->eccpos[7] = 35;       \
++      nand_oob->eccpos[8] = 36;       \
++      nand_oob->eccpos[9] = 50;       \
++      nand_oob->eccpos[10] = 51;      \
++      nand_oob->eccpos[11] = 52;      \
++      this->badblockpos = 5;
++
++#define       BOARD_SET_NAND_BADBLOCK         \
++      this->eccsteps = 4;             \
++      this->badblockpos = 5;
++
++/*SVA related board specific declaration*******************/
++#define SVA_HCL_INIT_MEM_SIZE SZ_4M
++
++/* CPLD/EPIO related declaration************************************/
++/* the below defination is w.r.to CPLD version 3.0.1.2 */
++#define NOMADIK_CPLD_BASE     0x36000000      /* CPLD base */
++
++#define COB15_ID      0x00    /* offsets for cpld board registers */
++#define COB15_CTRL    0x02
++#define KEYPAD_DATA   0x04
++#define MSP_CONF      0x06
++#define UART_CONF     0x08
++#define SSP_CONF      0x0A
++#define AUX_GPO1      0x20
++#define AUX_GPO2      0x22
++
++extern u16 nomadik_epio_read_i2c(int reg);
++extern int nomadik_epio_write_i2c(u16 data, int reg);
++#define nomadik_epio_read_cob_id()    nomadik_epio_read_i2c(COB15_ID)
++#define nomadik_epio_read_cob_ctl()   nomadik_epio_read_i2c(COB15_CTRL)
++#define nomadik_epio_read_keypad()    nomadik_epio_read_i2c(KEYPAD_DATA)
++#define nomadik_epio_read_msp_conf()  nomadik_epio_read_i2c(MSP_CONF)
++#define nomadik_epio_read_uart_conf() nomadik_epio_read_i2c(UART_CONF)
++#define nomadik_epio_read_ssp_conf()  nomadik_epio_read_i2c(SSP_CONF)
++#define nomadik_epio_read_aux_gpo1()  nomadik_epio_read_i2c(AUX_GPO1)
++#define nomadik_epio_read_aux_gpo2()  nomadik_epio_read_i2c(AUX_GPO2)
++#define nomadik_epio_write_cob_ctl(x) nomadik_epio_write_i2c((uint16)x,COB15_CTRL)
++#define nomadik_epio_write_keypad(x)  nomadik_epio_write_i2c((uint16)x,KEYPAD_DATA)
++#define nomadik_epio_write_msp_conf(x)        nomadik_epio_write_i2c((uint16)x,MSP_CONF)
++#define nomadik_epio_write_uart_conf(x)       nomadik_epio_write_i2c((uint16)x,UART_CONF)
++#define nomadik_epio_write_ssp_conf(x)        nomadik_epio_write_i2c((uint16)x,SSP_CONF)
++#define nomadik_epio_write_aux_gpo1(x)        nomadik_epio_write_i2c((uint16)x,AUX_GPO1)
++#define nomadik_epio_write_aux_gpo2(x)        nomadik_epio_write_i2c((uint16)x,AUX_GPO2)
++
++/*CPLD Version abstraction constants */
++#define COB_REV_BITS          0x7000  /*numeric field */
++#define COB_REV_BITS_POS      12      /*need to roate this much times */
++#define COB_REV_SUBBITS               0x0000  /*decimal field */
++#define COB_REV_SUBBITS_POS   0       /*need to roate this much times */
++#define CPLD_REV_BITS         0x0FF0  /*numeric field */
++#define CPLD_REV_BITS_POS     4       /*need to roate this much times */
++#define CPLD_REV_SUBBITS      0x000F  /*decimal field */
++
++/* Bits defination for NDK15_CTRL (COB_CTRL) register */
++#define CPLD_GPIO34           0x0200  /*(1)CPLD sent CC_PWRDETECTn */
++#define BT_WAKEUP_GPO1                0x0100  /*(1)from AUX_GPO1 CPLD register, bit (0)*/
++#define DEEPSLEEP_CLK_GPIO106 0x00c0  /*(00)from Nomadik GPIO106 */
++#define DEEPSLEEP_CLK_GPIO49  0x0040  /*(01)from Nomadik GPIO49 */
++#define DEEPSLEEP_CLK_GPO1    0x00c0  /*(11)from AUX_GPO1 CPLD register, bit (14)*/
++#define GPIO106_LAN_IT                0x0030  /*(00) fron ethernet controller*/
++#define GPIO106_PWRDET                0x0010  /*(01) fron CC_PWRDETECTn(Charge controller)*/
++#define GPIO106_PM_ITWK               0x0020  /*(10) fron PM_IT_WKUP(Touareg USB insertion)*/
++#define GPIO106_DIS           0x0030  /*(11) High Z*/
++#define HPI_GPIO_DIS          0x000c  /*(11) selection for HPI_GPIO disabled*/
++#define BIOS_TCHSCR           0x0002
++#define USER_LED0             0x0001  /*(1)user led0 on */
++
++/* Bits defination for UART_CONF register */
++#define DBG_UART4W            0x0200  /*(1) select 4 number of wires on the UART interface*/
++#define DBG_UART0             0x0400  /*(1X00) Enable the UART0 link for the debug RS232 connector */
++#define DBG_UART1             0x0480  /*(1X01) Enable the UART1 link for the debug RS232 connector */
++#define DBG_UART2             0x0580  /*(1X11) Enable the UART2 link for the debug RS232 connector */
++#define MD_UART0              0x0040  /*(1X00) Enable the UART0 link for peripheral in expansion connector (Modem
+\ No newline at end of file
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h
 @@ -0,0 +1,131 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/nhk15_devices.h
@@ -233835,9 +234923,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/nhk15_devices.h ../new/li
 +
 +#endif        /*__ASSEMBLY__*/
 +#endif        /*__ASM_ARM_ARCH_NHK15_DEVICES_H*/
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/param.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/param.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/param.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/param.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/param.h
 @@ -0,0 +1,19 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/param.h
@@ -233858,9 +234945,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/param.h ../new/linux-2.6.
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h    2008-07-04 23:45:27.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h
 @@ -0,0 +1,355 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/pexp.h
@@ -233921,10 +235007,10 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h ../new/linux-2.6.2
 +#define STMPE2401_WAKEUP_IRQ                  24      /*ISR bit 0*/
 +#define STMPE2401_KEYPAD_IRQ                  25      /*ISR bit 1*/
 +#define STMPE2401_KEYPAD_OVERFLOW_IRQ         26      /*ISR bit 2,lowest priority*/
-+#define STMPE2401_ROTATOR_IRQ                 27      /*NOT_SUPPORTED in this version*/ 
-+#define STMPE2401_ROTATOR_OVERFLOW_IRQ                28      /*NOT_SUPPORTED in this version*/ 
-+#define STMPE2401_PWM0_IRQ                    29      /*NOT_SUPPORTED in this version*/ 
-+#define STMPE2401_PWM1_IRQ                    30      /*NOT_SUPPORTED in this version*/ 
++#define STMPE2401_ROTATOR_IRQ                 27      /*NOT_SUPPORTED in this version*/
++#define STMPE2401_ROTATOR_OVERFLOW_IRQ                28      /*NOT_SUPPORTED in this version*/
++#define STMPE2401_PWM0_IRQ                    29      /*NOT_SUPPORTED in this version*/
++#define STMPE2401_PWM1_IRQ                    30      /*NOT_SUPPORTED in this version*/
 +#define STMPE2401_PWM2_IRQ                    31      /*NOT_SUPPORTED in this version*/
 +
 +#define STMPE2401_ENABLE_INTERRUPT            1
@@ -234003,11 +235089,11 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h ../new/linux-2.6.2
 +/*interrupt settings*/
 +typedef struct
 +{
-+      gpio_pin        NdkPin;         
-+      gpio_config NdkPinConfig;       
++      gpio_pin        NdkPin;
++      gpio_config NdkPinConfig;
 +
 +      void (*Callback[MAX_STMPE2401_CALLBACK])(void *parameter);
-+      void *CallbackParam[MAX_STMPE2401_CALLBACK];            
++      void *CallbackParam[MAX_STMPE2401_CALLBACK];
 +
 +      unsigned short ControlReg;
 +      unsigned short EnableReg;
@@ -234181,7 +235267,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h ../new/linux-2.6.2
 +} t_STMPE2401_error;
 +
 +/*Device initialization functions*/
-+PUBLIC t_STMPE2401_error STMPE2401_Init(unsigned char stmpeId); 
++PUBLIC t_STMPE2401_error STMPE2401_Init(unsigned char stmpeId);
 +/*Device info*/
 +PUBLIC t_STMPE2401_error STMPE2401_Info(unsigned char stmpeId, t_STMPE2401_info *info );
 +
@@ -234217,9 +235303,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/pexp.h ../new/linux-2.6.2
 +
 +#endif
 +
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/power.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/power.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/power.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/power.h   2008-07-28 15:20:47.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/power.h
 @@ -0,0 +1,180 @@
 +
 +/* include/asm-arm/arch-nomadik/power.h
@@ -234262,7 +235347,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/power.h ../new/linux-2.6.
 +#include <asm/mach/time.h>
 +#include <asm/arch/debug.h>
 +
-+/* 
++/*
 + * Undefine/UnComment NMDK_RTT_WAKEUP if wakeup from RTC
 + * Undefine/UnComment NMDK_RTC_WAKEUP if wakeup from RTT
 + * wakeup from that device
@@ -234393,7 +235478,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/power.h ../new/linux-2.6.
 +
 +#endif
 +
-+#ifdef CONFIG_NOMADIK_PM 
++#ifdef CONFIG_NOMADIK_PM
 +extern int nomadik_clock_enable(u32 );
 +extern int nomadik_clock_disable(u32 );
 +#else
@@ -234401,9 +235486,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/power.h ../new/linux-2.6.
 +#define nomadik_clock_disable(u32)  do{}while(0)
 +#endif
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/smp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/smp.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/smp.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/smp.h     2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/smp.h
 @@ -0,0 +1,19 @@
 +#ifndef ASMARM_ARCH_SMP_H
 +#define ASMARM_ARCH_SMP_H
@@ -234424,9 +235508,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/smp.h ../new/linux-2.6.20
 +extern void secondary_scan_irqs(void);
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/spi.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/spi.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/spi.h     2008-07-28 15:20:48.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/spi.h
 @@ -0,0 +1,521 @@
 +/*
 + * include/asm-arm/arch-nomadik/spi.h
@@ -234502,7 +235585,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 +typedef struct {
 +      t_msp_clk_src clk_src;
 +      uint16 sckdiv;          /* value from 0 to 1023 */
-+      bool_t sckpol;          /*Used only when MSPSCK clocks the sample rate generator (SCKSEL = 1Xb): 
++      bool_t sckpol;          /*Used only when MSPSCK clocks the sample rate generator (SCKSEL = 1Xb):
 +                                 0b: The rising edge of MSPSCK clocks the sample rate generator
 +                                 1b: The falling edge of MSPSCK clocks the sample rate generator */
 +} t_msp_clock_params;
@@ -234526,7 +235609,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 +/***************************************************************************/
 +
 +/**
-+ * whether SSP is in loopback mode or not 
++ * whether SSP is in loopback mode or not
 + */
 +typedef enum {
 +      LOOPBACK_DISABLED,
@@ -234607,7 +235690,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 +} t_ssp_rx_level_trig;
 +
 +/**
-+ * Transmit FIFO watermark level which triggers (IT Interrupt fires 
++ * Transmit FIFO watermark level which triggers (IT Interrupt fires
 + * when _N_ or more empty locations in TX FIFO)
 + */
 +typedef enum {
@@ -234770,7 +235853,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 + * @hierarchy: sets whether interface is master or slave
 + * @slave_tx_disable: SSPTXD is disconnected (in slave mode only)
 + * @clk_freq: Tune freq parameters of SSP(when in master mode)
-+ * @endian_rx: Endianess of Data in Rx FIFO 
++ * @endian_rx: Endianess of Data in Rx FIFO
 + * @endian_tx: Endianess of Data in Tx FIFO
 + * @data_size: Width of data element(4 to 32 bits)
 + * @com_mode: communication mode: polling, Interrupt or DMA
@@ -234780,7 +235863,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 + * @clk_pol: Motorola SPI interface Clock polarity
 + * @ctrl_len: Microwire interface: Control length
 + * @wait_state: Microwire interface: Wait state
-+ * @duplex: Microwire interface: Full/Half duplex 
++ * @duplex: Microwire interface: Full/Half duplex
 + * @freq: Freq of operation(will be used if clk_freq is not given)
 + * @cs_control: function pointer to board-specific function to assert/deassert I/O port to control HW generation of devices chip-select.
 + * @dma_xfer_type: Type of DMA xfer (Mem-to-periph or Periph-to-Periph)
@@ -234858,7 +235941,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 +      RESTORE_STATE ,
 +      LOAD_DEFAULT_CONFIG ,
 +      CLEAR_ALL_INTERRUPT,
-+} cntlr_commands;     
++} cntlr_commands;
 +
 +/***************************************************************************/
 +#define SPI_REG_WRITE_BITS(reg,val,mask,sb)  ((reg) =   (((reg) & ~(mask)) | (((val)<<(sb)) & (mask))))
@@ -234913,7 +235996,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 + * @cs_control: chip select callback provided by chip
 + * @xfer_type: polling/interrupt/dma
 + *
-+ * Runtime state of the SPI controller, maintained per chip, 
++ * Runtime state of the SPI controller, maintained per chip,
 + * This would be set according to the current message that would be served
 + */
 +struct chip_data {
@@ -234922,7 +236005,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 +              struct msp_regs mspr;
 +      } regs;
 +      u32 chip_id;
-+      u8 n_bytes;     
++      u8 n_bytes;
 +      u8 enable_dma;
 +      struct spi_dma_info * dma_info;
 +      void (*write) (struct driver_data * drv_data);
@@ -234949,9 +236032,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/spi.h ../new/linux-2.6.20
 +extern irqreturn_t spi_dma_callback_handler(int irq, void *param);
 +extern void nomadik_spi_tasklet(unsigned long param);
 +#endif                                /* _SPI_NMDK_H */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h
 @@ -0,0 +1,280 @@
 +/*
 + * arch/arm/mach-nomadik/ssp-spi.h
@@ -235071,7 +236153,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h ../new/linux-2.
 +#define SSP_CPSR_MASK_CPSDVSR         ((uint32)(0xFFUL << 0)) /*(0xFF << 0)*/
 +
 +/*#######################################################################
-+      SSP Interrupt Mask Set/Clear Register  - ssp_imsc 
++      SSP Interrupt Mask Set/Clear Register  - ssp_imsc
 +#########################################################################
 +*/
 +#define SSP_IMSC_MASK_RORIM           ((uint32)(0x1UL << 0))  /* Receive Overrun Interrupt mask */
@@ -235189,7 +236271,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h ../new/linux-2.
 +#define NMDK_SSP_CLOCK_FREQ 48000000
 +
 +/*#######################################################################
-+      SSP Interrupt related Macros 
++      SSP Interrupt related Macros
 +#########################################################################
 + */
 +#define DEFAULT_SSP_REG_IMSC  0x0UL
@@ -235199,7 +236281,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h ../new/linux-2.
 +#define CLEAR_ALL_SSP_INTERRUPTS  0x3
 +
 +/*#######################################################################
-+    Default SSP Register Values       
++    Default SSP Register Values
 +#########################################################################
 + */
 +#define DEFAULT_SSP_REG_CR0   ( \
@@ -235233,9 +236315,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ssp-spi.h ../new/linux-2.
 +              GEN_MASK_BITS(SSP_DMA_DISABLED, SSP_DMACR_MASK_TXDMAE, 1) \
 +      )
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h
 @@ -0,0 +1,120 @@
 +/*
 + * include/asm-arm/arch-nomadik/stn8810_devices.h
@@ -235260,7 +236341,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h ../new/
 +#define NOMADIK_TDES_BASE       0x10180000    /* TDES Processor */
 +#define NOMADIK_USB_BASE      0x10300000      /* USB-OTG conf reg base */
 +
-+/* 
++/*
 + *  Chip specific Interrupt numbers
 + */
 +#define IRQ_MSP1                      30
@@ -235332,11 +236413,11 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h ../new/
 +#define FWM_ESRAM_BANK3_BASE          (FWM_ESRAM_BANK2_BASE + FWM_ESRAM_BANK_SIZE)
 +
 +/*
-+ * Macros 
++ * Macros
 + */
 +#define SOC_IO_DESC           /*nothing to define */
 +
-+/* 
++/*
 + Backup RAM size not mentioned for this soc chip (TBC!!)
 + */
 +
@@ -235357,9 +236438,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8810_devices.h ../new/
 +#define FIRDA_RX_REG_OFFSET   (0x20)
 +
 +#endif                                /* __stn8810_devices_h */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h 2008-07-04 23:45:28.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h
 @@ -0,0 +1,165 @@
 +/*
 + * include/asm-arm/arch-nomadik/stn8815_devices.h
@@ -235384,12 +236464,12 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h ../new/
 +#define NOMADIK_USB_BASE           0x10170000 /* USB-OTG conf reg base */
 +#define NOMADIK_CRYP_BASE            0x10180000       /* Cryptographic processor
 +                                                 configuration/data registers */
-+#define NOMADIK_MSHC_BASE            0x101F5000       /* Memory Stick(Pro) Host 
++#define NOMADIK_MSHC_BASE            0x101F5000       /* Memory Stick(Pro) Host
 +                                                 Controller Registers */
 +
-+#define NOMADIK_L2CC_BASE            0x10210000       /* L2 Cache controller */ 
++#define NOMADIK_L2CC_BASE            0x10210000       /* L2 Cache controller */
 +
-+/* 
++/*
 + *  Chip specific Interrupt numbers
 + */
 +#define IRQ_MSP1              62
@@ -235491,14 +236571,14 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h ../new/
 +
 +
 +/*
-+ * Macros 
++ * Macros
 + */
 +#define SOC_IO_DESC                   \
 +      {IO_ADDRESS(NOMADIK_GPIO3_BASE), __phys_to_pfn(NOMADIK_GPIO3_BASE),\
 +       SZ_4K, MT_DEVICE},
 +
-+/* 
-+ Backup RAM size 
++/*
++ Backup RAM size
 + */
 +#define BACKUP_RAM_SIZE (1024)
 +/*
@@ -235526,13 +236606,12 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stn8815_devices.h ../new/
 +
 +
 +#endif                                /* __stn8815_devices_h  */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stw5094ap.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stw5094ap.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/stw5094ap.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stw5094ap.h       2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/stw5094ap.h
 @@ -0,0 +1,176 @@
 +/* include/asm-arm/arch-nomadik/stw5094ap.h
 + *
-+ * Header file for audiocodec STW5094 specific data structures, enums 
++ * Header file for audiocodec STW5094 specific data structures, enums
 + * and private & public functions.
 + *
 + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
@@ -235706,13 +236785,12 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stw5094ap.h ../new/linux-
 +#define MASTERCLK_MCLK          0x10  /* The Master Clock Input for Tone and FM mode only is MCLK */
 +
 +#endif                                /* _STW5094AP_H_ */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h
 @@ -0,0 +1,1387 @@
 +/* include/asm-arm/arch-nomadik/nomadik_stw5095.h
 + *
-+ * Header file for audiocodec STW5095 specific data structures, enums 
++ * Header file for audiocodec STW5095 specific data structures, enums
 + * and private & public functions.
 + *
 + * Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
@@ -235738,12 +236816,12 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h ../new/linux-2.
 +#define _NOMADIK_ACODEC_STW5095_H_
 +
 +/*---------------------------------------------------------------------
-+ * Includes                                                                                      
++ * Includes
 + *--------------------------------------------------------------------*/
 +#include <asm/types.h>
 +
 +/*---------------------------------------------------------------------
-+ * Define                                                            
++ * Define
 + *--------------------------------------------------------------------*/
 +
 +typedef enum {
@@ -235915,9 +236993,9 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h ../new/linux-2.
 +t_codec_error CODEC_I2CWrite(__u16 add_of_codec_on_i2c, __u8 location,
 +                           __u8 * p_data, __u32 count);
 +
-+/*--------------------------------------------------------------------------------------------- 
++/*---------------------------------------------------------------------------------------------
 +* Private Header file for AUDIOCODEC stw5095
-+*--------------------------------------------------------------------------------------------- 
++*---------------------------------------------------------------------------------------------
 +*/
 +
 +#define CODEC_MASK_ONE_BIT                      0x1UL
@@ -237097,9 +238175,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/stw5095.h ../new/linux-2.
 +} t_codec_system_context;
 +
 +#endif                                /* _NOMADIK_ACODEC_STW5095_H_ */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/sva.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/sva.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/sva.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/sva.h     2008-07-17 16:42:46.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/sva.h
 @@ -0,0 +1,43 @@
 +/*--------------------------------------------------------------------------------------------------*/
 +/*© copyright STMicroelectronics, 2007.                                                           */
@@ -237144,9 +238221,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/sva.h ../new/linux-2.6.20
 +};
 +
 +
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/system.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/system.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/system.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/system.h  2008-07-04 23:45:29.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/system.h
 @@ -0,0 +1,62 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/system.h
@@ -237202,17 +238278,16 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/system.h ../new/linux-2.6
 +
 +      src_rstsr = psrc_cr + 6;
 +
-+      /* 
-+       * Writing anything in Reset status register will do the soft reset 
++      /*
++       * Writing anything in Reset status register will do the soft reset
 +       */
 +
 +      *(src_rstsr) = 1;
 +}
 +
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/timex.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/timex.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/timex.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/timex.h   2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/timex.h
 @@ -0,0 +1,71 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/timex.h
@@ -237285,55 +238360,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/timex.h ../new/linux-2.6.
 +}
 +mtu_struct_t;
 +#endif
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h      2007-11-21 11:51:42.000000000 +0530
-@@ -0,0 +1,42 @@
-+/*
-+ * linux/include/asm-arm/arch-nomadik/touchp2003.h
-+ *
-+ * Copyright (C) STMicroelectronics
-+ *
-+ * 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
-+ */
-+
-+/******************************************************************************
-+ *             C STMicroelectronics
-+ *-----------------------------------------------------------------------------
-+ *
-+ * Purpose           : Basic definitions for Nomadik Touchpanel Driver
-+ *
-+ *****************************************************************************/
-+
-+#ifndef _TOUCHP_NOMADIK_TSC2003_H
-+#define _TOUCHP_NOMADIK_TSC2003_H
-+
-+
-+struct touchp_tsc2003_device{
-+      int             (*irq_init)(void (*callback)(void* parameter), void * p);
-+      int             (*irq_exit)(void);
-+      int             (*pirq_en) (void);
-+      int             (*pirq_dis)(void);
-+      int             (*pirq_ack)(void);
-+      int             (*pirq_read_val)(unsigned char  * value);
-+};
-+
-+#endif                                /* _NOMADIK_TP_h */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h  2008-07-04 23:45:30.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h
 @@ -0,0 +1,145 @@
 +/*
 + * linux/include/asm-arm/arch-nomadik/touchp.h
@@ -237480,9 +238508,53 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/touchp.h ../new/linux-2.6
 +extern void nomadik_tp_spi_cs_enable(void);
 +
 +#endif                                /* _NOMADIK_TP_h */
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/udc.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/udc.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/udc.h     2008-07-04 23:45:53.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/touchp2003.h
+@@ -0,0 +1,42 @@
++/*
++ * linux/include/asm-arm/arch-nomadik/touchp2003.h
++ *
++ * Copyright (C) STMicroelectronics
++ *
++ * 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
++ */
++
++/******************************************************************************
++ *             C STMicroelectronics
++ *-----------------------------------------------------------------------------
++ *
++ * Purpose           : Basic definitions for Nomadik Touchpanel Driver
++ *
++ *****************************************************************************/
++
++#ifndef _TOUCHP_NOMADIK_TSC2003_H
++#define _TOUCHP_NOMADIK_TSC2003_H
++
++
++struct touchp_tsc2003_device{
++      int             (*irq_init)(void (*callback)(void* parameter), void * p);
++      int             (*irq_exit)(void);
++      int             (*pirq_en) (void);
++      int             (*pirq_dis)(void);
++      int             (*pirq_ack)(void);
++      int             (*pirq_read_val)(unsigned char  * value);
++};
++
++#endif                                /* _NOMADIK_TP_h */
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/udc.h
 @@ -0,0 +1,490 @@
 +//#define DEBUG_LEVEL 1
 +#undef DEBUG_LEVEL
@@ -237493,13 +238565,13 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +              printk(KERN_ERR "%s:%s: " format "\n" , __FILE__,  __FUNCTION__ , ## arg); \
 +      }while(0)
 +#else
-+      #define DBG(level, format, arg...)  do { } while(0) 
++      #define DBG(level, format, arg...)  do { } while(0)
 +#endif
 +
 +
 +#define ERR(format, arg...) \
 +printk(KERN_ERR "%s:%s: " format "\n" , __FILE__,  __FUNCTION__ , ## arg)
-+    
++
 +#define WARN(format, arg...) \
 +    printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__,  __FUNCTION__ , ## arg)
 +
@@ -237534,7 +238606,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +
 +
 +/*
-+ *     MUSBMHDRC Register map 
++ *     MUSBMHDRC Register map
 + */
 +
 +/* Common USB registers */
@@ -237544,11 +238616,11 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +
 +#define MUSB_O_HDRC_INTRTX    0x02    /* 16-bit */
 +#define MUSB_O_HDRC_INTRRX       0x04
-+#define MUSB_O_HDRC_INTRTXE      0x06  
-+#define MUSB_O_HDRC_INTRRXE      0x08  
++#define MUSB_O_HDRC_INTRTXE      0x06
++#define MUSB_O_HDRC_INTRRXE      0x08
 +#define MUSB_O_HDRC_INTRUSB      0x0A   /* 8 bit */
 +#define MUSB_O_HDRC_INTRUSBE     0x0B   /* 8 bit */
-+#define MUSB_O_HDRC_FRAME        0x0C  
++#define MUSB_O_HDRC_FRAME        0x0C
 +#define MUSB_O_HDRC_INDEX        0x0E   /* 8 bit */
 +#define MUSB_O_HDRC_TESTMODE     0x0F   /* 8 bit */
 +
@@ -237603,7 +238675,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +
 +/* POWER */
 +
-+#define MUSB_M_POWER_ISOUPDATE   0x80 
++#define MUSB_M_POWER_ISOUPDATE   0x80
 +#define       MUSB_M_POWER_SOFTCONN    0x40
 +#define       MUSB_M_POWER_HSENAB     0x20
 +#define       MUSB_M_POWER_HSMODE     0x10
@@ -237617,7 +238689,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +#define MUSB_M_INTR_RESUME     0x02
 +#define MUSB_M_INTR_RESET      0x04
 +#define MUSB_M_INTR_BABBLE     0x04
-+#define MUSB_M_INTR_SOF        0x08 
++#define MUSB_M_INTR_SOF        0x08
 +#define MUSB_M_INTR_CONNECT    0x10
 +#define MUSB_M_INTR_DISCONNECT 0x20
 +#define MUSB_M_INTR_SESSREQ    0x40
@@ -237625,7 +238697,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +#define MUSB_M_INTR_EP0      0x01  /* FOR EP0 INTERRUPT */
 +
 +/* DEVCTL */
-+#define MUSB_M_DEVCTL_BDEVICE    0x80   
++#define MUSB_M_DEVCTL_BDEVICE    0x80
 +#define MUSB_M_DEVCTL_FSDEV      0x40
 +#define MUSB_M_DEVCTL_LSDEV      0x20
 +#define MUSB_M_DEVCTL_VBUS       0x18
@@ -237840,7 +238912,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +      u8                              ackwait;
 +      u8                              dma_channel;
 +      u8                              is_tx;
-+      u8                              end_number;     
++      u8                              end_number;
 +      u16                             dma_counter;
 +      int                             lch;
 +      struct nomadik_udc                      *udc;
@@ -237854,7 +238926,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +      u8                              end_number;
 +      unsigned                        dma_bytes;
 +      unsigned                        mapped:1;
-+};       
++};
 +
 +
 +#if 0
@@ -237941,14 +239013,14 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +      DBG(4, "WRITE8(%p, %x, %02x)\n", base_ptr, offset, data); \
 +              wmb(); \
 +                  *(volatile uint8_t*)((unsigned long)base_ptr + offset) = data; \
-+      }   
++      }
 +
 +#undef MUSB_WRITE16
 +#define MUSB_WRITE16(base_ptr, offset, data) { \
 +      DBG(4, "WRITE16(%p, %x, %04x)\n", base_ptr, offset, data); \
 +              wmb(); \
 +                  *(volatile uint16_t*)((unsigned long)base_ptr + offset) = data; \
-+      }   
++      }
 +
 +
 +#undef MUSB_WRITE32
@@ -237956,7 +239028,7 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +      DBG(4, "WRITE32(%p, %x, %08x)\n", base_ptr, offset, data); \
 +              wmb(); \
 +                  *(volatile uint32_t*)((unsigned long)base_ptr + offset) = data; \
-+      }   
++      }
 +
 +#define MUSB_SELECTEND(base_ptr, end) \
 +    MUSB_WRITE8(base_ptr, MUSB_O_HDRC_INDEX, end)
@@ -237974,9 +239046,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/udc.h ../new/linux-2.6.20
 +              MUSB_WRITE16(base_ptr, (offset + 0x10), data)
 +
 +
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h      2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h
 @@ -0,0 +1,71 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/uncompress.h
@@ -238049,9 +239120,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/uncompress.h ../new/linux
 + * nothing to do
 + */
 +#define arch_decomp_wdog()
-diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h ../new/linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h
---- linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h
 @@ -0,0 +1,32 @@
 +/*
 + *  linux/include/asm-arm/arch-nomadik/vmalloc.h
@@ -238085,9 +239155,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/vmalloc.h ../new/linux-2.
 +#define VMALLOC_START   (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
 +#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
-diff -Nauprw linux-2.6.20/include/asm-arm/kgdb.h ../new/linux-2.6.20/include/asm-arm/kgdb.h
---- linux-2.6.20/include/asm-arm/kgdb.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/kgdb.h 2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/include/asm-arm/kgdb.h
 @@ -0,0 +1,91 @@
 +/*
 + * include/asm-arm/kgdb.h
@@ -238180,10 +239249,11 @@ diff -Nauprw linux-2.6.20/include/asm-arm/kgdb.h ../new/linux-2.6.20/include/asm
 +#define CFI_END_FRAME(func)   __CFI_END_FRAME(_PC,_SP,func)
 +
 +#endif /* __ASM_KGDB_H__ */
-diff -Nauprw linux-2.6.20/include/asm-arm/system.h ../new/linux-2.6.20/include/asm-arm/system.h
---- linux-2.6.20/include/asm-arm/system.h      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-arm/system.h       2007-11-21 11:51:42.000000000 +0530
-@@ -345,6 +345,47 @@ static inline unsigned long __xchg(unsig
+--- linux-2.6.20.orig/include/asm-arm/system.h
++++ linux-2.6.20/include/asm-arm/system.h
+@@ -343,10 +343,51 @@ static inline unsigned long __xchg(unsig
+ }
  extern void disable_hlt(void);
  extern void enable_hlt(void);
  
@@ -238231,9 +239301,10 @@ diff -Nauprw linux-2.6.20/include/asm-arm/system.h ../new/linux-2.6.20/include/a
  #endif /* __ASSEMBLY__ */
  
  #define arch_align_stack(x) (x)
-diff -Nauprw linux-2.6.20/include/asm-generic/kgdb.h ../new/linux-2.6.20/include/asm-generic/kgdb.h
---- linux-2.6.20/include/asm-generic/kgdb.h    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/asm-generic/kgdb.h     2007-11-21 11:51:42.000000000 +0530
+ #endif /* __KERNEL__ */
+--- /dev/null
++++ linux-2.6.20/include/asm-generic/kgdb.h
 @@ -0,0 +1,34 @@
 +/*
 + * include/asm-generic/kgdb.h
@@ -238269,10 +239340,11 @@ diff -Nauprw linux-2.6.20/include/asm-generic/kgdb.h ../new/linux-2.6.20/include
 +#endif                                /* CONFIG_KGDB */
 +#endif                                /* __ASSEMBLY__ */
 +#endif                                /* __ASM_GENERIC_KGDB_H__ */
-diff -Nauprw linux-2.6.20/include/linux/amba/clcd.h ../new/linux-2.6.20/include/linux/amba/clcd.h
---- linux-2.6.20/include/linux/amba/clcd.h     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/amba/clcd.h      2007-11-21 11:51:42.000000000 +0530
-@@ -53,7 +53,12 @@
+--- linux-2.6.20.orig/include/linux/amba/clcd.h
++++ linux-2.6.20/include/linux/amba/clcd.h
+@@ -51,11 +51,16 @@
+ #define CNTL_LCDBPP1          (0 << 1)
+ #define CNTL_LCDBPP2          (1 << 1)
  #define CNTL_LCDBPP4          (2 << 1)
  #define CNTL_LCDBPP8          (3 << 1)
  #define CNTL_LCDBPP16         (4 << 1)
@@ -238285,7 +239357,11 @@ diff -Nauprw linux-2.6.20/include/linux/amba/clcd.h ../new/linux-2.6.20/include/
  #define CNTL_LCDBPP24         (5 << 1)
  #define CNTL_LCDBW            (1 << 4)
  #define CNTL_LCDTFT           (1 << 5)
-@@ -66,6 +71,13 @@
+ #define CNTL_LCDMONO8         (1 << 6)
+ #define CNTL_LCDDUAL          (1 << 7)
+@@ -64,10 +69,17 @@
+ #define CNTL_BEPO             (1 << 10)
+ #define CNTL_LCDPWR           (1 << 11)
  #define CNTL_LCDVCOMP(x)      ((x) << 12)
  #define CNTL_LDMAFIFOTIME     (1 << 15)
  #define CNTL_WATERMARK                (1 << 16)
@@ -238299,7 +239375,11 @@ diff -Nauprw linux-2.6.20/include/linux/amba/clcd.h ../new/linux-2.6.20/include/
  
  struct clcd_panel {
        struct fb_videomode     mode;
-@@ -218,8 +230,20 @@ static inline void clcdfb_decode(struct 
+       signed short            width;  /* width in mm */
+       signed short            height; /* height in mm */
+@@ -216,12 +228,24 @@ static inline void clcdfb_decode(struct 
+               if ((fb->dev->periphid & 0x000fffff) == 0x00041110)
+                       val |= CNTL_LCDBPP16;
                else if (fb->fb.var.green.length == 5)
                        val |= CNTL_LCDBPP16;
                else
@@ -238311,18 +239391,322 @@ diff -Nauprw linux-2.6.20/include/linux/amba/clcd.h ../new/linux-2.6.20/include/
 +#else
                        val |= CNTL_LCDBPP16_565;
 +#endif
-+              break;
+               break;
 +#ifdef CONFIG_ARCH_NOMADIK
 +      case 24:
 +              val |= CNTL_LCDBPP24PACKED;
-               break;
++              break;
 +#endif
        case 32:
                val |= CNTL_LCDBPP24;
                break;
-diff -Nauprw linux-2.6.20/include/linux/dwarf2.h ../new/linux-2.6.20/include/linux/dwarf2.h
---- linux-2.6.20/include/linux/dwarf2.h        1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/dwarf2.h 2007-11-21 11:51:42.000000000 +0530
+       }
+--- /dev/null
++++ linux-2.6.20/include/linux/dwarf2-lang.h
+@@ -0,0 +1,300 @@
++#ifndef DWARF2_LANG
++#define DWARF2_LANG
++
++/*
++ * This 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 file defines macros that allow generation of DWARF debug records
++ * for asm files.  This file is platform independent.  Register numbers
++ * (which are about the only thing that is platform dependent) are to be
++ * supplied by a platform defined file.
++ */
++/*
++ * We need this to work for both asm and C.  In asm we are using the
++ * old comment trick to concatenate while C uses the new ANSI thing.
++ * Here we have concat macro...  The multi level thing is to allow and
++ * macros used in the names to be resolved prior to the cat (at which
++ * time they are no longer the same string).
++ */
++#define CAT3(a,b,c) _CAT3(a,b,c)
++#define _CAT3(a,b,c) __CAT3(a,b,c)
++#ifndef __STDC__
++#define __CAT3(a,b,c) a/**/b/**/c
++#else
++#define __CAT3(a,b,c) a##b##c
++#endif
++#ifdef __ASSEMBLY__
++#define IFC(a)
++#define IFN_C(a) a
++#define NL ;
++#define QUOTE_THIS(a) a
++#define DWARF_preamble .section .debug_frame,"",%progbits;
++#else
++#define IFC(a) a
++#define IFN_C(a)
++#define NL \n\t
++#define QUOTE_THIS(a) _QUOTE_THIS(a)
++#define _QUOTE_THIS(a) #a
++/* Don't let CPP see the " and , \042=" \054=, */
++#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits
++#endif
++
++#ifdef CONFIG_64BIT
++#define DATA_ALIGN_FACTOR     8
++#define ADDR_LOC              .quad
++#else
++#define DATA_ALIGN_FACTOR     4
++#define ADDR_LOC              .long
++#endif
++
++#include <linux/dwarf2-defs.h>
++/*
++ * This macro starts a debug frame section.  The debug_frame describes
++ * where to find the registers that the enclosing function saved on
++ * entry.
++ *
++ * ORD is use by the label generator and should be the same as what is
++ * passed to CFI_postamble.
++ *
++ * pc,        pc register gdb ordinal.
++ *
++ * code_align this is the factor used to define locations or regions
++ * where the given definitions apply.  If you use labels to define these
++ * this should be 1.
++ *
++ * data_align this is the factor used to define register offsets.  If
++ * you use struct offset, this should be the size of the register in
++ * bytes or the negative of that.  This is how it is used: you will
++ * define a register as the reference register, say the stack pointer,
++ * then you will say where a register is located relative to this
++ * reference registers value, say 40 for register 3 (the gdb register
++ * number).  The <40> will be multiplied by <data_align> to define the
++ * byte offset of the given register (3, in this example).  So if your
++ * <40> is the byte offset and the reference register points at the
++ * begining, you would want 1 for the data_offset.  If <40> was the 40th
++ * 4-byte element in that structure you would want 4.  And if your
++ * reference register points at the end of the structure you would want
++ * a negative data_align value(and you would have to do other math as
++ * well).
++ */
++
++#define CFI_preamble(ORD, pc, code_align, data_align) \
++         DWARF_preamble       NL                              \
++      .align DATA_ALIGN_FACTOR NL                     \
++        .globl CAT3(frame,_,ORD) NL                   \
++CAT3(frame,_,ORD): NL                                 \
++      .long 7f-6f NL                                  \
++6:                                                    \
++      .long   DW_CIE_ID NL                            \
++      .byte   DW_CIE_VERSION NL                       \
++      .byte 0  NL                                     \
++      .uleb128 code_align NL                          \
++      .sleb128 data_align NL                          \
++      .byte pc NL
++
++/*
++ * After the above macro and prior to the CFI_postamble, you need to
++ * define the initial state.  This starts with defining the reference
++ * register and, usually the pc.  Here are some helper macros:
++ */
++
++#define CFA_define_reference(reg, offset)     \
++      .byte DW_CFA_def_cfa NL                 \
++      .uleb128 reg NL                         \
++      .uleb128 (offset) NL
++
++#define CFA_define_offset(reg, offset)                \
++      .byte (DW_CFA_offset + reg) NL          \
++      .uleb128 (offset) NL
++
++#define CFA_restore(reg)                      \
++        .byte (DW_CFA_restore + reg) NL
++
++#define CFI_postamble()                               \
++      .align DATA_ALIGN_FACTOR NL                             \
++7: NL                                         \
++.previous NL
++
++/*
++ * So now your code pushs stuff on the stack, you need a new location
++ * and the rules for what to do.  This starts a running description of
++ * the call frame.  You need to describe what changes with respect to
++ * the call registers as the location of the pc moves through the code.
++ * The following builds an FDE (fram descriptor entry?).  Like the
++ * above, it has a preamble and a postamble.  It also is tied to the CFI
++ * above.
++ * The preamble macro is tied to the CFI thru the first parameter.  The
++ * second is the code start address and then the code end address+1.
++ */
++#define FDE_preamble(ORD, initial_address, end_address)       \
++        DWARF_preamble NL                             \
++      .align DATA_ALIGN_FACTOR NL                                     \
++      .long 9f-8f NL                                  \
++8:                                                    \
++      .long CAT3(frame,_,ORD) NL                      \
++      ADDR_LOC initial_address NL                     \
++      ADDR_LOC (end_address - initial_address) NL
++
++#define FDE_postamble()                               \
++      .align DATA_ALIGN_FACTOR NL                             \
++9:     NL                                     \
++.previous NL
++
++/*
++ * That done, you can now add registers, subtract registers, move the
++ * reference and even change the reference.  You can also define a new
++ * area of code the info applies to.  For discontinuous bits you should
++ * start a new FDE.  You may have as many as you like.
++ */
++
++/*
++ * To advance the stack address by <bytes> (0x3f max)
++ */
++
++#define CFA_advance_loc(bytes)                        \
++      .byte DW_CFA_advance_loc+bytes NL
++
++/*
++ * This one is good for 0xff or 255
++ */
++#define CFA_advance_loc1(bytes)                       \
++      .byte DW_CFA_advance_loc1 NL            \
++        .byte bytes NL
++
++#define CFA_undefine_reg(reg)                 \
++        .byte DW_CFA_undefined NL             \
++      .uleb128 reg NL
++/*
++ * With the above you can define all the register locations.  But
++ * suppose the reference register moves... Takes the new offset NOT an
++ * increment.  This is how esp is tracked if it is not saved.
++ */
++
++#define CFA_define_cfa_offset(offset)         \
++      .byte DW_CFA_def_cfa_offset NL          \
++      .uleb128 (offset) NL
++/*
++ * Or suppose you want to use a different reference register...
++ */
++#define CFA_define_cfa_register(reg)          \
++      .byte DW_CFA_def_cfa_register NL        \
++      .uleb128 reg NL
++
++/*
++ * If you want to mess with the stack pointer, here is the expression.
++ * The stack starts empty.
++ */
++#define CFA_def_cfa_expression                        \
++        .byte DW_CFA_def_cfa_expression       NL      \
++      .uleb128 20f-10f NL                     \
++10:     NL
++/*
++ * This expression is to be used for other regs.  The stack starts with the
++ * stack address.
++ */
++
++#define CFA_expression(reg)                   \
++        .byte DW_CFA_expression        NL             \
++        .uleb128 reg NL                               \
++      .uleb128 20f-10f NL                     \
++10:     NL
++/*
++ * Here we do the expression stuff.  You should code the above followed
++ *  by expression OPs followed by CFA_expression_end.
++ */
++
++
++#define CFA_expression_end                    \
++20:    NL
++
++#define CFA_exp_OP_const4s(a)                 \
++        .byte DW_OP_const4s NL                        \
++        .long a NL
++
++#define  CFA_exp_OP_swap  .byte DW_OP_swap NL
++#define  CFA_exp_OP_dup  .byte DW_OP_dup NL
++#define  CFA_exp_OP_drop  .byte DW_OP_drop NL
++/*
++ * All these work on the top two elements on the stack, replacing them
++ * with the result.  Top comes first where it matters.  True is 1, false 0.
++ */
++#define  CFA_exp_OP_deref .byte DW_OP_deref NL
++#define  CFA_exp_OP_and   .byte DW_OP_and NL
++#define  CFA_exp_OP_div   .byte DW_OP_div NL
++#define  CFA_exp_OP_minus .byte DW_OP_minus NL
++#define  CFA_exp_OP_mod   .byte DW_OP_mod NL
++#define  CFA_exp_OP_neg   .byte DW_OP_neg NL
++#define  CFA_exp_OP_plus  .byte DW_OP_plus NL
++#define  CFA_exp_OP_not   .byte DW_OP_not NL
++#define  CFA_exp_OP_or    .byte DW_OP_or NL
++#define  CFA_exp_OP_xor   .byte DW_OP_xor NL
++#define  CFA_exp_OP_le    .byte DW_OP_le NL
++#define  CFA_exp_OP_ge    .byte DW_OP_ge NL
++#define  CFA_exp_OP_eq    .byte DW_OP_eq NL
++#define  CFA_exp_OP_lt    .byte DW_OP_lt NL
++#define  CFA_exp_OP_gt    .byte DW_OP_gt NL
++#define  CFA_exp_OP_ne    .byte DW_OP_ne NL
++/*
++ * These take a parameter as noted
++ */
++/*
++ * Unconditional skip to loc. loc is a label (loc:)
++ */
++#define CFA_exp_OP_skip(loc)                  \
++         .byte DW_OP_skip  NL                         \
++       .hword  loc-.-2 NL
++/*
++ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
++ */
++#define CFA_exp_OP_bra(loc)                   \
++         .byte DW_OP_bra NL                   \
++       .hword loc-.-2 NL
++
++/*
++ * TOS += no (an unsigned number)
++ */
++#define CFA_exp_OP_plus_uconst(no)            \
++         .byte DW_OP_plus_uconst NL           \
++         .uleb128 no NL
++
++/*
++ * ++TOS = no (a unsigned number)
++ */
++#define CFA_exp_OP_constu(no)                 \
++         .byte DW_OP_constu NL                        \
++       .uleb128 no NL
++/*
++ * ++TOS = no (a signed number)
++ */
++#define CFA_exp_OP_consts(no)                 \
++         .byte DW_OP_consts NL                        \
++       .sleb128 no NL
++/*
++ * ++TOS = no (an unsigned byte)
++ */
++#define CFA_exp_OP_const1u(no)                        \
++         .byte DW_OP_const1u NL                       \
++       .byte no NL
++
++
++/*
++ * ++TOS = no (a address)
++ */
++#define CFA_exp_OP_addr(no)                   \
++         .byte DW_OP_addr NL                  \
++       .long no NL
++
++/*
++ * Push current frames value for "reg" + offset
++ * We take advantage of the opcode assignments to make this a litteral reg
++ * rather than use the DW_OP_bregx opcode.
++ */
++
++#define CFA_exp_OP_breg(reg,offset)           \
++         .byte DW_OP_breg0+reg NL             \
++         .sleb128 offset NL
++#endif
+--- /dev/null
++++ linux-2.6.20/include/linux/dwarf2.h
 @@ -0,0 +1,775 @@
 +/* Declarations and definitions of codes relating to the DWARF2 symbolic
 +   debugging information format.
@@ -239099,314 +240483,11 @@ diff -Nauprw linux-2.6.20/include/linux/dwarf2.h ../new/linux-2.6.20/include/lin
 +#define DW_EH_PE_indirect     0x80
 +
 +#endif /* _ELF_DWARF2_H */
-diff -Nauprw linux-2.6.20/include/linux/dwarf2-lang.h ../new/linux-2.6.20/include/linux/dwarf2-lang.h
---- linux-2.6.20/include/linux/dwarf2-lang.h   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/dwarf2-lang.h    2007-11-21 11:51:42.000000000 +0530
-@@ -0,0 +1,300 @@
-+#ifndef DWARF2_LANG
-+#define DWARF2_LANG
-+
-+/*
-+ * This 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 file defines macros that allow generation of DWARF debug records
-+ * for asm files.  This file is platform independent.  Register numbers
-+ * (which are about the only thing that is platform dependent) are to be
-+ * supplied by a platform defined file.
-+ */
-+/*
-+ * We need this to work for both asm and C.  In asm we are using the
-+ * old comment trick to concatenate while C uses the new ANSI thing.
-+ * Here we have concat macro...  The multi level thing is to allow and
-+ * macros used in the names to be resolved prior to the cat (at which
-+ * time they are no longer the same string).
-+ */
-+#define CAT3(a,b,c) _CAT3(a,b,c)
-+#define _CAT3(a,b,c) __CAT3(a,b,c)
-+#ifndef __STDC__
-+#define __CAT3(a,b,c) a/**/b/**/c
-+#else
-+#define __CAT3(a,b,c) a##b##c
-+#endif
-+#ifdef __ASSEMBLY__
-+#define IFC(a)
-+#define IFN_C(a) a
-+#define NL ;
-+#define QUOTE_THIS(a) a
-+#define DWARF_preamble .section .debug_frame,"",%progbits;
-+#else
-+#define IFC(a) a
-+#define IFN_C(a)
-+#define NL \n\t
-+#define QUOTE_THIS(a) _QUOTE_THIS(a)
-+#define _QUOTE_THIS(a) #a
-+/* Don't let CPP see the " and , \042=" \054=, */
-+#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits
-+#endif
-+
-+#ifdef CONFIG_64BIT
-+#define DATA_ALIGN_FACTOR     8
-+#define ADDR_LOC              .quad
-+#else
-+#define DATA_ALIGN_FACTOR     4
-+#define ADDR_LOC              .long
-+#endif
-+
-+#include <linux/dwarf2-defs.h>
-+/*
-+ * This macro starts a debug frame section.  The debug_frame describes
-+ * where to find the registers that the enclosing function saved on
-+ * entry.
-+ *
-+ * ORD is use by the label generator and should be the same as what is
-+ * passed to CFI_postamble.
-+ *
-+ * pc,        pc register gdb ordinal.
-+ *
-+ * code_align this is the factor used to define locations or regions
-+ * where the given definitions apply.  If you use labels to define these
-+ * this should be 1.
-+ *
-+ * data_align this is the factor used to define register offsets.  If
-+ * you use struct offset, this should be the size of the register in
-+ * bytes or the negative of that.  This is how it is used: you will
-+ * define a register as the reference register, say the stack pointer,
-+ * then you will say where a register is located relative to this
-+ * reference registers value, say 40 for register 3 (the gdb register
-+ * number).  The <40> will be multiplied by <data_align> to define the
-+ * byte offset of the given register (3, in this example).  So if your
-+ * <40> is the byte offset and the reference register points at the
-+ * begining, you would want 1 for the data_offset.  If <40> was the 40th
-+ * 4-byte element in that structure you would want 4.  And if your
-+ * reference register points at the end of the structure you would want
-+ * a negative data_align value(and you would have to do other math as
-+ * well).
-+ */
-+
-+#define CFI_preamble(ORD, pc, code_align, data_align) \
-+         DWARF_preamble       NL                              \
-+      .align DATA_ALIGN_FACTOR NL                     \
-+        .globl CAT3(frame,_,ORD) NL                   \
-+CAT3(frame,_,ORD): NL                                 \
-+      .long 7f-6f NL                                  \
-+6:                                                    \
-+      .long   DW_CIE_ID NL                            \
-+      .byte   DW_CIE_VERSION NL                       \
-+      .byte 0  NL                                     \
-+      .uleb128 code_align NL                          \
-+      .sleb128 data_align NL                          \
-+      .byte pc NL
-+
-+/*
-+ * After the above macro and prior to the CFI_postamble, you need to
-+ * define the initial state.  This starts with defining the reference
-+ * register and, usually the pc.  Here are some helper macros:
-+ */
-+
-+#define CFA_define_reference(reg, offset)     \
-+      .byte DW_CFA_def_cfa NL                 \
-+      .uleb128 reg NL                         \
-+      .uleb128 (offset) NL
-+
-+#define CFA_define_offset(reg, offset)                \
-+      .byte (DW_CFA_offset + reg) NL          \
-+      .uleb128 (offset) NL
-+
-+#define CFA_restore(reg)                      \
-+        .byte (DW_CFA_restore + reg) NL
-+
-+#define CFI_postamble()                               \
-+      .align DATA_ALIGN_FACTOR NL                             \
-+7: NL                                         \
-+.previous NL
-+
-+/*
-+ * So now your code pushs stuff on the stack, you need a new location
-+ * and the rules for what to do.  This starts a running description of
-+ * the call frame.  You need to describe what changes with respect to
-+ * the call registers as the location of the pc moves through the code.
-+ * The following builds an FDE (fram descriptor entry?).  Like the
-+ * above, it has a preamble and a postamble.  It also is tied to the CFI
-+ * above.
-+ * The preamble macro is tied to the CFI thru the first parameter.  The
-+ * second is the code start address and then the code end address+1.
-+ */
-+#define FDE_preamble(ORD, initial_address, end_address)       \
-+        DWARF_preamble NL                             \
-+      .align DATA_ALIGN_FACTOR NL                                     \
-+      .long 9f-8f NL                                  \
-+8:                                                    \
-+      .long CAT3(frame,_,ORD) NL                      \
-+      ADDR_LOC initial_address NL                     \
-+      ADDR_LOC (end_address - initial_address) NL
-+
-+#define FDE_postamble()                               \
-+      .align DATA_ALIGN_FACTOR NL                             \
-+9:     NL                                     \
-+.previous NL
-+
-+/*
-+ * That done, you can now add registers, subtract registers, move the
-+ * reference and even change the reference.  You can also define a new
-+ * area of code the info applies to.  For discontinuous bits you should
-+ * start a new FDE.  You may have as many as you like.
-+ */
-+
-+/*
-+ * To advance the stack address by <bytes> (0x3f max)
-+ */
-+
-+#define CFA_advance_loc(bytes)                        \
-+      .byte DW_CFA_advance_loc+bytes NL
-+
-+/*
-+ * This one is good for 0xff or 255
-+ */
-+#define CFA_advance_loc1(bytes)                       \
-+      .byte DW_CFA_advance_loc1 NL            \
-+        .byte bytes NL
-+
-+#define CFA_undefine_reg(reg)                 \
-+        .byte DW_CFA_undefined NL             \
-+      .uleb128 reg NL
-+/*
-+ * With the above you can define all the register locations.  But
-+ * suppose the reference register moves... Takes the new offset NOT an
-+ * increment.  This is how esp is tracked if it is not saved.
-+ */
-+
-+#define CFA_define_cfa_offset(offset)         \
-+      .byte DW_CFA_def_cfa_offset NL          \
-+      .uleb128 (offset) NL
-+/*
-+ * Or suppose you want to use a different reference register...
-+ */
-+#define CFA_define_cfa_register(reg)          \
-+      .byte DW_CFA_def_cfa_register NL        \
-+      .uleb128 reg NL
-+
-+/*
-+ * If you want to mess with the stack pointer, here is the expression.
-+ * The stack starts empty.
-+ */
-+#define CFA_def_cfa_expression                        \
-+        .byte DW_CFA_def_cfa_expression       NL      \
-+      .uleb128 20f-10f NL                     \
-+10:     NL
-+/*
-+ * This expression is to be used for other regs.  The stack starts with the
-+ * stack address.
-+ */
-+
-+#define CFA_expression(reg)                   \
-+        .byte DW_CFA_expression        NL             \
-+        .uleb128 reg NL                               \
-+      .uleb128 20f-10f NL                     \
-+10:     NL
-+/*
-+ * Here we do the expression stuff.  You should code the above followed
-+ *  by expression OPs followed by CFA_expression_end.
-+ */
-+
-+
-+#define CFA_expression_end                    \
-+20:    NL
-+
-+#define CFA_exp_OP_const4s(a)                 \
-+        .byte DW_OP_const4s NL                        \
-+        .long a NL
-+
-+#define  CFA_exp_OP_swap  .byte DW_OP_swap NL
-+#define  CFA_exp_OP_dup  .byte DW_OP_dup NL
-+#define  CFA_exp_OP_drop  .byte DW_OP_drop NL
-+/*
-+ * All these work on the top two elements on the stack, replacing them
-+ * with the result.  Top comes first where it matters.  True is 1, false 0.
-+ */
-+#define  CFA_exp_OP_deref .byte DW_OP_deref NL
-+#define  CFA_exp_OP_and   .byte DW_OP_and NL
-+#define  CFA_exp_OP_div   .byte DW_OP_div NL
-+#define  CFA_exp_OP_minus .byte DW_OP_minus NL
-+#define  CFA_exp_OP_mod   .byte DW_OP_mod NL
-+#define  CFA_exp_OP_neg   .byte DW_OP_neg NL
-+#define  CFA_exp_OP_plus  .byte DW_OP_plus NL
-+#define  CFA_exp_OP_not   .byte DW_OP_not NL
-+#define  CFA_exp_OP_or    .byte DW_OP_or NL
-+#define  CFA_exp_OP_xor   .byte DW_OP_xor NL
-+#define  CFA_exp_OP_le    .byte DW_OP_le NL
-+#define  CFA_exp_OP_ge    .byte DW_OP_ge NL
-+#define  CFA_exp_OP_eq    .byte DW_OP_eq NL
-+#define  CFA_exp_OP_lt    .byte DW_OP_lt NL
-+#define  CFA_exp_OP_gt    .byte DW_OP_gt NL
-+#define  CFA_exp_OP_ne    .byte DW_OP_ne NL
-+/*
-+ * These take a parameter as noted
-+ */
-+/*
-+ * Unconditional skip to loc. loc is a label (loc:)
-+ */
-+#define CFA_exp_OP_skip(loc)                  \
-+         .byte DW_OP_skip  NL                         \
-+       .hword  loc-.-2 NL
-+/*
-+ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
-+ */
-+#define CFA_exp_OP_bra(loc)                   \
-+         .byte DW_OP_bra NL                   \
-+       .hword loc-.-2 NL
-+
-+/*
-+ * TOS += no (an unsigned number)
-+ */
-+#define CFA_exp_OP_plus_uconst(no)            \
-+         .byte DW_OP_plus_uconst NL           \
-+         .uleb128 no NL
-+
-+/*
-+ * ++TOS = no (a unsigned number)
-+ */
-+#define CFA_exp_OP_constu(no)                 \
-+         .byte DW_OP_constu NL                        \
-+       .uleb128 no NL
-+/*
-+ * ++TOS = no (a signed number)
-+ */
-+#define CFA_exp_OP_consts(no)                 \
-+         .byte DW_OP_consts NL                        \
-+       .sleb128 no NL
-+/*
-+ * ++TOS = no (an unsigned byte)
-+ */
-+#define CFA_exp_OP_const1u(no)                        \
-+         .byte DW_OP_const1u NL                       \
-+       .byte no NL
-+
-+
-+/*
-+ * ++TOS = no (a address)
-+ */
-+#define CFA_exp_OP_addr(no)                   \
-+         .byte DW_OP_addr NL                  \
-+       .long no NL
-+
-+/*
-+ * Push current frames value for "reg" + offset
-+ * We take advantage of the opcode assignments to make this a litteral reg
-+ * rather than use the DW_OP_bregx opcode.
-+ */
-+
-+#define CFA_exp_OP_breg(reg,offset)           \
-+         .byte DW_OP_breg0+reg NL             \
-+         .sleb128 offset NL
-+#endif
-diff -Nauprw linux-2.6.20/include/linux/i2c.h ../new/linux-2.6.20/include/linux/i2c.h
---- linux-2.6.20/include/linux/i2c.h   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/i2c.h    2007-11-21 11:51:42.000000000 +0530
-@@ -146,6 +146,9 @@ struct i2c_driver {
+--- linux-2.6.20.orig/include/linux/i2c.h
++++ linux-2.6.20/include/linux/i2c.h
+@@ -144,10 +144,13 @@ struct i2c_driver {
+  * function is mainly used for lookup & other admin. functions.
+  */
  struct i2c_client {
        unsigned int flags;             /* div., see below              */
        unsigned short addr;            /* chip address - NOTE: 7bit    */
@@ -239416,7 +240497,11 @@ diff -Nauprw linux-2.6.20/include/linux/i2c.h ../new/linux-2.6.20/include/linux/
                                        /* addresses are stored in the  */
                                        /* _LOWER_ 7 bits               */
        struct i2c_adapter *adapter;    /* the adapter we sit on        */
-@@ -214,8 +217,18 @@ struct i2c_adapter {
+       struct i2c_driver *driver;      /* and our access routines      */
+       int usage_count;                /* How many accesses currently  */
+@@ -212,12 +215,22 @@ struct i2c_adapter {
+       void *algo_data;
        /* --- administration stuff. */
        int (*client_register)(struct i2c_client *);
        int (*client_unregister)(struct i2c_client *);
@@ -239429,15 +240514,16 @@ diff -Nauprw linux-2.6.20/include/linux/i2c.h ../new/linux-2.6.20/include/linux/
 +                      /* data fields that are valid for all devices   */
  
        /* data fields that are valid for all devices   */
-+      struct semaphore lock; 
-+       
++      struct semaphore lock;
++
 +      /******ADDED IN consistency with previous i2c subsystem*********/
        u8 level;                       /* nesting level for lockdep */
        struct mutex bus_lock;
        struct mutex clist_lock;
-diff -Nauprw linux-2.6.20/include/linux/kgdb.h ../new/linux-2.6.20/include/linux/kgdb.h
---- linux-2.6.20/include/linux/kgdb.h  1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/kgdb.h   2007-11-21 11:51:42.000000000 +0530
+       int timeout;
+--- /dev/null
++++ linux-2.6.20/include/linux/kgdb.h
 @@ -0,0 +1,271 @@
 +/*
 + * include/linux/kgdb.h
@@ -239710,10 +240796,11 @@ diff -Nauprw linux-2.6.20/include/linux/kgdb.h ../new/linux-2.6.20/include/linux
 +#endif                                /* CONFIG_KGDB */
 +#endif                                /* _KGDB_H_ */
 +#endif                                /* __KERNEL__ */
-diff -Nauprw linux-2.6.20/include/linux/miscdevice.h ../new/linux-2.6.20/include/linux/miscdevice.h
---- linux-2.6.20/include/linux/miscdevice.h    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/miscdevice.h     2007-11-21 11:51:42.000000000 +0530
-@@ -12,6 +12,7 @@
+--- linux-2.6.20.orig/include/linux/miscdevice.h
++++ linux-2.6.20/include/linux/miscdevice.h
+@@ -10,10 +10,11 @@
+ #define ATARIMOUSE_MINOR 5
+ #define SUN_MOUSE_MINOR 6
  #define APOLLO_MOUSE_MINOR 7
  #define PC110PAD_MINOR 9
  /*#define ADB_MOUSE_MINOR 10  FIXME OBSOLETE */
@@ -239721,20 +240808,27 @@ diff -Nauprw linux-2.6.20/include/linux/miscdevice.h ../new/linux-2.6.20/include
  #define WATCHDOG_MINOR                130     /* Watchdog timer     */
  #define TEMP_MINOR            131     /* Temperature Sensor */
  #define RTC_MINOR 135
-diff -Nauprw linux-2.6.20/include/linux/module.h ../new/linux-2.6.20/include/linux/module.h
---- linux-2.6.20/include/linux/module.h        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/module.h 2008-10-20 13:37:45.000000000 +0530
-@@ -34,6 +34,9 @@ struct kernel_symbol
+ #define EFI_RTC_MINOR         136     /* EFI Time services */
+ #define SUN_OPENPROM_MINOR 139
+--- linux-2.6.20.orig/include/linux/module.h
++++ linux-2.6.20/include/linux/module.h
+@@ -32,10 +32,13 @@
+ struct kernel_symbol
  {
        unsigned long value;
        const char *name;
-+#ifdef CONFIG_LKM_HASH        
++#ifdef CONFIG_LKM_HASH
 +      unsigned long hash_value;
-+#endif        
++#endif
  };
  
  struct modversion_info
-@@ -186,6 +189,13 @@ void *__symbol_get_gpl(const char *symbo
+ {
+       unsigned long crc;
+@@ -184,21 +187,28 @@ void *__symbol_get_gpl(const char *symbo
+       = (unsigned long) &__crc_##sym;
+ #else
  #define __CRC_SYMBOL(sym, sec)
  #endif
  
@@ -239748,7 +240842,10 @@ diff -Nauprw linux-2.6.20/include/linux/module.h ../new/linux-2.6.20/include/lin
  /* For every exported symbol, place a struct in the __ksymtab section */
  #define __EXPORT_SYMBOL(sym, sec)                             \
        extern typeof(sym) sym;                                 \
-@@ -196,7 +206,7 @@ void *__symbol_get_gpl(const char *symbo
+       __CRC_SYMBOL(sym, sec)                                  \
+       static const char __kstrtab_##sym[]                     \
+       __attribute__((section("__ksymtab_strings")))           \
+       = MODULE_SYMBOL_PREFIX #sym;                            \
        static const struct kernel_symbol __ksymtab_##sym       \
        __attribute_used__                                      \
        __attribute__((section("__ksymtab" sec), unused))       \
@@ -239757,7 +240854,11 @@ diff -Nauprw linux-2.6.20/include/linux/module.h ../new/linux-2.6.20/include/lin
  
  #define EXPORT_SYMBOL(sym)                                    \
        __EXPORT_SYMBOL(sym, "")
-@@ -228,8 +238,17 @@ enum module_state
+ #define EXPORT_SYMBOL_GPL(sym)                                        \
+@@ -226,12 +236,21 @@ struct module_ref
+ enum module_state
+ {
        MODULE_STATE_LIVE,
        MODULE_STATE_COMING,
        MODULE_STATE_GOING,
@@ -239775,7 +240876,11 @@ diff -Nauprw linux-2.6.20/include/linux/module.h ../new/linux-2.6.20/include/lin
  /* Similar stuff for section attributes. */
  struct module_sect_attr
  {
-@@ -257,6 +276,13 @@ struct module
+       struct module_attribute mattr;
+       char *name;
+@@ -255,10 +274,17 @@ struct module
+       struct list_head list;
        /* Unique handle for this module */
        char name[MODULE_NAME_LEN];
  
@@ -239789,10 +240894,13 @@ diff -Nauprw linux-2.6.20/include/linux/module.h ../new/linux-2.6.20/include/lin
        /* Sysfs stuff. */
        struct module_kobject mkobj;
        struct module_param_attrs *param_attrs;
-diff -Nauprw linux-2.6.20/include/linux/mtd/bbm.h ../new/linux-2.6.20/include/linux/mtd/bbm.h
---- linux-2.6.20/include/linux/mtd/bbm.h       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/mtd/bbm.h        2008-09-17 13:23:35.000000000 +0530
-@@ -10,6 +10,10 @@
+       struct module_attribute *modinfo_attrs;
+       const char *version;
+--- linux-2.6.20.orig/include/linux/mtd/bbm.h
++++ linux-2.6.20/include/linux/mtd/bbm.h
+@@ -8,10 +8,14 @@
+  *  Kyungmin Park <kyungmin.park@samsung.com>
+  *
   *  Copyright (c) 2000-2005
   *  Thomas Gleixner <tglx@linuxtronix.de>
   *
@@ -239803,7 +240911,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/bbm.h ../new/linux-2.6.20/include/li
   */
  #ifndef __LINUX_MTD_BBM_H
  #define __LINUX_MTD_BBM_H
-@@ -92,6 +96,13 @@ struct nand_bbt_descr {
+ /* The maximum number of NAND chips in an array */
+@@ -90,10 +94,17 @@ struct nand_bbt_descr {
+ /*
+  * Constants for oob configuration
   */
  #define ONENAND_BADBLOCK_POS  0
  
@@ -239817,10 +240929,13 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/bbm.h ../new/linux-2.6.20/include/li
  /**
   * struct bbm_info - [GENERIC] Bad Block Table data structure
   * @bbt_erase_shift:  [INTERN] number of address bits in a bbt entry
-diff -Nauprw linux-2.6.20/include/linux/mtd/mtd.h ../new/linux-2.6.20/include/linux/mtd/mtd.h
---- linux-2.6.20/include/linux/mtd/mtd.h       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/mtd/mtd.h        2008-11-19 16:47:04.000000000 +0530
-@@ -119,6 +119,7 @@ struct mtd_info {
+  * @badblockpos:      [INTERN] position of the bad block marker in the oob area
+  * @options:          options for this descriptor
+--- linux-2.6.20.orig/include/linux/mtd/mtd.h
++++ linux-2.6.20/include/linux/mtd/mtd.h
+@@ -117,10 +117,11 @@ struct mtd_info {
+       u_int32_t writesize;
        u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
        u_int32_t ecctype;
        u_int32_t eccsize;
@@ -239828,10 +240943,13 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/mtd.h ../new/linux-2.6.20/include/li
  
        /*
         * Reuse some of the above unused fields in the case of NOR flash
-diff -Nauprw linux-2.6.20/include/linux/mtd/nand.h ../new/linux-2.6.20/include/linux/mtd/nand.h
---- linux-2.6.20/include/linux/mtd/nand.h      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/mtd/nand.h       2007-11-21 11:51:42.000000000 +0530
-@@ -546,54 +546,12 @@ extern int nand_do_read(struct mtd_info 
+        * with configurable programming regions to avoid modifying the
+        * user visible structure layout/size.  Only valid when the
+--- linux-2.6.20.orig/include/linux/mtd/nand.h
++++ linux-2.6.20/include/linux/mtd/nand.h
+@@ -544,56 +544,14 @@ extern int nand_do_read(struct mtd_info 
+                       size_t * retlen, uint8_t * buf);
  /*
  * Constants for oob configuration
  */
@@ -239891,10 +241009,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/nand.h ../new/linux-2.6.20/include/l
 +#endif
  
  #endif /* __LINUX_MTD_NAND_H */
-diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/include/linux/mtd/onenand.h
---- linux-2.6.20/include/linux/mtd/onenand.h   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/mtd/onenand.h    2008-09-17 13:23:35.000000000 +0530
-@@ -42,14 +42,10 @@ typedef enum {
+--- linux-2.6.20.orig/include/linux/mtd/onenand.h
++++ linux-2.6.20/include/linux/mtd/onenand.h
+@@ -40,18 +40,14 @@ typedef enum {
+       FL_PM_SUSPENDED,
+ } onenand_state_t;
  
  /**
   * struct onenand_bufferram - OneNAND BufferRAM Data
@@ -239911,7 +241030,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
  };
  
  /**
-@@ -63,8 +59,8 @@ struct onenand_bufferram {
+  * struct onenand_chip - OneNAND Private Flash Chip Data
+  * @base:             [BOARDSPECIFIC] address to access OneNAND
+@@ -61,12 +57,12 @@ struct onenand_bufferram {
+  * @verstion_id:      [INTERN] version ID
+  * @options:          [BOARDSPECIFIC] various chip options. They can
   *                    partly be set to inform onenand_scan about
   * @erase_shift:      [INTERN] number of address bits in a block
   * @page_shift:               [INTERN] number of address bits in a page
@@ -239921,7 +241044,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
   * @bufferram_index:  [INTERN] BufferRAM index
   * @bufferram:                [INTERN] BufferRAM info
   * @readw:            [REPLACEABLE] hardware specific function for read short
-@@ -87,7 +83,8 @@ struct onenand_bufferram {
+  * @writew:           [REPLACEABLE] hardware specific function for write short
+  * @command:          [REPLACEABLE] hardware specific function for writing
+@@ -85,11 +81,12 @@ struct onenand_bufferram {
+  * @chip_lock:                [INTERN] spinlock used to protect access to this
+  *                    structure and the chip
   * @wq:                       [INTERN] wait queue to sleep on if a OneNAND
   *                    operation is in progress
   * @state:            [INTERN] the current state of the OneNAND device
@@ -239931,7 +241058,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
   * @subpagesize:      [INTERN] holds the subpagesize
   * @ecclayout:                [REPLACEABLE] the default ecc placement scheme
   * @bbm:              [REPLACEABLE] pointer to Bad Block Management
-@@ -103,8 +100,8 @@ struct onenand_chip {
+  * @priv:             [OPTIONAL] pointer to private chip date
+  */
+@@ -101,12 +98,12 @@ struct onenand_chip {
+       unsigned int            density_mask;
+       unsigned int            options;
  
        unsigned int            erase_shift;
        unsigned int            page_shift;
@@ -239941,7 +241072,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
  
        unsigned int            bufferram_index;
        struct onenand_bufferram        bufferram[MAX_BUFFERRAM];
-@@ -128,6 +125,7 @@ struct onenand_chip {
+       int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len);
+@@ -126,10 +123,11 @@ struct onenand_chip {
+       spinlock_t              chip_lock;
        wait_queue_head_t       wq;
        onenand_state_t         state;
        unsigned char           *page_buf;
@@ -239949,7 +241084,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
  
        int                     subpagesize;
        struct nand_ecclayout   *ecclayout;
-@@ -144,12 +142,24 @@ struct onenand_chip {
+       void                    *bbm;
+@@ -142,25 +140,39 @@ struct onenand_chip {
+  */
+ #define ONENAND_CURRENT_BUFFERRAM(this)               (this->bufferram_index)
  #define ONENAND_NEXT_BUFFERRAM(this)          (this->bufferram_index ^ 1)
  #define ONENAND_SET_NEXT_BUFFERRAM(this)      (this->bufferram_index ^= 1)
  #define ONENAND_SET_PREV_BUFFERRAM(this)      (this->bufferram_index ^= 1)
@@ -239974,7 +241113,8 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
  /* Check byte access in OneNAND */
  #define ONENAND_CHECK_BYTE_ACCESS(addr)               (addr & 0x1)
  
-@@ -158,7 +168,9 @@ struct onenand_chip {
+ /*
+  * Options bits
   */
  #define ONENAND_HAS_CONT_LOCK         (0x0001)
  #define ONENAND_HAS_UNLOCK_ALL                (0x0002)
@@ -239984,15 +241124,20 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand.h ../new/linux-2.6.20/includ
  
  /*
   * OneNAND Flash Manufacturer ID Codes
-@@ -176,3 +188,4 @@ struct onenand_manufacturers {
+  */
+ #define ONENAND_MFR_SAMSUNG   0xec
+@@ -174,5 +186,6 @@ struct onenand_manufacturers {
+         int id;
+         char *name;
  };
  
  #endif        /* __LINUX_MTD_ONENAND_H */
 +
-diff -Nauprw linux-2.6.20/include/linux/mtd/onenand_regs.h ../new/linux-2.6.20/include/linux/mtd/onenand_regs.h
---- linux-2.6.20/include/linux/mtd/onenand_regs.h      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/mtd/onenand_regs.h       2008-09-17 13:23:35.000000000 +0530
-@@ -73,6 +73,8 @@
+--- linux-2.6.20.orig/include/linux/mtd/onenand_regs.h
++++ linux-2.6.20/include/linux/mtd/onenand_regs.h
+@@ -71,20 +71,24 @@
+ #define ONENAND_DEVICE_IS_DEMUX               (1 << 2)
+ #define ONENAND_DEVICE_VCC_MASK               (0x3)
  
  #define ONENAND_DEVICE_DENSITY_512Mb  (0x002)
  #define ONENAND_DEVICE_DENSITY_1Gb    (0x003)
@@ -240001,7 +241146,7 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand_regs.h ../new/linux-2.6.20/i
  
  /*
   * Version ID Register F002h (R)
-@@ -80,9 +82,11 @@
+  */
  #define ONENAND_VERSION_PROCESS_SHIFT (8)
  
  /*
@@ -240014,7 +241159,11 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand_regs.h ../new/linux-2.6.20/i
  
  /*
   * Start Address 8 F107h (R/W)
-@@ -108,6 +112,8 @@
+  */
+ #define ONENAND_FPA_MASK              (0x3f)
+@@ -106,10 +110,12 @@
+  */
+ #define ONENAND_CMD_READ              (0x00)
  #define ONENAND_CMD_READOOB           (0x13)
  #define ONENAND_CMD_PROG              (0x80)
  #define ONENAND_CMD_PROGOOB           (0x1A)
@@ -240023,10 +241172,13 @@ diff -Nauprw linux-2.6.20/include/linux/mtd/onenand_regs.h ../new/linux-2.6.20/i
  #define ONENAND_CMD_UNLOCK            (0x23)
  #define ONENAND_CMD_LOCK              (0x2A)
  #define ONENAND_CMD_LOCK_TIGHT                (0x2C)
-diff -Nauprw linux-2.6.20/include/linux/netpoll.h ../new/linux-2.6.20/include/linux/netpoll.h
---- linux-2.6.20/include/linux/netpoll.h       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/netpoll.h        2007-11-21 11:51:42.000000000 +0530
-@@ -16,7 +16,7 @@ struct netpoll {
+ #define ONENAND_CMD_UNLOCK_ALL                (0x27)
+ #define ONENAND_CMD_ERASE             (0x94)
+--- linux-2.6.20.orig/include/linux/netpoll.h
++++ linux-2.6.20/include/linux/netpoll.h
+@@ -14,11 +14,11 @@
+ struct netpoll {
        struct net_device *dev;
        char dev_name[IFNAMSIZ];
        const char *name;
@@ -240035,25 +241187,29 @@ diff -Nauprw linux-2.6.20/include/linux/netpoll.h ../new/linux-2.6.20/include/li
  
        u32 local_ip, remote_ip;
        u16 local_port, remote_port;
-diff -Nauprw linux-2.6.20/include/linux/usb.h ../new/linux-2.6.20/include/linux/usb.h
---- linux-2.6.20/include/linux/usb.h   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/usb.h    2008-07-04 23:45:30.000000000 +0530
-@@ -287,7 +287,9 @@ struct usb_bus {
+       u8 local_mac[ETH_ALEN], remote_mac[ETH_ALEN];
+ };
+--- linux-2.6.20.orig/include/linux/usb.h
++++ linux-2.6.20/include/linux/usb.h
+@@ -285,11 +285,13 @@ struct usb_bus {
+                                        * round-robin allocation */
        struct usb_devmap devmap;       /* device address allocation map */
        struct usb_device *root_hub;    /* Root hub */
        struct list_head bus_list;      /* list of busses */
 -
-+#if defined (CONFIG_NOMADIK_NHK15) 
-+      void *hcpriv;       /* Host Controller private data  - FIXME hack !!*/ 
-+#endif        
++#if defined (CONFIG_NOMADIK_NHK15)
++      void *hcpriv;       /* Host Controller private data  - FIXME hack !!*/
++#endif
        int bandwidth_allocated;        /* on this bus: how much of the time
                                         * reserved for periodic (intr/iso)
                                         * requests is used, on average?
-diff -Nauprw linux-2.6.20/include/linux/v4l2-nomadikdefs.h ../new/linux-2.6.20/include/linux/v4l2-nomadikdefs.h
---- linux-2.6.20/include/linux/v4l2-nomadikdefs.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/v4l2-nomadikdefs.h       2008-11-24 14:06:28.000000000 +0530
+                                        * Units: microseconds/frame.
+                                        * Limits: Full/low speed reserve 90%,
+--- /dev/null
++++ linux-2.6.20/include/linux/v4l2-nomadikdefs.h
 @@ -0,0 +1,12 @@
-+/* ST Microelectronic Proprietary 
++/* ST Microelectronic Proprietary
 +   File: v4l2-nomadikdefs.h
 +   Contains custom V4L2 definition
 +*/
@@ -240065,10 +241221,11 @@ diff -Nauprw linux-2.6.20/include/linux/v4l2-nomadikdefs.h ../new/linux-2.6.20/i
 +#define V4L2_CID_CROP                 (V4L2_CID_PRIVATE_BASE+0)
 +#define V4L2_CID_RESIZE                       (V4L2_CID_PRIVATE_BASE+1)
 +
-diff -Nauprw linux-2.6.20/include/linux/videodev2.h ../new/linux-2.6.20/include/linux/videodev2.h
---- linux-2.6.20/include/linux/videodev2.h     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/include/linux/videodev2.h      2008-11-24 14:06:28.000000000 +0530
-@@ -1340,6 +1340,17 @@ struct v4l2_streamparm
+--- linux-2.6.20.orig/include/linux/videodev2.h
++++ linux-2.6.20/include/linux/videodev2.h
+@@ -1338,10 +1338,21 @@ struct v4l2_streamparm
+ #if 1
+ #define VIDIOC_ENUM_FRAMESIZES        _IOWR ('V', 74, struct v4l2_frmsizeenum)
  #define VIDIOC_ENUM_FRAMEINTERVALS    _IOWR ('V', 75, struct v4l2_frmivalenum)
  #endif
  
@@ -240086,10 +241243,13 @@ diff -Nauprw linux-2.6.20/include/linux/videodev2.h ../new/linux-2.6.20/include/
  #ifdef __OLD_VIDIOC_
  /* for compatibility, will go away some day */
  #define VIDIOC_OVERLAY_OLD            _IOWR ('V', 14, int)
-diff -Nauprw linux-2.6.20/init/Kconfig ../new/linux-2.6.20/init/Kconfig
---- linux-2.6.20/init/Kconfig  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/init/Kconfig   2008-10-20 13:37:46.000000000 +0530
-@@ -561,6 +561,21 @@ config KMOD
+ #define VIDIOC_S_PARM_OLD             _IOW  ('V', 22, struct v4l2_streamparm)
+ #define VIDIOC_S_CTRL_OLD             _IOW  ('V', 28, struct v4l2_control)
+--- linux-2.6.20.orig/init/Kconfig
++++ linux-2.6.20/init/Kconfig
+@@ -559,10 +559,25 @@ config KMOD
+         here, some parts of the kernel will be able to load modules
+         automatically: when a part of the kernel needs a module, it
          runs modprobe with the appropriate arguments, thereby
          loading the module if it is available.  If unsure, say Y.
  
@@ -240111,9 +241271,24 @@ diff -Nauprw linux-2.6.20/init/Kconfig ../new/linux-2.6.20/init/Kconfig
  config STOP_MACHINE
        bool
        default y
-diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
---- linux-2.6.20/kernel/kgdb.c 1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/kgdb.c  2008-10-20 13:37:46.000000000 +0530
+       depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
+       help
+--- linux-2.6.20.orig/kernel/Makefile
++++ linux-2.6.20/kernel/Makefile
+@@ -39,10 +39,11 @@ obj-$(CONFIG_CPUSETS) += cpuset.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
+ obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+ obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
+ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+ obj-$(CONFIG_KPROBES) += kprobes.o
++obj-$(CONFIG_KGDB) += kgdb.o
+ obj-$(CONFIG_SYSFS) += ksysfs.o
+ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
+ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
+ obj-$(CONFIG_SECCOMP) += seccomp.o
+ obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
+--- /dev/null
++++ linux-2.6.20/kernel/kgdb.c
 @@ -0,0 +1,1963 @@
 +/*
 + * kernel/kgdb.c
@@ -240929,19 +242104,19 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +      int error = 0;
 +      unsigned long addr;
 +      for (i = 0; i < MAX_BREAKPOINTS; i++) {
-+              if (kgdb_break[i].state != bp_set) 
++              if (kgdb_break[i].state != bp_set)
 +                      continue;
 +              addr = kgdb_break[i].bpt_addr;
-+              if ((error = kgdb_arch_set_breakpoint(addr, 
++              if ((error = kgdb_arch_set_breakpoint(addr,
 +                                      kgdb_break[i].saved_instr)))
 +                      return error;
 +
 +              if (CACHE_FLUSH_IS_SAFE) {
 +                      if (current->mm && addr < TASK_SIZE)
-+                              flush_cache_range(current->mm->mmap_cache, 
++                              flush_cache_range(current->mm->mmap_cache,
 +                                              addr, addr + BREAK_INSTR_SIZE);
 +                      else
-+                              flush_icache_range(addr, addr + 
++                              flush_icache_range(addr, addr +
 +                                              BREAK_INSTR_SIZE);
 +              }
 +
@@ -240962,7 +242137,7 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +                      return -EEXIST;
 +      }
 +      for (i = 0; i < MAX_BREAKPOINTS; i++) {
-+              if (kgdb_break[i].state == bp_removed && 
++              if (kgdb_break[i].state == bp_removed &&
 +                              kgdb_break[i].bpt_addr == addr) {
 +                      breakno = i;
 +                      break;
@@ -240994,9 +242169,9 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +      unsigned long addr;
 +      for (i = 0; i < MAX_BREAKPOINTS; i++) {
 +              if (kgdb_break[i].state != bp_active)
-+                      continue;       
++                      continue;
 +              addr = kgdb_break[i].bpt_addr;
-+              if ((error = kgdb_arch_remove_breakpoint(addr, 
++              if ((error = kgdb_arch_remove_breakpoint(addr,
 +                                      kgdb_break[i].saved_instr)))
 +                      return error;
 +
@@ -241046,10 +242221,10 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +
 +      /* Clear memory breakpoints. */
 +      for (i = 0; i < MAX_BREAKPOINTS; i++) {
-+              if (kgdb_break[i].state != bp_set) 
++              if (kgdb_break[i].state != bp_set)
 +                      continue;
 +              addr = kgdb_break[i].bpt_addr;
-+              if ((error = kgdb_arch_remove_breakpoint(addr, 
++              if ((error = kgdb_arch_remove_breakpoint(addr,
 +                                      kgdb_break[i].saved_instr)))
 +                      return error;
 +              kgdb_break[i].state = bp_removed;
@@ -241177,7 +242352,7 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +      }
 +
 +      atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1);
-+      
++
 +      /*
 +      * Don't enter if we have hit a removed breakpoint.
 +      */
@@ -241394,7 +242569,7 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +                              put_packet(remcom_out_buffer);
 +                              emergency_sync();
 +                              /* Execution should not return from
-+                               * machine_restart() 
++                               * machine_restart()
 +                               */
 +                              machine_restart(NULL);
 +                              kgdb_connected = 0;
@@ -241735,7 +242910,7 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +
 +      /* We can't do much if this fails */
 +      register_module_notifier(&kgdb_module_load_nb);
-+      
++
 +      kgdb_initialized = 1;
 +}
 +
@@ -241951,7 +243126,7 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +
 +      /* Registering to reboot notifier list*/
 +      register_reboot_notifier(&kgdb_reboot_notifier);
-+      
++
 +      /* Now do any late init of the I/O. */
 +      if (kgdb_io_ops.late_init)
 +              kgdb_io_ops.late_init();
@@ -242021,7 +243196,7 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +static int kgdb_notify_reboot(struct notifier_block *this,
 +                            unsigned long code, void *x)
 +{
-+      
++
 +      unsigned long flags;
 +
 +      /* If we're debugging, or KGDB has not connected, don't try
@@ -242034,8 +243209,8 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +              local_irq_restore(flags);
 +      }
 +      return NOTIFY_DONE;
-+}             
-+      
++}
++
 +#ifdef CONFIG_KGDB_CONSOLE
 +void kgdb_console_write(struct console *co, const char *s, unsigned count)
 +{
@@ -242078,21 +243253,11 @@ diff -Nauprw linux-2.6.20/kernel/kgdb.c ../new/linux-2.6.20/kernel/kgdb.c
 +}
 +
 +early_param("kgdbwait", opt_kgdb_enter);
-diff -Nauprw linux-2.6.20/kernel/Makefile ../new/linux-2.6.20/kernel/Makefile
---- linux-2.6.20/kernel/Makefile       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/Makefile        2007-11-21 11:51:42.000000000 +0530
-@@ -41,6 +41,7 @@ obj-$(CONFIG_STOP_MACHINE) += stop_machi
- obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
- obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
- obj-$(CONFIG_KPROBES) += kprobes.o
-+obj-$(CONFIG_KGDB) += kgdb.o
- obj-$(CONFIG_SYSFS) += ksysfs.o
- obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
- obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
-diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
---- linux-2.6.20/kernel/module.c       2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/module.c        2008-10-20 13:37:46.000000000 +0530
-@@ -55,6 +55,27 @@
+--- linux-2.6.20.orig/kernel/module.c
++++ linux-2.6.20/kernel/module.c
+@@ -53,19 +53,41 @@
+ #ifndef ARCH_SHF_SMALL
  #define ARCH_SHF_SMALL 0
  #endif
  
@@ -242120,7 +243285,9 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
  /* If this is set, the section belongs in the init part of the module */
  #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
  
-@@ -64,6 +85,7 @@ static DEFINE_SPINLOCK(modlist_lock);
+ /* Protects module list */
+ static DEFINE_SPINLOCK(modlist_lock);
  /* List of modules, protected by module_mutex AND modlist_lock */
  static DEFINE_MUTEX(module_mutex);
  static LIST_HEAD(modules);
@@ -242128,7 +243295,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
  
  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
  
-@@ -145,7 +167,58 @@ extern const unsigned long __start___kcr
+ int register_module_notifier(struct notifier_block * nb)
+ {
+@@ -143,11 +165,62 @@ extern const unsigned long __start___kcr
+ #define symversion(base, idx) NULL
+ #else
  #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
  #endif
  
@@ -242160,10 +243331,10 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
 +      const struct kernel_symbol *start,
 +      const struct kernel_symbol *stop)
 +{
-+      const struct kernel_symbol *ks = start; 
-+      
++      const struct kernel_symbol *ks = start;
++
 +      for (; ks < stop; ks++) {
-+      
++
 +              /* If hash values don't match, we are sure symbols are different,
 +                 otherwise we need to explicitely do string comparison.
 +              */
@@ -242188,7 +243359,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
  static const struct kernel_symbol *lookup_symbol(const char *name,
        const struct kernel_symbol *start,
        const struct kernel_symbol *stop)
-@@ -157,6 +230,9 @@ static const struct kernel_symbol *looku
+ {
+       const struct kernel_symbol *ks = start;
+@@ -155,10 +228,13 @@ static const struct kernel_symbol *looku
+               if (strcmp(ks->name, name) == 0)
+                       return ks;
        return NULL;
  }
  
@@ -242198,7 +243373,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
  static void printk_unused_warning(const char *name)
  {
        printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
-@@ -169,7 +245,7 @@ static void printk_unused_warning(const 
+               "however this module is using it.\n", name);
+       printk(KERN_WARNING "This symbol will go away in the future.\n");
+@@ -167,35 +243,35 @@ static void printk_unused_warning(const 
+               "mailinglist together with submitting your code for "
+               "inclusion.\n");
  }
  
  /* Find a symbol, return value, crc and module which owns it */
@@ -242207,7 +243386,9 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                   struct module **owner,
                                   const unsigned long **crc,
                                   int gplok)
-@@ -179,13 +255,13 @@ static unsigned long __find_symbol(const
+ {
+       struct module *mod;
+       const struct kernel_symbol *ks;
  
        /* Core kernel first. */ 
        *owner = NULL;
@@ -242223,7 +243404,7 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                         __stop___ksymtab_gpl);
                if (ks) {
                        *crc = symversion(__start___kcrctab_gpl,
-@@ -193,7 +269,7 @@ static unsigned long __find_symbol(const
+                                         (ks - __start___ksymtab_gpl));
                        return ks->value;
                }
        }
@@ -242232,7 +243413,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                 __stop___ksymtab_gpl_future);
        if (ks) {
                if (!gplok) {
-@@ -210,7 +286,7 @@ static unsigned long __find_symbol(const
+                       printk(KERN_WARNING "Symbol %s is being used "
+                              "by a non-GPL module, which will not "
+@@ -208,21 +284,21 @@ static unsigned long __find_symbol(const
+               *crc = symversion(__start___kcrctab_gpl_future,
+                                 (ks - __start___ksymtab_gpl_future));
                return ks->value;
        }
  
@@ -242241,7 +243426,9 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                 __stop___ksymtab_unused);
        if (ks) {
                printk_unused_warning(name);
-@@ -220,7 +296,7 @@ static unsigned long __find_symbol(const
+               *crc = symversion(__start___kcrctab_unused,
+                                 (ks - __start___ksymtab_unused));
+               return ks->value;
        }
  
        if (gplok)
@@ -242250,7 +243437,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                 __stop___ksymtab_unused_gpl);
        if (ks) {
                printk_unused_warning(name);
-@@ -232,14 +308,14 @@ static unsigned long __find_symbol(const
+               *crc = symversion(__start___kcrctab_unused_gpl,
+                                 (ks - __start___ksymtab_unused_gpl));
+@@ -230,43 +306,43 @@ static unsigned long __find_symbol(const
+       }
        /* Now try modules. */ 
        list_for_each_entry(mod, &modules, list) {
                *owner = mod;
@@ -242267,7 +243458,7 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                           mod->gpl_syms + mod->num_gpl_syms);
                        if (ks) {
                                *crc = symversion(mod->gpl_crcs,
-@@ -247,7 +323,7 @@ static unsigned long __find_symbol(const
+                                                 (ks - mod->gpl_syms));
                                return ks->value;
                        }
                }
@@ -242276,7 +243467,7 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                if (ks) {
                        printk_unused_warning(name);
                        *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
-@@ -255,7 +331,7 @@ static unsigned long __find_symbol(const
+                       return ks->value;
                }
  
                if (gplok) {
@@ -242285,7 +243476,8 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                           mod->unused_gpl_syms + mod->num_unused_gpl_syms);
                        if (ks) {
                                printk_unused_warning(name);
-@@ -264,7 +340,7 @@ static unsigned long __find_symbol(const
+                               *crc = symversion(mod->unused_gpl_crcs,
+                                                 (ks - mod->unused_gpl_syms));
                                return ks->value;
                        }
                }
@@ -242294,7 +243486,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                                   (mod->gpl_future_syms +
                                    mod->num_gpl_future_syms));
                if (ks) {
-@@ -706,6 +782,12 @@ sys_delete_module(const char __user *nam
+                       if (!gplok) {
+                               printk(KERN_WARNING "Symbol %s is being used "
+@@ -704,10 +780,16 @@ sys_delete_module(const char __user *nam
+       /* Stop the machine so refcounts can't move and disable module. */
+       ret = try_stop_module(mod, flags, &forced);
        if (ret != 0)
                goto out;
  
@@ -242307,7 +243503,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        /* Never wait if forced. */
        if (!forced && module_refcount(mod) != 0)
                wait_for_zero_refcount(mod);
-@@ -718,6 +800,11 @@ sys_delete_module(const char __user *nam
+       /* Final destruction now noone is using it. */
+@@ -716,10 +798,15 @@ sys_delete_module(const char __user *nam
+               mod->exit();
+               mutex_lock(&module_mutex);
        }
        free_module(mod);
  
@@ -242319,7 +243519,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
   out:
        mutex_unlock(&module_mutex);
        return ret;
-@@ -758,7 +845,7 @@ void __symbol_put(const char *symbol)
+ }
+@@ -756,11 +843,11 @@ void __symbol_put(const char *symbol)
+       struct module *owner;
+       unsigned long flags;
        const unsigned long *crc;
  
        spin_lock_irqsave(&modlist_lock, flags);
@@ -242328,7 +243532,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                BUG();
        module_put(owner);
        spin_unlock_irqrestore(&modlist_lock, flags);
-@@ -839,6 +926,9 @@ static ssize_t show_initstate(struct mod
+ }
+ EXPORT_SYMBOL(__symbol_put);
+@@ -837,10 +924,13 @@ static ssize_t show_initstate(struct mod
+               state = "coming";
+               break;
        case MODULE_STATE_GOING:
                state = "going";
                break;
@@ -242338,7 +243546,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        }
        return sprintf(buffer, "%s\n", state);
  }
-@@ -905,7 +995,7 @@ static inline int check_modstruct_versio
+ static struct module_attribute initstate = {
+@@ -903,11 +993,11 @@ static inline int check_modstruct_versio
+                                         struct module *mod)
+ {
        const unsigned long *crc;
        struct module *owner;
  
@@ -242347,7 +243559,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                BUG();
        return check_version(sechdrs, versindex, "struct_module", mod,
                             crc);
-@@ -946,13 +1036,14 @@ static inline int same_magic(const char 
+ }
+@@ -944,17 +1034,18 @@ static inline int same_magic(const char 
+ /* Resolve a symbol for this module.  I.e. if we find one, record usage.
+    Must be holding module_mutex. */
  static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
                                    unsigned int versindex,
                                    const char *name,
@@ -242363,7 +243579,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                        !(mod->taints & TAINT_PROPRIETARY_MODULE));
        if (ret) {
                /* use_module can fail due to OOM, or module unloading */
-@@ -1192,6 +1283,11 @@ static void free_module(struct module *m
+               if (!check_version(sechdrs, versindex, name, mod, crc) ||
+                   !use_module(mod, owner))
+@@ -1190,10 +1281,15 @@ static void free_module(struct module *m
+       unwind_remove_table(mod->unwind_info, 0);
        /* Arch-specific cleanup. */
        module_arch_cleanup(mod);
  
@@ -242375,7 +243595,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        /* Module unload stuff */
        module_unload_free(mod);
  
-@@ -1215,7 +1311,7 @@ void *__symbol_get(const char *symbol)
+       /* This may be NULL, but that's OK */
+       module_free(mod, mod->module_init);
+@@ -1213,11 +1309,11 @@ void *__symbol_get(const char *symbol)
+       struct module *owner;
+       unsigned long value, flags;
        const unsigned long *crc;
  
        spin_lock_irqsave(&modlist_lock, flags);
@@ -242384,7 +243608,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        if (value && !strong_try_module_get(owner))
                value = 0;
        spin_unlock_irqrestore(&modlist_lock, flags);
-@@ -1236,14 +1332,14 @@ static int verify_export_symbols(struct 
+       return (void *)value;
+@@ -1234,18 +1330,18 @@ static int verify_export_symbols(struct 
+       unsigned long i, ret = 0;
+       struct module *owner;
        const unsigned long *crc;
  
        for (i = 0; i < mod->num_syms; i++)
@@ -242401,7 +243629,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                        name = mod->gpl_syms[i].name;
                        ret = -ENOEXEC;
                        goto dup;
-@@ -1260,6 +1356,7 @@ dup:
+               }
+@@ -1258,20 +1354,29 @@ dup:
+ }
  /* Change all symbols so that sh_value encodes the pointer directly. */
  static int simplify_symbols(Elf_Shdr *sechdrs,
                            unsigned int symindex,
@@ -242409,7 +243641,10 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                            const char *strtab,
                            unsigned int versindex,
                            unsigned int pcpuindex,
-@@ -1270,6 +1367,14 @@ static int simplify_symbols(Elf_Shdr *se
+                           struct module *mod)
+ {
+       Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+       unsigned long secbase;
        unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
        int ret = 0;
  
@@ -242419,12 +243654,16 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
 +      unsigned int u = 0;
 +#else
 +#define HASH_VALUE
-+#endif        
-+      
++#endif
++
        for (i = 1; i < n; i++) {
                switch (sym[i].st_shndx) {
                case SHN_COMMON:
-@@ -1290,7 +1395,7 @@ static int simplify_symbols(Elf_Shdr *se
+                       /* We compiled with -fno-common.  These are not
+                          supposed to happen.  */
+@@ -1288,11 +1393,11 @@ static int simplify_symbols(Elf_Shdr *se
+                       break;
                case SHN_UNDEF:
                        sym[i].st_value
                          = resolve_symbol(sechdrs, versindex,
@@ -242433,7 +243672,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
  
                        /* Ok if resolved.  */
                        if (sym[i].st_value != 0)
-@@ -1451,13 +1556,39 @@ static void setup_modinfo(struct module 
+                               break;
+                       /* Ok if weak.  */
+@@ -1449,17 +1554,43 @@ static void setup_modinfo(struct module 
+                                               infoindex,
+                                               attr->attr.name));
        }
  }
  
@@ -242466,7 +243709,7 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
  {
 -      if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
 +      HASH_VALUE_DEF(name);
-+      
++
 +      if (!mod && lookup_symbol(name, HASH_VALUE_ARG __start___ksymtab, __stop___ksymtab))
                return 1;
        else
@@ -242475,17 +243718,25 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                        return 1;
                else
                        return 0;
-@@ -1543,6 +1674,9 @@ static struct module *load_module(void _
+ }
+@@ -1541,10 +1672,13 @@ static struct module *load_module(void _
+       Elf_Shdr *sechdrs;
+       char *secstrings, *args, *modmagic, *strtab = NULL;
        unsigned int i;
        unsigned int symindex = 0;
        unsigned int strindex = 0;
 +#ifdef CONFIG_LKM_HASH
 +      unsigned int symhashindex = 0;
-+#endif        
++#endif
        unsigned int setupindex;
        unsigned int exindex;
        unsigned int exportindex;
-@@ -1565,6 +1699,9 @@ static struct module *load_module(void _
+       unsigned int modindex;
+       unsigned int obsparmindex;
+@@ -1563,10 +1697,13 @@ static struct module *load_module(void _
+       unsigned int unusedgplcrcindex;
+       struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
        struct exception_table_entry *extable;
@@ -242495,7 +243746,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        mm_segment_t old_fs;
  
        DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
-@@ -1637,6 +1774,17 @@ static struct module *load_module(void _
+              umod, len, uargs);
+       if (len < sizeof(*hdr))
+@@ -1635,10 +1772,21 @@ static struct module *load_module(void _
+                      mod->name);
+               err = -ENOEXEC;
                goto free_hdr;
        }
  
@@ -242507,13 +243762,17 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
 +              err = -ENOEXEC;
 +              goto free_hdr;
 +      }
-+#endif        
-+      
++#endif
++
 +
        /* Optional sections */
        exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
        gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
-@@ -1780,11 +1928,17 @@ static struct module *load_module(void _
+       gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
+       unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
+@@ -1778,15 +1926,21 @@ static struct module *load_module(void _
+       /* Set up MODINFO_ATTR fields */
        setup_modinfo(mod, sechdrs, infoindex);
  
        /* Fix up syms, so that st_value is a pointer to location. */
@@ -242527,13 +243786,17 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                goto cleanup;
 -
 +#ifdef LKM_LOAD_BENCH
-+      do_gettimeofday(&end);  
++      do_gettimeofday(&end);
 +      print_elapsed(mod->name, &start, &end);
 +#endif
        /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */
        mod->num_syms = sechdrs[exportindex].sh_size / sizeof(*mod->syms);
        mod->syms = (void *)sechdrs[exportindex].sh_addr;
-@@ -1862,6 +2016,12 @@ static struct module *load_module(void _
+       if (crcindex)
+               mod->crcs = (void *)sechdrs[crcindex].sh_addr;
+@@ -1860,10 +2014,16 @@ static struct module *load_module(void _
+       percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
+                      sechdrs[pcpuindex].sh_size);
  
        add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
  
@@ -242546,7 +243809,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        err = module_finalize(hdr, sechdrs, mod);
        if (err < 0)
                goto cleanup;
-@@ -1922,6 +2082,11 @@ static struct module *load_module(void _
+       /* flush the icache in correct context */
+@@ -1920,10 +2080,15 @@ static struct module *load_module(void _
+       return mod;
   arch_cleanup:
        module_arch_cleanup(mod);
   cleanup:
@@ -242558,7 +243825,11 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
        module_unload_free(mod);
        module_free(mod, mod->module_init);
   free_core:
-@@ -1993,6 +2158,11 @@ sys_init_module(void __user *umod,
+       module_free(mod, mod->module_core);
+  free_percpu:
+@@ -1991,10 +2156,15 @@ sys_init_module(void __user *umod,
+               ret = mod->init();
+       if (ret < 0) {
                /* Init routine failed: abort.  Try to protect us from
                     buggy refcounters. */
                mod->state = MODULE_STATE_GOING;
@@ -242570,10 +243841,13 @@ diff -Nauprw linux-2.6.20/kernel/module.c ../new/linux-2.6.20/kernel/module.c
                synchronize_sched();
                if (mod->unsafe)
                        printk(KERN_ERR "%s: module is now stuck!\n",
-diff -Nauprw linux-2.6.20/kernel/pid.c ../new/linux-2.6.20/kernel/pid.c
---- linux-2.6.20/kernel/pid.c  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/pid.c   2007-11-21 11:51:42.000000000 +0530
-@@ -383,8 +383,13 @@ void free_pid_ns(struct kref *kref)
+                              mod->name);
+               else {
+--- linux-2.6.20.orig/kernel/pid.c
++++ linux-2.6.20/kernel/pid.c
+@@ -381,12 +381,17 @@ void free_pid_ns(struct kref *kref)
+ }
  /*
   * The pid hash table is scaled according to the amount of memory in the
   * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
@@ -242588,7 +243862,11 @@ diff -Nauprw linux-2.6.20/kernel/pid.c ../new/linux-2.6.20/kernel/pid.c
  void __init pidhash_init(void)
  {
        int i, pidhash_size;
-@@ -403,6 +408,10 @@ void __init pidhash_init(void)
+       unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT);
+@@ -401,10 +406,14 @@ void __init pidhash_init(void)
+       pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash)));
+       if (!pid_hash)
                panic("Could not alloc pidhash!\n");
        for (i = 0; i < pidhash_size; i++)
                INIT_HLIST_HEAD(&pid_hash[i]);
@@ -242599,10 +243877,13 @@ diff -Nauprw linux-2.6.20/kernel/pid.c ../new/linux-2.6.20/kernel/pid.c
  }
  
  void __init pidmap_init(void)
-diff -Nauprw linux-2.6.20/kernel/power/main.c ../new/linux-2.6.20/kernel/power/main.c
---- linux-2.6.20/kernel/power/main.c   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/power/main.c    2007-11-21 11:51:42.000000000 +0530
-@@ -87,7 +87,7 @@ static int suspend_prepare(suspend_state
+ {
+       init_pid_ns.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+--- linux-2.6.20.orig/kernel/power/main.c
++++ linux-2.6.20/kernel/power/main.c
+@@ -85,11 +85,11 @@ static int suspend_prepare(suspend_state
+       if (pm_ops->prepare) {
+               if ((error = pm_ops->prepare(state)))
                        goto Thaw;
        }
  
@@ -242611,10 +243892,13 @@ diff -Nauprw linux-2.6.20/kernel/power/main.c ../new/linux-2.6.20/kernel/power/m
        if ((error = device_suspend(PMSG_SUSPEND))) {
                printk(KERN_ERR "Some devices failed to suspend\n");
                goto Finish;
-diff -Nauprw linux-2.6.20/kernel/sched.c ../new/linux-2.6.20/kernel/sched.c
---- linux-2.6.20/kernel/sched.c        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/sched.c 2007-11-21 11:51:42.000000000 +0530
-@@ -52,6 +52,7 @@
+       }
+       return 0;
+--- linux-2.6.20.orig/kernel/sched.c
++++ linux-2.6.20/kernel/sched.c
+@@ -50,10 +50,11 @@
+ #include <linux/syscalls.h>
+ #include <linux/times.h>
  #include <linux/tsacct_kern.h>
  #include <linux/kprobes.h>
  #include <linux/delayacct.h>
@@ -242622,7 +243906,11 @@ diff -Nauprw linux-2.6.20/kernel/sched.c ../new/linux-2.6.20/kernel/sched.c
  #include <asm/tlb.h>
  
  #include <asm/unistd.h>
-@@ -6962,6 +6963,11 @@ void __might_sleep(char *file, int line)
+ /*
+@@ -6964,10 +6965,15 @@ void __init sched_init(void)
+ void __might_sleep(char *file, int line)
+ {
  #ifdef in_atomic
        static unsigned long prev_jiffy;        /* ratelimiting */
  
@@ -242634,10 +243922,13 @@ diff -Nauprw linux-2.6.20/kernel/sched.c ../new/linux-2.6.20/kernel/sched.c
        if ((in_atomic() || irqs_disabled()) &&
            system_state == SYSTEM_RUNNING && !oops_in_progress) {
                if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
-diff -Nauprw linux-2.6.20/kernel/softlockup.c ../new/linux-2.6.20/kernel/softlockup.c
---- linux-2.6.20/kernel/softlockup.c   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/softlockup.c    2007-11-21 11:51:42.000000000 +0530
-@@ -13,6 +13,7 @@
+                       return;
+               prev_jiffy = jiffies;
+--- linux-2.6.20.orig/kernel/softlockup.c
++++ linux-2.6.20/kernel/softlockup.c
+@@ -11,10 +11,11 @@
+ #include <linux/init.h>
+ #include <linux/delay.h>
  #include <linux/kthread.h>
  #include <linux/notifier.h>
  #include <linux/module.h>
@@ -242645,7 +243936,11 @@ diff -Nauprw linux-2.6.20/kernel/softlockup.c ../new/linux-2.6.20/kernel/softloc
  
  static DEFINE_SPINLOCK(print_lock);
  
-@@ -37,6 +38,9 @@ static struct notifier_block panic_block
+ static DEFINE_PER_CPU(unsigned long, touch_timestamp);
+ static DEFINE_PER_CPU(unsigned long, print_timestamp);
+@@ -35,10 +36,13 @@ static struct notifier_block panic_block
+ };
  void touch_softlockup_watchdog(void)
  {
        __raw_get_cpu_var(touch_timestamp) = jiffies;
@@ -242655,10 +243950,13 @@ diff -Nauprw linux-2.6.20/kernel/softlockup.c ../new/linux-2.6.20/kernel/softloc
  }
  EXPORT_SYMBOL(touch_softlockup_watchdog);
  
-diff -Nauprw linux-2.6.20/kernel/timer.c ../new/linux-2.6.20/kernel/timer.c
---- linux-2.6.20/kernel/timer.c        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/kernel/timer.c 2008-10-20 13:37:46.000000000 +0530
-@@ -33,6 +33,7 @@
+ /*
+  * This callback runs from the timer interrupt, and checks
+--- linux-2.6.20.orig/kernel/timer.c
++++ linux-2.6.20/kernel/timer.c
+@@ -31,10 +31,11 @@
+ #include <linux/time.h>
+ #include <linux/jiffies.h>
  #include <linux/posix-timers.h>
  #include <linux/cpu.h>
  #include <linux/syscalls.h>
@@ -242666,7 +243964,11 @@ diff -Nauprw linux-2.6.20/kernel/timer.c ../new/linux-2.6.20/kernel/timer.c
  #include <linux/delay.h>
  
  #include <asm/uaccess.h>
-@@ -1207,8 +1208,15 @@ static inline void update_times(unsigned
+ #include <asm/unistd.h>
+ #include <asm/div64.h>
+@@ -1205,12 +1206,19 @@ static inline void update_times(unsigned
+  * jiffies is defined in the linker script...
+  */
  
  void do_timer(unsigned long ticks)
  {
@@ -242682,10 +243984,13 @@ diff -Nauprw linux-2.6.20/kernel/timer.c ../new/linux-2.6.20/kernel/timer.c
  }
  
  #ifdef __ARCH_WANT_SYS_ALARM
-diff -Nauprw linux-2.6.20/lib/Kconfig.debug ../new/linux-2.6.20/lib/Kconfig.debug
---- linux-2.6.20/lib/Kconfig.debug     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/lib/Kconfig.debug      2007-11-21 11:51:42.000000000 +0530
-@@ -429,3 +429,82 @@ config FAULT_INJECTION_DEBUG_FS
+ /*
+--- linux-2.6.20.orig/lib/Kconfig.debug
++++ linux-2.6.20/lib/Kconfig.debug
+@@ -427,5 +427,84 @@ config FAIL_MAKE_REQUEST
+ config FAULT_INJECTION_DEBUG_FS
+       bool "Debugfs entries for fault-injection capabilities"
        depends on FAULT_INJECTION && SYSFS && DEBUG_FS
        help
          Enable configuration of fault-injection capabilities via debugfs.
@@ -242768,583 +244073,11 @@ diff -Nauprw linux-2.6.20/lib/Kconfig.debug ../new/linux-2.6.20/lib/Kconfig.debu
 +          to use NETCONSOLE in conjunction with KGDB_ETH instead of
 +          KGDB_CONSOLE.
 +
-diff -Nauprw linux-2.6.20/MAINTAINERS ../new/linux-2.6.20/MAINTAINERS
---- linux-2.6.20/MAINTAINERS   2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/MAINTAINERS    2007-11-21 11:51:42.000000000 +0530
-@@ -1941,6 +1941,15 @@ L:      linux-kernel@vger.kernel.org
- L:    fastboot@osdl.org
- S:    Maintained
-+KGDB
-+P:    Tom Rini
-+P:    Amit S. Kale
-+M:    trini@kernel.crashing.org
-+M:    amitkale@linsyssoft.com
-+W:    http://sourceforge.net/projects/kgdb
-+L:    kgdb-bugreport@lists.sourceforge.net
-+S:    Maintained
-+
- KPROBES
- P:    Prasanna S Panchamukhi
- M:    prasanna@in.ibm.com
-diff -Nauprw linux-2.6.20/Makefile ../new/linux-2.6.20/Makefile
---- linux-2.6.20/Makefile      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/Makefile       2008-10-20 13:37:44.000000000 +0530
-@@ -12,7 +12,7 @@ NAME = Homicidal Dwarf Hamster
- # Do not:
- # o  use make's built-in rules and variables
--#    (this increases performance and avoid hard-to-debug behavour);
-+#    (this increases performance and avoids hard-to-debug behaviour);
- # o  print "Entering directory ...";
- MAKEFLAGS += -rR --no-print-directory
-@@ -321,7 +321,7 @@ KERNELRELEASE = $(shell cat include/conf
- KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
- export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
--export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
-+export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CFLAGS CROSS_COMPILE AS LD CC
- export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
- export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
-@@ -497,7 +497,7 @@ CFLAGS             += -fomit-frame-pointer
- endif
- ifdef CONFIG_DEBUG_INFO
--CFLAGS                += -g
-+CFLAGS                += -gdwarf-2
- endif
- # Force gcc to behave correct even for buggy distributions
-@@ -530,7 +530,6 @@ export     INSTALL_PATH ?= /boot
- # relocations required by build roots.  This is not defined in the
- # makefile but the argument can be passed to make if needed.
- #
--
- MODLIB        = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
- export MODLIB
-@@ -576,7 +575,7 @@ libs-y             := $(libs-y1) $(libs-y2)
- # ---------------------------------------------------------------------------
- # vmlinux is built from the objects selected by $(vmlinux-init) and
- # $(vmlinux-main). Most are built-in.o files from top-level directories
--# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
-+# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
- # Ordering when linking is important, and $(vmlinux-init) must be first.
- #
- # vmlinux
-@@ -734,6 +733,7 @@ debug_kallsyms: .tmp_map$(last_kallsyms)
- endif # ifdef CONFIG_KALLSYMS
-+include $(srctree)/scripts/ksymhash/Makefile
- # vmlinux image - including updated kernel symbols
- vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
- ifdef CONFIG_HEADERS_CHECK
-@@ -742,6 +742,7 @@ endif
-       $(call if_changed_rule,vmlinux__)
-       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
-       $(Q)rm -f .old_version
-+      $(rule_ksymhash)
- # The actual objects are generated when descending, 
- # make sure no implicit rule kicks in
-@@ -1482,7 +1483,12 @@ clean := -f $(if $(KBUILD_SRC),$(srctree
- endif # skip-makefile
- PHONY += FORCE
--FORCE:
-+include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk
-+      mkdir -p include/linux/
-+      awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h
-+
-+FORCE: include/linux/dwarf2-defs.h
-+
- # Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes.
- Makefile: ;
-diff -Nauprw linux-2.6.20/net/core/fib_rules.c ../new/linux-2.6.20/net/core/fib_rules.c
---- linux-2.6.20/net/core/fib_rules.c  2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/net/core/fib_rules.c   2008-08-27 04:39:17.000000000 +0530
-@@ -1,473 +0,0 @@
--/*
-- * net/core/fib_rules.c               Generic Routing Rules
-- *
-- *    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, version 2.
-- *
-- * Authors:   Thomas Graf <tgraf@suug.ch>
-- */
--
--#include <linux/types.h>
--#include <linux/kernel.h>
--#include <linux/list.h>
--#include <net/fib_rules.h>
--
--static LIST_HEAD(rules_ops);
--static DEFINE_SPINLOCK(rules_mod_lock);
--
--static void notify_rule_change(int event, struct fib_rule *rule,
--                             struct fib_rules_ops *ops, struct nlmsghdr *nlh,
--                             u32 pid);
--
--static struct fib_rules_ops *lookup_rules_ops(int family)
--{
--      struct fib_rules_ops *ops;
--
--      rcu_read_lock();
--      list_for_each_entry_rcu(ops, &rules_ops, list) {
--              if (ops->family == family) {
--                      if (!try_module_get(ops->owner))
--                              ops = NULL;
--                      rcu_read_unlock();
--                      return ops;
--              }
--      }
--      rcu_read_unlock();
--
--      return NULL;
--}
--
--static void rules_ops_put(struct fib_rules_ops *ops)
--{
--      if (ops)
--              module_put(ops->owner);
--}
--
--int fib_rules_register(struct fib_rules_ops *ops)
--{
--      int err = -EEXIST;
--      struct fib_rules_ops *o;
--
--      if (ops->rule_size < sizeof(struct fib_rule))
--              return -EINVAL;
--
--      if (ops->match == NULL || ops->configure == NULL ||
--          ops->compare == NULL || ops->fill == NULL ||
--          ops->action == NULL)
--              return -EINVAL;
--
--      spin_lock(&rules_mod_lock);
--      list_for_each_entry(o, &rules_ops, list)
--              if (ops->family == o->family)
--                      goto errout;
--
--      list_add_tail_rcu(&ops->list, &rules_ops);
--      err = 0;
--errout:
--      spin_unlock(&rules_mod_lock);
--
--      return err;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_register);
--
--static void cleanup_ops(struct fib_rules_ops *ops)
--{
--      struct fib_rule *rule, *tmp;
--
--      list_for_each_entry_safe(rule, tmp, ops->rules_list, list) {
--              list_del_rcu(&rule->list);
--              fib_rule_put(rule);
--      }
--}
--
--int fib_rules_unregister(struct fib_rules_ops *ops)
--{
--      int err = 0;
--      struct fib_rules_ops *o;
--
--      spin_lock(&rules_mod_lock);
--      list_for_each_entry(o, &rules_ops, list) {
--              if (o == ops) {
--                      list_del_rcu(&o->list);
--                      cleanup_ops(ops);
--                      goto out;
--              }
--      }
--
--      err = -ENOENT;
--out:
--      spin_unlock(&rules_mod_lock);
--
--      synchronize_rcu();
--
--      return err;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_unregister);
--
--static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
--                        struct flowi *fl, int flags)
--{
--      int ret = 0;
--
--      if (rule->ifindex && (rule->ifindex != fl->iif))
--              goto out;
--
--      if ((rule->mark ^ fl->mark) & rule->mark_mask)
--              goto out;
--
--      ret = ops->match(rule, fl, flags);
--out:
--      return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
--}
--
--int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
--                   int flags, struct fib_lookup_arg *arg)
--{
--      struct fib_rule *rule;
--      int err;
--
--      rcu_read_lock();
--
--      list_for_each_entry_rcu(rule, ops->rules_list, list) {
--              if (!fib_rule_match(rule, ops, fl, flags))
--                      continue;
--
--              err = ops->action(rule, fl, flags, arg);
--              if (err != -EAGAIN) {
--                      fib_rule_get(rule);
--                      arg->rule = rule;
--                      goto out;
--              }
--      }
--
--      err = -ENETUNREACH;
--out:
--      rcu_read_unlock();
--
--      return err;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_lookup);
--
--int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
--{
--      struct fib_rule_hdr *frh = nlmsg_data(nlh);
--      struct fib_rules_ops *ops = NULL;
--      struct fib_rule *rule, *r, *last = NULL;
--      struct nlattr *tb[FRA_MAX+1];
--      int err = -EINVAL;
--
--      if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
--              goto errout;
--
--      ops = lookup_rules_ops(frh->family);
--      if (ops == NULL) {
--              err = EAFNOSUPPORT;
--              goto errout;
--      }
--
--      err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy);
--      if (err < 0)
--              goto errout;
--
--      rule = kzalloc(ops->rule_size, GFP_KERNEL);
--      if (rule == NULL) {
--              err = -ENOMEM;
--              goto errout;
--      }
--
--      if (tb[FRA_PRIORITY])
--              rule->pref = nla_get_u32(tb[FRA_PRIORITY]);
--
--      if (tb[FRA_IFNAME]) {
--              struct net_device *dev;
--
--              rule->ifindex = -1;
--              nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ);
--              dev = __dev_get_by_name(rule->ifname);
--              if (dev)
--                      rule->ifindex = dev->ifindex;
--      }
--
--      if (tb[FRA_FWMARK]) {
--              rule->mark = nla_get_u32(tb[FRA_FWMARK]);
--              if (rule->mark)
--                      /* compatibility: if the mark value is non-zero all bits
--                       * are compared unless a mask is explicitly specified.
--                       */
--                      rule->mark_mask = 0xFFFFFFFF;
--      }
--
--      if (tb[FRA_FWMASK])
--              rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
--
--      rule->action = frh->action;
--      rule->flags = frh->flags;
--      rule->table = frh_get_table(frh, tb);
--
--      if (!rule->pref && ops->default_pref)
--              rule->pref = ops->default_pref();
--
--      err = ops->configure(rule, skb, nlh, frh, tb);
--      if (err < 0)
--              goto errout_free;
--
--      list_for_each_entry(r, ops->rules_list, list) {
--              if (r->pref > rule->pref)
--                      break;
--              last = r;
--      }
--
--      fib_rule_get(rule);
--
--      if (last)
--              list_add_rcu(&rule->list, &last->list);
--      else
--              list_add_rcu(&rule->list, ops->rules_list);
--
--      notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
--      rules_ops_put(ops);
--      return 0;
--
--errout_free:
--      kfree(rule);
--errout:
--      rules_ops_put(ops);
--      return err;
--}
--
--int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
--{
--      struct fib_rule_hdr *frh = nlmsg_data(nlh);
--      struct fib_rules_ops *ops = NULL;
--      struct fib_rule *rule;
--      struct nlattr *tb[FRA_MAX+1];
--      int err = -EINVAL;
--
--      if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
--              goto errout;
--
--      ops = lookup_rules_ops(frh->family);
--      if (ops == NULL) {
--              err = EAFNOSUPPORT;
--              goto errout;
--      }
--
--      err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy);
--      if (err < 0)
--              goto errout;
--
--      list_for_each_entry(rule, ops->rules_list, list) {
--              if (frh->action && (frh->action != rule->action))
--                      continue;
--
--              if (frh->table && (frh_get_table(frh, tb) != rule->table))
--                      continue;
--
--              if (tb[FRA_PRIORITY] &&
--                  (rule->pref != nla_get_u32(tb[FRA_PRIORITY])))
--                      continue;
--
--              if (tb[FRA_IFNAME] &&
--                  nla_strcmp(tb[FRA_IFNAME], rule->ifname))
--                      continue;
--
--              if (tb[FRA_FWMARK] &&
--                  (rule->mark != nla_get_u32(tb[FRA_FWMARK])))
--                      continue;
--
--              if (tb[FRA_FWMASK] &&
--                  (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
--                      continue;
--
--              if (!ops->compare(rule, frh, tb))
--                      continue;
--
--              if (rule->flags & FIB_RULE_PERMANENT) {
--                      err = -EPERM;
--                      goto errout;
--              }
--
--              list_del_rcu(&rule->list);
--              synchronize_rcu();
--              notify_rule_change(RTM_DELRULE, rule, ops, nlh,
--                                 NETLINK_CB(skb).pid);
--              fib_rule_put(rule);
--              rules_ops_put(ops);
--              return 0;
--      }
--
--      err = -ENOENT;
--errout:
--      rules_ops_put(ops);
--      return err;
--}
--
--static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
--                                       struct fib_rule *rule)
--{
--      size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr))
--                       + nla_total_size(IFNAMSIZ) /* FRA_IFNAME */
--                       + nla_total_size(4) /* FRA_PRIORITY */
--                       + nla_total_size(4) /* FRA_TABLE */
--                       + nla_total_size(4) /* FRA_FWMARK */
--                       + nla_total_size(4); /* FRA_FWMASK */
--
--      if (ops->nlmsg_payload)
--              payload += ops->nlmsg_payload(rule);
--
--      return payload;
--}
--
--static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
--                          u32 pid, u32 seq, int type, int flags,
--                          struct fib_rules_ops *ops)
--{
--      struct nlmsghdr *nlh;
--      struct fib_rule_hdr *frh;
--
--      nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags);
--      if (nlh == NULL)
--              return -1;
--
--      frh = nlmsg_data(nlh);
--      frh->table = rule->table;
--      NLA_PUT_U32(skb, FRA_TABLE, rule->table);
--      frh->res1 = 0;
--      frh->res2 = 0;
--      frh->action = rule->action;
--      frh->flags = rule->flags;
--
--      if (rule->ifname[0])
--              NLA_PUT_STRING(skb, FRA_IFNAME, rule->ifname);
--
--      if (rule->pref)
--              NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
--
--      if (rule->mark)
--              NLA_PUT_U32(skb, FRA_FWMARK, rule->mark);
--
--      if (rule->mark_mask || rule->mark)
--              NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask);
--
--      if (ops->fill(rule, skb, nlh, frh) < 0)
--              goto nla_put_failure;
--
--      return nlmsg_end(skb, nlh);
--
--nla_put_failure:
--      return nlmsg_cancel(skb, nlh);
--}
--
--int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
--{
--      int idx = 0;
--      struct fib_rule *rule;
--      struct fib_rules_ops *ops;
--
--      ops = lookup_rules_ops(family);
--      if (ops == NULL)
--              return -EAFNOSUPPORT;
--
--      rcu_read_lock();
--      list_for_each_entry(rule, ops->rules_list, list) {
--              if (idx < cb->args[0])
--                      goto skip;
--
--              if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid,
--                                   cb->nlh->nlmsg_seq, RTM_NEWRULE,
--                                   NLM_F_MULTI, ops) < 0)
--                      break;
--skip:
--              idx++;
--      }
--      rcu_read_unlock();
--      cb->args[0] = idx;
--      rules_ops_put(ops);
--
--      return skb->len;
--}
--
--EXPORT_SYMBOL_GPL(fib_rules_dump);
--
--static void notify_rule_change(int event, struct fib_rule *rule,
--                             struct fib_rules_ops *ops, struct nlmsghdr *nlh,
--                             u32 pid)
--{
--      struct sk_buff *skb;
--      int err = -ENOBUFS;
--
--      skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL);
--      if (skb == NULL)
--              goto errout;
--
--      err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
--      /* failure implies BUG in fib_rule_nlmsg_size() */
--      BUG_ON(err < 0);
--
--      err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
--errout:
--      if (err < 0)
--              rtnl_set_sk_err(ops->nlgroup, err);
--}
--
--static void attach_rules(struct list_head *rules, struct net_device *dev)
--{
--      struct fib_rule *rule;
--
--      list_for_each_entry(rule, rules, list) {
--              if (rule->ifindex == -1 &&
--                  strcmp(dev->name, rule->ifname) == 0)
--                      rule->ifindex = dev->ifindex;
--      }
--}
--
--static void detach_rules(struct list_head *rules, struct net_device *dev)
--{
--      struct fib_rule *rule;
--
--      list_for_each_entry(rule, rules, list)
--              if (rule->ifindex == dev->ifindex)
--                      rule->ifindex = -1;
--}
--
--
--static int fib_rules_event(struct notifier_block *this, unsigned long event,
--                          void *ptr)
--{
--      struct net_device *dev = ptr;
--      struct fib_rules_ops *ops;
--
--      ASSERT_RTNL();
--      rcu_read_lock();
--
--      switch (event) {
--      case NETDEV_REGISTER:
--              list_for_each_entry(ops, &rules_ops, list)
--                      attach_rules(ops->rules_list, dev);
--              break;
--
--      case NETDEV_UNREGISTER:
--              list_for_each_entry(ops, &rules_ops, list)
--                      detach_rules(ops->rules_list, dev);
--              break;
--      }
--
--      rcu_read_unlock();
--
--      return NOTIFY_DONE;
--}
--
--static struct notifier_block fib_rules_notifier = {
--      .notifier_call = fib_rules_event,
--};
--
--static int __init fib_rules_init(void)
--{
--      return register_netdevice_notifier(&fib_rules_notifier);
--}
--
--subsys_initcall(fib_rules_init);
-diff -Nauprw linux-2.6.20/net/core/netpoll.c ../new/linux-2.6.20/net/core/netpoll.c
---- linux-2.6.20/net/core/netpoll.c    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/net/core/netpoll.c     2007-11-21 11:51:42.000000000 +0530
-@@ -491,7 +491,10 @@ int __netpoll_rx(struct sk_buff *skb)
+--- linux-2.6.20.orig/net/core/netpoll.c
++++ linux-2.6.20/net/core/netpoll.c
+@@ -496,11 +496,14 @@ int __netpoll_rx(struct sk_buff *skb)
+       if (np->local_port && np->local_port != ntohs(uh->dest))
+               goto out;
  
        np->rx_hook(np, ntohs(uh->source),
                    (char *)(uh+1),
@@ -243356,10 +244089,13 @@ diff -Nauprw linux-2.6.20/net/core/netpoll.c ../new/linux-2.6.20/net/core/netpol
  
        kfree_skb(skb);
        return 1;
-diff -Nauprw linux-2.6.20/net/sunrpc/xprtsock.c ../new/linux-2.6.20/net/sunrpc/xprtsock.c
---- linux-2.6.20/net/sunrpc/xprtsock.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/net/sunrpc/xprtsock.c  2007-11-21 11:51:42.000000000 +0530
-@@ -1612,8 +1612,9 @@ struct rpc_xprt *xs_setup_tcp(struct soc
+ out:
+--- linux-2.6.20.orig/net/sunrpc/xprtsock.c
++++ linux-2.6.20/net/sunrpc/xprtsock.c
+@@ -1610,12 +1610,13 @@ struct rpc_xprt *xs_setup_tcp(struct soc
+       xprt->ops = &xs_tcp_ops;
  
        if (to)
                xprt->timeout = *to;
@@ -243371,9 +244107,40 @@ diff -Nauprw linux-2.6.20/net/sunrpc/xprtsock.c ../new/linux-2.6.20/net/sunrpc/x
  
        xs_format_peer_addresses(xprt);
        dprintk("RPC:      set up transport to address %s\n",
-diff -Nauprw linux-2.6.20/scripts/dwarfh.awk ../new/linux-2.6.20/scripts/dwarfh.awk
---- linux-2.6.20/scripts/dwarfh.awk    1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/dwarfh.awk     2007-11-21 11:51:42.000000000 +0530
+                       xprt->address_strings[RPC_DISPLAY_ALL]);
+--- linux-2.6.20.orig/scripts/Makefile
++++ linux-2.6.20/scripts/Makefile
+@@ -18,8 +18,9 @@ always               := $(hostprogs-y) $(hostprogs-m)
+ # The following hostprogs-y programs are only build on demand
+ hostprogs-y += unifdef
+ subdir-$(CONFIG_MODVERSIONS) += genksyms
+ subdir-y                     += mod
++subdir-$(CONFIG_LKM_HASH)    += ksymhash
+ # Let clean descend into subdirs
+ subdir-       += basic kconfig package
+--- linux-2.6.20.orig/scripts/Makefile.modpost
++++ linux-2.6.20/scripts/Makefile.modpost
+@@ -97,13 +97,15 @@ targets += $(modules:.ko=.mod.o)
+ # Step 6), final link of the modules
+ quiet_cmd_ld_ko_o = LD [M]  $@
+       cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@          \
+                         $(filter-out FORCE,$^)
++include $(srctree)/scripts/ksymhash/Makefile
+ $(modules): %.ko :%.o %.mod.o FORCE
+       $(call if_changed,ld_ko_o)
++      $(rule_ksymhash)
+ targets += $(modules)
+ # Add FORCE to the prequisites of a target to force it to be always rebuilt.
+--- /dev/null
++++ linux-2.6.20/scripts/dwarfh.awk
 @@ -0,0 +1,19 @@
 +BEGIN {
 +      print "#ifndef  _ELF_DWARF_H"
@@ -243394,10 +244161,11 @@ diff -Nauprw linux-2.6.20/scripts/dwarfh.awk ../new/linux-2.6.20/scripts/dwarfh.
 +END {
 +      print "#endif"
 +}
-diff -Nauprw linux-2.6.20/scripts/kconfig/Makefile ../new/linux-2.6.20/scripts/kconfig/Makefile
---- linux-2.6.20/scripts/kconfig/Makefile      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/kconfig/Makefile       2007-11-21 11:51:42.000000000 +0530
-@@ -4,22 +4,30 @@
+--- linux-2.6.20.orig/scripts/kconfig/Makefile
++++ linux-2.6.20/scripts/kconfig/Makefile
+@@ -2,26 +2,34 @@
+ # Kernel configuration targets
+ # These targets are used from top-level makefile
  
  PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
  
@@ -243434,7 +244202,11 @@ diff -Nauprw linux-2.6.20/scripts/kconfig/Makefile ../new/linux-2.6.20/scripts/k
        $< -s arch/$(ARCH)/Kconfig
  
  update-po-config: $(obj)/kxgettext
-@@ -43,19 +51,19 @@ update-po-config: $(obj)/kxgettext
+       xgettext --default-domain=linux \
+           --add-comments --keyword=_ --keyword=N_ \
+@@ -41,31 +49,31 @@ update-po-config: $(obj)/kxgettext
+       $(Q)rm -f arch/um/Kconfig_arch
+       $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot
  
  PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
  
@@ -243455,11 +244227,11 @@ diff -Nauprw linux-2.6.20/scripts/kconfig/Makefile ../new/linux-2.6.20/scripts/k
        $< -m arch/$(ARCH)/Kconfig
  
 -defconfig: $(obj)/conf
-+defconfig: $(obj)/conf machconfig 
++defconfig: $(obj)/conf machconfig
  ifeq ($(KBUILD_DEFCONFIG),)
        $< -d arch/$(ARCH)/Kconfig
  else
-@@ -63,7 +71,7 @@ else
+       @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)'
        $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig
  endif
  
@@ -243468,9 +244240,48 @@ diff -Nauprw linux-2.6.20/scripts/kconfig/Makefile ../new/linux-2.6.20/scripts/k
        $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig
  
  # Help text used by make help
-diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/ksymhash/elflib.c
---- linux-2.6.20/scripts/ksymhash/elflib.c     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/elflib.c      2008-10-20 13:38:35.000000000 +0530
+ help:
+       @echo  '  config          - Update current config utilising a line-oriented program'
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/Makefile
+@@ -0,0 +1,35 @@
++# Shared between Makefile and Makefile.modpost
++
++hostprogs-y           += ksymhash mk_elfconfig
++always                        := $(hostprogs-y) empty.o
++
++ksymhash-objs := ksymhash.o elflib.o
++
++# dependencies on generated files need to be listed explicitly
++
++$(obj)/ksymhash.o : $(obj)/elflib.o
++$(obj)/elflib.o   : $(obj)/elfconfig.h
++
++quiet_cmd_elfconfig = MKELF   $@
++      cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
++
++$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
++      $(call if_changed,elfconfig)
++
++targets += elfconfig.h
++
++# Post-process vmlinux image to populate ksymtabs with GNU hash values
++
++quiet_cmd_ksymhash = SYMHASH
++      cmd_ksymhash = scripts/ksymhash/ksymhash
++
++ifdef CONFIG_LKM_HASH
++define rule_ksymhash
++      $(Q)$(if $($(quiet)cmd_ksymhash),                                                               \
++              echo '  $($(quiet)cmd_ksymhash) $@' &&)                                         \
++      $(cmd_ksymhash) $@
++endef
++else
++define rule_ksymhash
++endef
++endif
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/elflib.c
 @@ -0,0 +1,164 @@
 +#include "elflib.h"
 +
@@ -243514,7 +244325,7 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/
 +static inline void set_ksymtable(struct elf_info *info, enum ksymtab_type type, \
 +                                      Elf_Ehdr *hdr, Elf_Shdr *sechdrs, unsigned int secidx, \
 +                                      const char *secname) {
-+                                      
++
 +      info->ksym_tables[type].start = (struct kernel_symbol *) ((void *) hdr + sechdrs[secidx].sh_offset);
 +      info->ksym_tables[type].stop = (struct kernel_symbol *) ((void *) hdr + sechdrs[secidx].sh_offset + sechdrs[secidx].sh_size);
 +      info->ksym_tables[type].name = strdup(secname);
@@ -243547,8 +244358,8 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/
 +              /* Not an ELF file - silently ignore it */
 +              return 0;
 +      }
-+      
-+      /* Check if it is the vmlinux or lkm */ 
++
++      /* Check if it is the vmlinux or lkm */
 +      if((lkm_suffix = strstr(filename,".ko")) && (strlen(lkm_suffix) == 3))
 +              /* Likely this is a lkm */
 +              info->is_lkm = 1;
@@ -243556,7 +244367,7 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/
 +              info->is_lkm = 0;
 +              /* Don't care */
 +              info->base_addr = 0;
-+      }               
++      }
 +
 +      /* Fix endianness in ELF header */
 +      hdr->e_shoff    = TO_NATIVE(hdr->e_shoff);
@@ -243588,10 +244399,10 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/
 +                      return 0;
 +              }
 +              secname = secstrings + sechdrs[i].sh_name;
-+              
++
 +              if (strcmp(secname, ".text") == 0)
 +                      info->base_addr = sechdrs[i].sh_addr - sechdrs[i].sh_offset;
-+              
++
 +              if (strcmp(secname, "__ksymtab") == 0)
 +                      set_ksymtable(info, KSYMTAB, hdr, sechdrs, i, secname);
 +              else if (strcmp(secname, "__ksymtab_unused") == 0)
@@ -243636,9 +244447,8 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.c ../new/linux-2.6.20/scripts/
 +}
 +
 +
-diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/ksymhash/elflib.h
---- linux-2.6.20/scripts/ksymhash/elflib.h     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/elflib.h      2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/elflib.h
 @@ -0,0 +1,142 @@
 +#include <sys/stat.h>
 +#include <elf.h>
@@ -243728,7 +244538,7 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/
 +      __ksymtab_gpl_future
 +                      and
 +       __ksymtab_strings
-+*/     
++*/
 +
 +enum ksymtab_type {
 +      KSYMTAB = 0,
@@ -243756,7 +244566,7 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/
 +      unsigned long size;
 +      Elf_Ehdr     *hdr;
 +      Elf_Shdr     *sechdrs;
-+      
++
 +      unsigned char is_lkm;
 +      unsigned long base_addr;
 +      unsigned int unresolved;
@@ -243764,12 +244574,12 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/
 +              Elf_Sym *start;
 +              Elf_Sym *stop;
 +      } symtab;
-+      
++
 +      struct {
 +              ksym_hash_t *start;
 +              ksym_hash_t *stop;
 +      } symtab_hash;
-+              
++
 +      struct kernel_symtab ksym_tables[KSYMTAB_ALL];
 +      const char   *strtab;
 +      const char   *kstrings;
@@ -243782,23 +244592,21 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/elflib.h ../new/linux-2.6.20/scripts/
 +void parse_elf_finish(struct elf_info *info);
 +
 +
-diff -Nauprw linux-2.6.20/scripts/ksymhash/empty.c ../new/linux-2.6.20/scripts/ksymhash/empty.c
---- linux-2.6.20/scripts/ksymhash/empty.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/empty.c       2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/empty.c
 @@ -0,0 +1 @@
 +/* empty file to figure out endianness / word size */
-diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/scripts/ksymhash/ksymhash.c
---- linux-2.6.20/scripts/ksymhash/ksymhash.c   1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/ksymhash.c    2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/ksymhash.c
 @@ -0,0 +1,126 @@
 +/*
 + * Copyright STMicroelectronics Ltd (2008)
-+ * 
++ *
 + * Author: Carmelo Amoroso <carmelo.amoroso@st.com>
 + *
 + *
 + */
-+ 
++
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <unistd.h>
@@ -243816,10 +244624,10 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/script
 +#else
 +#define debug(__msg...) /* nothing */
 +/*#define dump_ksym(__ksym, __kstr)  nothing */
-+#endif        
++#endif
 +
 +#define dump_undef(__undef, __hash) debug("\tUnresolved: %s\thash = 0x%lx\n", __undef, __hash)
-+#define dump_ksym(__ksym, __kstr)   debug("\tExported: %s\thash = 0x%x\n", __kstr, __ksym->hash_value)        
++#define dump_ksym(__ksym, __kstr)   debug("\tExported: %s\thash = 0x%x\n", __kstr, __ksym->hash_value)
 +
 +static ksym_hash_t gnu_hash (const unsigned char *name) {
 +      ksym_hash_t h = 5381;
@@ -243834,7 +244642,7 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/script
 +
 +      struct kernel_symbol * sym;
 +      long s_offset;
-+      
++
 +      if(elf->is_lkm) {
 +              /*
 +               * ksym->name is an offset with respect to the start of the
@@ -243842,13 +244650,13 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/script
 +               */
 +              s_offset = (long) elf->kstrings;
 +      } else {
-+              /*      
++              /*
 +               * In this case, ksym->name is the absolute value of the string into
 +               * the __ksymtab_strings
 +               */
 +               s_offset = (long)elf->hdr - (long)elf->base_addr;
-+      }       
-+      
++      }
++
 +      for(sym = elf->ksym_tables[tp].start; sym < elf->ksym_tables[tp].stop; sym++) {
 +              sym->hash_value = gnu_hash(GET_KSTRING(sym, s_offset));
 +              dump_ksym(sym, GET_KSTRING(sym, s_offset));
@@ -243860,7 +244668,7 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/script
 +      Elf_Sym *sym;
 +      unsigned int undef = 0;
 +      ksym_hash_t* hash_values = elf->symtab_hash.start;
-+      
++
 +      if(elf->is_lkm) {
 +              for(sym = elf->symtab.start; sym < elf->symtab.stop; sym++) {
 +                      if(sym->st_shndx == SHN_UNDEF) {
@@ -243877,88 +244685,48 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/ksymhash.c ../new/linux-2.6.20/script
 +                                      */
 +                                      hash_values++;
 +                                      undef++;
-+                              }                               
-+                      }                               
++                              }
++                      }
 +              }
 +      }
 +      elf->unresolved = undef;
-+}     
++}
 +
 +
 +int main(int argc, char **argv) {
 +
 +      enum ksymtab_type k;
 +      struct elf_info info = { };
-+              
++
 +      if (!parse_elf(&info, argv[1])) {
 +              exit(1);
-+      }       
-+      
++      }
++
 +      /* Skip __ksymtab_strings and __ksymtab.hash*/
 +      debug("--------------------------------------------------------------------------------\n");
 +      for(k=KSYMTAB; k < KSYMTAB_ALL; k++) {
 +
 +              if(info.ksym_tables[k].name) {
-+                      
-+                      /* Compute hash value for exported symbols */                                           
++
++                      /* Compute hash value for exported symbols */
 +                      compute_exported_hash(&info, k);
-+                      
-+                      debug("ktable: %s [exported: %u]\n", 
-+                                      info.ksym_tables[k].name, info.ksym_tables[k].entries);                                 
++
++                      debug("ktable: %s [exported: %u]\n",
++                                      info.ksym_tables[k].name, info.ksym_tables[k].entries);
 +              }
-+      }                                       
++      }
 +      debug("--------------------------------------------------------------------------------\n");
 +
 +      compute_unresolved_hash(&info);
 +      debug("Module: %s [unresolved: %u]\n", argv[1], info.unresolved);
 +      debug("--------------------------------------------------------------------------------\n");
-+      
++
 +
 +      parse_elf_finish(&info);
 +      return 0;
 +}
-diff -Nauprw linux-2.6.20/scripts/ksymhash/Makefile ../new/linux-2.6.20/scripts/ksymhash/Makefile
---- linux-2.6.20/scripts/ksymhash/Makefile     1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/Makefile      2008-10-20 13:38:35.000000000 +0530
-@@ -0,0 +1,35 @@
-+# Shared between Makefile and Makefile.modpost
-+
-+hostprogs-y           += ksymhash mk_elfconfig
-+always                        := $(hostprogs-y) empty.o
-+
-+ksymhash-objs := ksymhash.o elflib.o
-+
-+# dependencies on generated files need to be listed explicitly
-+
-+$(obj)/ksymhash.o : $(obj)/elflib.o
-+$(obj)/elflib.o   : $(obj)/elfconfig.h
-+
-+quiet_cmd_elfconfig = MKELF   $@
-+      cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
-+
-+$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
-+      $(call if_changed,elfconfig)
-+
-+targets += elfconfig.h 
-+
-+# Post-process vmlinux image to populate ksymtabs with GNU hash values
-+
-+quiet_cmd_ksymhash = SYMHASH
-+      cmd_ksymhash = scripts/ksymhash/ksymhash
-+
-+ifdef CONFIG_LKM_HASH
-+define rule_ksymhash
-+      $(Q)$(if $($(quiet)cmd_ksymhash),                                                               \
-+              echo '  $($(quiet)cmd_ksymhash) $@' &&)                                         \
-+      $(cmd_ksymhash) $@
-+endef
-+else
-+define rule_ksymhash
-+endef 
-+endif
-diff -Nauprw linux-2.6.20/scripts/ksymhash/mk_elfconfig.c ../new/linux-2.6.20/scripts/ksymhash/mk_elfconfig.c
---- linux-2.6.20/scripts/ksymhash/mk_elfconfig.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/ksymhash/mk_elfconfig.c        2008-10-20 13:38:35.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/scripts/ksymhash/mk_elfconfig.c
 @@ -0,0 +1,66 @@
 +#include <stdio.h>
 +#include <stdlib.h>
@@ -244026,36 +244794,11 @@ diff -Nauprw linux-2.6.20/scripts/ksymhash/mk_elfconfig.c ../new/linux-2.6.20/sc
 +      return 0;
 +}
 +
-diff -Nauprw linux-2.6.20/scripts/Makefile ../new/linux-2.6.20/scripts/Makefile
---- linux-2.6.20/scripts/Makefile      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/Makefile       2008-10-20 13:37:46.000000000 +0530
-@@ -20,6 +20,7 @@ hostprogs-y += unifdef
- subdir-$(CONFIG_MODVERSIONS) += genksyms
- subdir-y                     += mod
-+subdir-$(CONFIG_LKM_HASH)    += ksymhash
- # Let clean descend into subdirs
- subdir-       += basic kconfig package
-diff -Nauprw linux-2.6.20/scripts/Makefile.modpost ../new/linux-2.6.20/scripts/Makefile.modpost
---- linux-2.6.20/scripts/Makefile.modpost      2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/Makefile.modpost       2008-10-20 13:37:46.000000000 +0530
-@@ -99,9 +99,11 @@ targets += $(modules:.ko=.mod.o)
- quiet_cmd_ld_ko_o = LD [M]  $@
-       cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@          \
-                         $(filter-out FORCE,$^)
-+include $(srctree)/scripts/ksymhash/Makefile
- $(modules): %.ko :%.o %.mod.o FORCE
-       $(call if_changed,ld_ko_o)
-+      $(rule_ksymhash)
- targets += $(modules)
-diff -Nauprw linux-2.6.20/scripts/mod/modpost.c ../new/linux-2.6.20/scripts/mod/modpost.c
---- linux-2.6.20/scripts/mod/modpost.c 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/scripts/mod/modpost.c  2008-10-20 13:37:47.000000000 +0530
-@@ -1311,6 +1311,28 @@ static void add_srcversion(struct buffer
+--- linux-2.6.20.orig/scripts/mod/modpost.c
++++ linux-2.6.20/scripts/mod/modpost.c
+@@ -1309,10 +1309,32 @@ static void add_srcversion(struct buffer
+               buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
+                          mod->srcversion);
        }
  }
  
@@ -244074,7 +244817,7 @@ diff -Nauprw linux-2.6.20/scripts/mod/modpost.c ../new/linux-2.6.20/scripts/mod/
 +      for (s = mod->unres; s; s = s->next) {
 +              /* Fill with zero, the order of unresolved symbol is not yet correct
 +                 This will create a placeholder for the hash values
-+               */ 
++               */
 +              buf_printf(b, "\t%#8lx,\n", 0L);
 +      }
 +      buf_printf(b, "};\n");
@@ -244084,7 +244827,11 @@ diff -Nauprw linux-2.6.20/scripts/mod/modpost.c ../new/linux-2.6.20/scripts/mod/
  static void write_if_changed(struct buffer *b, const char *fname)
  {
        char *tmp;
-@@ -1502,6 +1524,7 @@ int main(int argc, char **argv)
+       FILE *file;
+       struct stat st;
+@@ -1500,10 +1522,11 @@ int main(int argc, char **argv)
+               add_header(&buf, mod);
+               err |= add_versions(&buf, mod);
                add_depends(&buf, mod, modules);
                add_moddevtable(&buf, mod);
                add_srcversion(&buf, mod);
@@ -244092,10 +244839,100 @@ diff -Nauprw linux-2.6.20/scripts/mod/modpost.c ../new/linux-2.6.20/scripts/mod/
  
                sprintf(fname, "%s.mod.c", mod->name);
                write_if_changed(&buf, fname);
-diff -Nauprw linux-2.6.20/sound/arm/Kconfig ../new/linux-2.6.20/sound/arm/Kconfig
---- linux-2.6.20/sound/arm/Kconfig     2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/sound/arm/Kconfig      2007-11-21 11:51:42.000000000 +0530
-@@ -3,6 +3,17 @@
+       }
+--- linux-2.6.20.orig/sound/Kconfig
++++ linux-2.6.20/sound/Kconfig
+@@ -1,10 +1,44 @@
+ # sound/Config.in
+ #
+ menu "Sound"
++# added for nomadik audio codec device
++
++config NOMADIK_ACODEC
++      tristate "Nomadik audio codec generic module (used both by SAA and ALSA)"
++      depends on ARCH_NOMADIK && NOMADIK_MSP && I2C_NOMADIK
++      help
++        Say Y here if you have a nomadik based device
++        and want to use its audio codec chip.
++
++        To compile this driver as a module, choose M here: the module
++        will be called nmdkmod_acodec.
++
++choice
++      prompt "audio codec type"
++      depends on NOMADIK_ACODEC
++      default NOMADIK_STW5095
++
++config NOMADIK_STW5094
++      bool "Nomadik stw5094 audio codec"
++
++config NOMADIK_STW5095
++      bool "Nomadik stw5095 audio codec"
++
++endchoice
++
++#configure audio codec to provide msp clock and frame sync
++config DA_MASTER
++      bool "Set stw5095 clock as bit clock"
++      depends on NOMADIK_STW5095
++#     default y
++      help
++         Say Y here if you wish to use the stw5095's audio clock as
++         the bit clock instead of the less accurate msp clock.
++
+ config SOUND
+       tristate "Sound card support"
+       help
+         If you have a sound card in your computer, i.e. if it can say more
+         than an occasional beep, say Y.  Be sure to have all the information
+@@ -34,10 +68,12 @@ config SOUND
+ source "sound/oss/dmasound/Kconfig"
+ if !M68K
++
++
+ menu "Advanced Linux Sound Architecture"
+       depends on SOUND!=n
+ config SND
+       tristate "Advanced Linux Sound Architecture"
+--- linux-2.6.20.orig/sound/Makefile
++++ linux-2.6.20/sound/Makefile
+@@ -1,8 +1,9 @@
+ # Makefile for the Linux sound card driver
+ #
++obj-$(CONFIG_NOMADIK_ACODEC) += nmdkmod_acodec.o
+ obj-$(CONFIG_SOUND) += soundcore.o
+ obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
+ obj-$(CONFIG_SOUND_PRIME) += oss/
+ obj-$(CONFIG_DMASOUND) += oss/
+ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
+@@ -13,6 +14,14 @@ obj-$(CONFIG_AC97_BUS) += ac97_bus.o
+ ifeq ($(CONFIG_SND),y)
+   obj-y += last.o
+ endif
++ifeq ($(CONFIG_NOMADIK_STW5094),y)
++nmdkmod_acodec-objs := nomadik_stw5094.o
++endif
++
++ifeq ($(CONFIG_NOMADIK_STW5095),y)
++nmdkmod_acodec-objs := nomadik_stw5095.o
++endif
++
+ soundcore-objs  := sound_core.o
+--- linux-2.6.20.orig/sound/arm/Kconfig
++++ linux-2.6.20/sound/arm/Kconfig
+@@ -1,10 +1,21 @@
+ # ALSA ARM drivers
  menu "ALSA ARM devices"
        depends on SND!=n && ARM
  
@@ -244113,19 +244950,21 @@ diff -Nauprw linux-2.6.20/sound/arm/Kconfig ../new/linux-2.6.20/sound/arm/Kconfi
  config SND_SA11XX_UDA1341
        tristate "SA11xx UDA1341TS driver (iPaq H3600)"
        depends on ARCH_SA1100 && SND && L3
-diff -Nauprw linux-2.6.20/sound/arm/Makefile ../new/linux-2.6.20/sound/arm/Makefile
---- linux-2.6.20/sound/arm/Makefile    2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/sound/arm/Makefile     2007-11-21 11:51:42.000000000 +0530
-@@ -13,3 +13,6 @@ snd-pxa2xx-pcm-objs          := pxa2xx-pcm.o
+       select SND_PCM
+       help
+--- linux-2.6.20.orig/sound/arm/Makefile
++++ linux-2.6.20/sound/arm/Makefile
+@@ -11,5 +11,8 @@ snd-aaci-objs                        := aaci.o devdma.o
+ obj-$(CONFIG_SND_PXA2XX_PCM)  += snd-pxa2xx-pcm.o
+ snd-pxa2xx-pcm-objs           := pxa2xx-pcm.o
  
  obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o
  snd-pxa2xx-ac97-objs          := pxa2xx-ac97.o
 +
 +obj-$(CONFIG_SND_NOMADIK_ALSA)  += nmdkmod_alsa.o
 +nmdkmod_alsa-objs             := nomadik_alsa.o devdma.o
-diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.c ../new/linux-2.6.20/sound/arm/nomadik_alsa.c
---- linux-2.6.20/sound/arm/nomadik_alsa.c      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/sound/arm/nomadik_alsa.c       2008-11-24 14:06:29.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/sound/arm/nomadik_alsa.c
 @@ -0,0 +1,1038 @@
 +/* sound/arm/nomadik_alsa.c
 + *
@@ -245165,15 +246004,14 @@ diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.c ../new/linux-2.6.20/sound/arm
 +MODULE_AUTHOR("David Siorpaes, Emanele Placidi, Abhijit Singh");
 +MODULE_LICENSE("GPL");
 +MODULE_DESCRIPTION("Nomadik ALSA driver");
-diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.h ../new/linux-2.6.20/sound/arm/nomadik_alsa.h
---- linux-2.6.20/sound/arm/nomadik_alsa.h      1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/sound/arm/nomadik_alsa.h       2007-11-21 11:51:42.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/sound/arm/nomadik_alsa.h
 @@ -0,0 +1,83 @@
-+/* sound/arm/nomadik_alsa.c 
-+ * 
++/* sound/arm/nomadik_alsa.c
++ *
 + * Header file for nomadik alsa driver
 + * Author: David Siorpaes, Emanele Placidi, Abhijit Singh
-+ * 
++ *
 + * 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
@@ -245252,91 +246090,13 @@ diff -Nauprw linux-2.6.20/sound/arm/nomadik_alsa.h ../new/linux-2.6.20/sound/arm
 +
 +
 +#endif
-diff -Nauprw linux-2.6.20/sound/Kconfig ../new/linux-2.6.20/sound/Kconfig
---- linux-2.6.20/sound/Kconfig 2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/sound/Kconfig  2008-11-19 16:47:04.000000000 +0530
-@@ -3,6 +3,40 @@
- menu "Sound"
-+# added for nomadik audio codec device
-+
-+config NOMADIK_ACODEC
-+      tristate "Nomadik audio codec generic module (used both by SAA and ALSA)"
-+      depends on ARCH_NOMADIK && NOMADIK_MSP && I2C_NOMADIK
-+      help
-+        Say Y here if you have a nomadik based device
-+        and want to use its audio codec chip.
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called nmdkmod_acodec.
-+
-+choice 
-+      prompt "audio codec type" 
-+      depends on NOMADIK_ACODEC
-+      default NOMADIK_STW5095
-+
-+config NOMADIK_STW5094
-+      bool "Nomadik stw5094 audio codec"
-+
-+config NOMADIK_STW5095
-+      bool "Nomadik stw5095 audio codec"
-+
-+endchoice
-+
-+#configure audio codec to provide msp clock and frame sync
-+config DA_MASTER
-+      bool "Set stw5095 clock as bit clock"
-+      depends on NOMADIK_STW5095
-+#     default y 
-+      help
-+         Say Y here if you wish to use the stw5095's audio clock as
-+         the bit clock instead of the less accurate msp clock.
-+ 
- config SOUND
-       tristate "Sound card support"
-       help
-@@ -36,6 +70,8 @@ source "sound/oss/dmasound/Kconfig"
- if !M68K
-+
-+
- menu "Advanced Linux Sound Architecture"
-       depends on SOUND!=n
-diff -Nauprw linux-2.6.20/sound/Makefile ../new/linux-2.6.20/sound/Makefile
---- linux-2.6.20/sound/Makefile        2007-02-05 00:14:54.000000000 +0530
-+++ ../new/linux-2.6.20/sound/Makefile 2007-11-21 11:51:42.000000000 +0530
-@@ -1,6 +1,7 @@
- # Makefile for the Linux sound card driver
- #
-+obj-$(CONFIG_NOMADIK_ACODEC) += nmdkmod_acodec.o
- obj-$(CONFIG_SOUND) += soundcore.o
- obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
- obj-$(CONFIG_SOUND_PRIME) += oss/
-@@ -15,4 +16,12 @@ ifeq ($(CONFIG_SND),y)
-   obj-y += last.o
- endif
-+ifeq ($(CONFIG_NOMADIK_STW5094),y)
-+nmdkmod_acodec-objs := nomadik_stw5094.o
-+endif
-+
-+ifeq ($(CONFIG_NOMADIK_STW5095),y)
-+nmdkmod_acodec-objs := nomadik_stw5095.o
-+endif
-+
- soundcore-objs  := sound_core.o
-diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/nomadik_stw5094.c
---- linux-2.6.20/sound/nomadik_stw5094.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/sound/nomadik_stw5094.c        2008-07-04 23:45:32.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/sound/nomadik_stw5094.c
 @@ -0,0 +1,2280 @@
-+/* sound/nomadik_stw5094.c 
-+ * 
++/* sound/nomadik_stw5094.c
++ *
 + * Contains STW5094 AudioCodec implementation
-+ * 
++ *
 + * 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
@@ -245354,7 +246114,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 + */
 +
 +/*-----------------------------------------------------------------------------
-+ * Common Includes                                   
++ * Common Includes
 + *---------------------------------------------------------------------------*/
 +
 +#include <linux/module.h>
@@ -245399,7 +246159,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +#define TRACE_EXIT(devname)  DEBUG(4, "%s: <- " __FUNCTION__ "()\n", devname);
 +
 +/*----------------------------------------------------------------------------
-+ * global declarations 
++ * global declarations
 + *---------------------------------------------------------------------------*/
 +
 +codec_configuration *nomadik_acodec_conf, *nomadik_acodec_defaultconf;
@@ -245412,7 +246172,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +
 +/**
 + * nomadik_acodec_set_user
-+ *                                      
++ *
 + * Set the current user for acodec.
 + */
 +
@@ -245433,7 +246193,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +
 +/**
 + * nomadik_acodec_unset_user
-+ *                                      
++ *
 + * Unset the current user for acodec.
 + */
 +
@@ -245446,22 +246206,22 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +                      ("ERROR : Trying to free audiocodec already in use by other user %d\n", g_cur_user);
 +              return CODEC_ERROR;
 +      }
-+      else 
++      else
 +              g_cur_user = NO_USER;
 +
 +      return (codec_error);
 +}
 +
 +/**
-+ * nomadik_acodec_init  
-+ *                                       
++ * nomadik_acodec_init
++ *
 + * This is the init function for STW5094 audiocodec driver.                            */
 +
 +static int __init nomadik_acodec_init(void)
 +{
 +      int error;
 +      /* default configuration for audiocodec
-+         -no argument in required in nomadik_acodec_init    
++         -no argument in required in nomadik_acodec_init
 +       */
 +      DEBUG(1, "  Entering nomadik_acodec_init\n");
 +
@@ -245529,8 +246289,8 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +
 +/**
 + * nomadik_acodec_deinit
-+ *                                        
-+ * exit function for STW5094 audiocodec driver. 
++ *
++ * exit function for STW5094 audiocodec driver.
 + */
 +static void __exit nomadik_acodec_deinit(void)
 +{
@@ -245561,16 +246321,16 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_enable_audio_mode                              
-+*                                                                            
-+* @direction - direction of data flow (from/to) audiocode                             
-+* @input_frequency - record direction    
-+* @output_frequency - playback direction 
-+* @mspClockSel - clock for MSP                     
++* nomadik_acodec_enable_audio_mode
++*
++* @direction - direction of data flow (from/to) audiocode
++* @input_frequency - record direction
++* @output_frequency - playback direction
++* @mspClockSel - clock for MSP
 +* @mspInClockFreq - input clock for MSP
-+*                                                                           
-+* It configures the audiocodec in audio mode. In this case,the I2S 
-+* protocol is used for data exchanges.                
++*
++* It configures the audiocodec in audio mode. In this case,the I2S
++* protocol is used for data exchanges.
 +*/
 +
 +t_codec_error nomadik_acodec_enable_audio_mode(t_codec_direction direction,
@@ -245794,16 +246554,16 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_enable_voice_mode                              
-+*                                                                            
-+* @direction - direction of data flow (from/to) audiocode                               
-+* @input_frequency - record direction    
-+* @output_frequency - playback direction 
-+* @mspClockSel - clock for MSP                                                           
++* nomadik_acodec_enable_voice_mode
++*
++* @direction - direction of data flow (from/to) audiocode
++* @input_frequency - record direction
++* @output_frequency - playback direction
++* @mspClockSel - clock for MSP
 +* @mspInClockFreq - input clock for MSP
-+*                                                                           
-+* It configures the audiocodec in audio mode. In this case,the PCM 
-+* protocol is used for data exchanges.                
++*
++* It configures the audiocodec in audio mode. In this case,the PCM
++* protocol is used for data exchanges.
 +*/
 +t_codec_error nomadik_acodec_enable_voice_mode(t_codec_direction direction,
 +                                             t_codec_sample_frequency
@@ -245880,7 +246640,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +
 +      }
 +
-+      /* Configure the audio codec for voice mode 
++      /* Configure the audio codec for voice mode
 +         set the OCK clock frequency first */
 +      error_status = set_ock_frequency(freq);
 +      if (CODEC_NOT_SUPPORTED == error_status) {
@@ -246030,16 +246790,16 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_enable_tonegeneratormode             
-+ * @tone_gain - gain in db for tone generated      
-+ * @mix_with_record - mixing of tone with recording       
-+ * @mix_with_playback - mixing of tone with playback           
-+ * @waveShape - wave shape sin/square                  
-+ * @reserved2 - reserved for future use                           
++ * nomadik_acodec_enable_tonegeneratormode
++ * @tone_gain - gain in db for tone generated
++ * @mix_with_record - mixing of tone with recording
++ * @mix_with_playback - mixing of tone with playback
++ * @waveShape - wave shape sin/square
++ * @reserved2 - reserved for future use
 + *
-+ * It configures the audiocodec in tone mode. if mix with      
-+ * or record is TRUE then enable internal tone generator else             
-+ * set tone only mode nad disable audio or voice mode.                    
++ * It configures the audiocodec in tone mode. if mix with
++ * or record is TRUE then enable internal tone generator else
++ * set tone only mode nad disable audio or voice mode.
 + */
 +
 +t_codec_error nomadik_acodec_enable_tonegeneratormode(int tone_gain,
@@ -246160,9 +246920,9 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_disable_tonegeneratormode            
++ * nomadik_acodec_disable_tonegeneratormode
 + *
-+ * It disables the tonegeneration mode.                           
++ * It disables the tonegeneration mode.
 + */
 +t_codec_error nomadik_acodec_disable_tonegeneratormode(t_acodec_user user)
 +{
@@ -246207,10 +246967,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_play_singletone                         
-+ * @tone_frequency: single frequency to generate tone                     
-+ *                                                                          
-+ * It starts the single frequency tone generation                 
++ * nomadik_acodec_play_singletone
++ * @tone_frequency: single frequency to generate tone
++ *
++ * It starts the single frequency tone generation
 + */
 +t_codec_error nomadik_acodec_play_singletone(int toneFrequency, t_acodec_user user)
 +{
@@ -246251,11 +247011,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_play_dualtone                            
-+* @freqF1 - frequency f1 to generate tone                         
-+* @ferqF2 - frequemcy f2 to generate tone                         
++* nomadik_acodec_play_dualtone
++* @freqF1 - frequency f1 to generate tone
++* @ferqF2 - frequemcy f2 to generate tone
 +*
-+* It starts the DTMF tone generation                      
++* It starts the DTMF tone generation
 +*/
 +t_codec_error nomadik_acodec_play_dualtone(int freqF1, int freqF2, t_acodec_user user)
 +{
@@ -246307,8 +247067,8 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_stop_tone - stops the DTMF or single tone generatio                  
-+*/ 
++* nomadik_acodec_stop_tone - stops the DTMF or single tone generatio
++*/
 +t_codec_error nomadik_acodec_stop_tone(t_acodec_user user)
 +{
 +      t_codec_error error_status = CODEC_OK;
@@ -246337,11 +247097,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_set_volume - configures the volume level for both speakers                                  
-+* @in_left_volume - volume for left channel of mic           
-+* @in_right_volume - volume for right channel of mic           
-+* @out_left_volume - volume for left speaker              
-+* @out_right_volume - volume for right speaker                 
++* nomadik_acodec_set_volume - configures the volume level for both speakers
++* @in_left_volume - volume for left channel of mic
++* @in_right_volume - volume for right channel of mic
++* @out_left_volume - volume for left speaker
++* @out_right_volume - volume for right speaker
 +*/
 +t_codec_error nomadik_acodec_set_volume(int input_vol_left,
 +                                      int input_vol_right,
@@ -246411,7 +247171,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +                      }
 +
 +                      /* dont change the mic selected. just change the volume clear
-+                       * the lower 5 bits and set the volume as lsb 0 to 44.5db 
++                       * the lower 5 bits and set the volume as lsb 0 to 44.5db
 +                       */
 +                      data &= 0xE0;
 +                      if (ZERO == (data & 0xC0)) {
@@ -246527,11 +247287,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_powerdown                                    
-+* @flag - level of power down, 0 means complete power down     
++* nomadik_acodec_powerdown
++* @flag - level of power down, 0 means complete power down
 +*
 +* It sets the codec in power down mode. complete functionality
-+* will be achieved in power management                        
++* will be achieved in power management
 +*/
 +t_codec_error nomadik_acodec_powerdown(__u8 flag)
 +{
@@ -246566,11 +247326,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_powerup                                      
++* nomadik_acodec_powerup
 +*
-+* It sets the codec in power up mode. rest is left for power  
-+* management.                                             
-+*/                                                                          
++* It sets the codec in power up mode. rest is left for power
++* management.
++*/
 +t_codec_error nomadik_acodec_powerup(void)
 +{
 +      t_codec_error error_status;
@@ -246599,14 +247359,14 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+* nomadik_acodec_enable_bypassmode                                 
-+* @analog_frequency             
-+* @fm_gain - outside gain in the received audio signals    
-+* @mix_with_playback - true if user wants to mix tone with audio played back       
-+* @reserved1 - reserved for future use             
-+* @reserved2 - reserved for future use             
++* nomadik_acodec_enable_bypassmode
++* @analog_frequency
++* @fm_gain - outside gain in the received audio signals
++* @mix_with_playback - true if user wants to mix tone with audio played back
++* @reserved1 - reserved for future use
++* @reserved2 - reserved for future use
 +*
-+* Enables the bypass mode (Analog IN is routed to analog out.  
++* Enables the bypass mode (Analog IN is routed to analog out.
 +*/
 +t_codec_error nomadik_acodec_enable_bypassmode(t_codec_sample_frequency analog_frequency, __u8 fm_gain,                                      boolean mix_with_playback,
 +                                             u_long * reserved1,
@@ -246648,7 +247408,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +              if (error_status < 0) {
 +                      DEBUG(1, "  error in set i2s power off\n");
 +              }
-+      } else {                /* dont set audio or voice mode , use existing mode and set CR20 to sum 
++      } else {                /* dont set audio or voice mode , use existing mode and set CR20 to sum
 +                                 the fm signals with the output comming from audio or voice */
 +              error_status = nomadik_acodec_powerup();
 +              if (error_status < 0) {
@@ -246686,10 +247446,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_set_samplesize                                         
++ * nomadik_acodec_set_samplesize
 + * @codec_size: sample size in bits
 + *
-+ * This routine sets the sample size in bits.                              
++ * This routine sets the sample size in bits.
 + */
 +t_codec_error nomadik_acodec_set_samplesize(codec_input_bit_length codec_size, t_acodec_user user)
 +{
@@ -246727,11 +247487,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_set_no_of_channels                                     
++ * nomadik_acodec_set_no_of_channels
 + * @channels: mono or stereo
-+ *       
++ *
 + * This routine checks then sets the no of channels configured together
-+ * with mode.                              
++ * with mode.
 + */
 +t_codec_error nomadik_acodec_set_no_of_channels(t_codec_channel channels, t_acodec_user user)
 +{
@@ -246762,10 +247522,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_set_compand                                    
++ * nomadik_acodec_set_compand
 + * @compand_mode: Linear, A-law or Mu-Law
 + *
-+ * This routine sets the Companded mode for audiocodec                              
++ * This routine sets the Companded mode for audiocodec
 + */
 +t_codec_error nomadik_acodec_set_compand(codec_compand_mode compand_mode, t_acodec_user user)
 +{
@@ -246824,9 +247584,9 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_enable_datapath_errcb                                        
++ * nomadik_acodec_enable_datapath_errcb
 + *
-+ * This routine is not implemented yet                             
++ * This routine is not implemented yet
 + */
 +t_codec_error nomadik_acodec_enable_datapath_errcb(codec_callback *
 +                                                 call_back_fn, u_long * data, t_acodec_user user)
@@ -246835,10 +247595,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_set_dataformat                                         
++ * nomadik_acodec_set_dataformat
 + * @codec_dfmt: data format bit mask.
-+ *        
-+ * This routine sets the dtmf format.                              
++ *
++ * This routine sets the dtmf format.
 + */
 +t_codec_error nomadik_acodec_set_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user)
 +{
@@ -246864,10 +247624,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_get_dataformat                                         
++ * nomadik_acodec_get_dataformat
 + * @codec_dfmt: data format bit mask.
-+ *                                                                          
-+ * This routine gets the dtmf format as ser earlier .                               
++ *
++ * This routine gets the dtmf format as ser earlier .
 + */
 +t_codec_error nomadik_acodec_get_dataformat(codec_dfmt * codec_dfmt, t_acodec_user user)
 +{
@@ -246892,13 +247652,13 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_enable_sidetone                                        
++ * nomadik_acodec_enable_sidetone
 + * @gain - sidetone gain in db
 + * @reserved1 - reserved for future use only.
 + * @reserved2 - reserved for future use only.
 + *
 + * This routine enables the side tone to be mixed with record
-+ * It is mot implemented yet.                               
++ * It is mot implemented yet.
 + */
 +t_codec_error nomadik_acodec_enable_sidetone(int gain, u_long * reserved1,
 +                                           u_long * reserved2, t_acodec_user user)
@@ -246948,7 +247708,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_disable_sidetone - diables the side tone                            
++ * nomadik_acodec_disable_sidetone - diables the side tone
 + */
 +t_codec_error nomadik_acodec_disable_sidetone(t_acodec_user user)
 +{
@@ -246979,11 +247739,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_select_input                                       
++ * nomadik_acodec_select_input
 + * @input_device: MIC or linein.
 + *
-+ * This routine selects the input device mic or linein.                             
-+ */  
++ * This routine selects the input device mic or linein.
++ */
 +t_codec_error nomadik_acodec_select_input(t_codec_input_select input_device, t_acodec_user user)
 +{
 +
@@ -247030,10 +247790,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_select_output                                       
++ * nomadik_acodec_select_output
 + * @output_device: output device HP/LSP
 + *
-+ * This routine selects the output device Headphone or loud speaker                   
++ * This routine selects the output device Headphone or loud speaker
 + */
 +t_codec_error nomadik_acodec_select_output(t_codec_output_select output_device, t_acodec_user user)
 +{
@@ -247081,10 +247841,10 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_get_minvolume                                       
++ * nomadik_acodec_get_minvolume
 + * @input_min_vol - minimum volume supported by acodec for recording
 + * @output_min_vol - minimum volume supported by acodec for playback
-+ *                                                                          
++ *
 + * This routine returns the minimum volume possible for audiocodec                     */
 +t_codec_error nomadik_acodec_get_minvolume(__u8 * input_min_vol,
 +                                         __u8 * output_min_vol)
@@ -247103,11 +247863,11 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_get_maxvolume                                          
++ * nomadik_acodec_get_maxvolume
 + * @input_max_vol - maximum volume supported by acodec for recording
 + * @output_max_vol - maximum volume supported by acodec for playback
 + *
-+ * This routine returns the maximum volume possible for audiocodec                    
++ * This routine returns the maximum volume possible for audiocodec
 + */
 +t_codec_error nomadik_acodec_get_maxvolume(__u8 * input_max_vol,
 +                                         __u8 * output_max_vol)
@@ -247127,12 +247887,12 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/*
-+ * nomadik_acodec_set_frequency                                       
++ * nomadik_acodec_set_frequency
 + * @direction - in/out direction form audiocodec
 + * @record_sample_frequency - record frequency
 + * @play_sample_frequency: playback frequency
-+ *        
-+ * This routine sets the freuency for audio codec and MSP                     
++ *
++ * This routine sets the freuency for audio codec and MSP
 + */
 +t_codec_error nomadik_acodec_set_frequency(t_codec_direction direction,
 +                                         t_codec_sample_frequency
@@ -247239,9 +247999,9 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_get_currentsettings                                       
-+ *                                                                         
-+ * This routine returns the codec_configuration structure                        
++ * nomadik_acodec_get_currentsettings
++ *
++ * This routine returns the codec_configuration structure
 + */
 +t_codec_error nomadik_acodec_get_currentsettings(codec_configuration *
 +                                               codec_conf, t_acodec_user user)
@@ -247268,9 +248028,9 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/**
-+ * nomadik_acodec_set_currentsettings 
-+ *                                      
-+ * This routine sets the codec_configuration structure    
++ * nomadik_acodec_set_currentsettings
++ *
++ * This routine sets the codec_configuration structure
 + */
 +t_codec_error nomadik_acodec_set_currentsettings(codec_configuration *
 +                                               codec_conf, t_acodec_user user)
@@ -247293,7 +248053,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +}
 +
 +/*******************************************************************************
-+ * private functions 
++ * private functions
 + ******************************************************************************/
 +
 +/* Calculate F1 or F2 from frequency given for DTMF tone generation */
@@ -247426,9 +248186,9 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +      return vol;
 +}
 +
-+ /* This routine calculates the OCK clock frequency depending on 
-+     sample frequency given by user. 
-+ */                              
++ /* This routine calculates the OCK clock frequency depending on
++     sample frequency given by user.
++ */
 +t_codec_error set_ock_frequency(t_codec_sample_frequency frequency)
 +{
 +
@@ -247550,7 +248310,7 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +
 +/**
 + * nomadik_acodec_reset
-+ *                                      
++ *
 + * Reset the global variables and clear audiocodec settings to default.
 + */
 +t_codec_error reset_nomadik_acodec(void)
@@ -247613,9 +248373,8 @@ diff -Nauprw linux-2.6.20/sound/nomadik_stw5094.c ../new/linux-2.6.20/sound/noma
 +EXPORT_SYMBOL(nomadik_acodec_disable_tonegeneratormode);
 +EXPORT_SYMBOL(nomadik_acodec_get_currentsettings);
 +EXPORT_SYMBOL(nomadik_acodec_set_currentsettings);
-diff -Nauprw linux-2.6.20/sound/nomadik_stw5095.c ../new/linux-2.6.20/sound/nomadik_stw5095.c
---- linux-2.6.20/sound/nomadik_stw5095.c       1970-01-01 05:30:00.000000000 +0530
-+++ ../new/linux-2.6.20/sound/nomadik_stw5095.c        2008-11-24 14:06:29.000000000 +0530
+--- /dev/null
++++ linux-2.6.20/sound/nomadik_stw5095.c
 @@ -0,0 +1,3529 @@
 +/* sound/nomadik_stw5095.c
 + *
index 45b3a32..8c1d3bb 100644 (file)
@@ -1,6 +1,12 @@
---- linux-2.6.20/sound/nomadik_stw5095.c       2008-12-02 19:24:57.059205000 +0530
-+++ ../new/linux-2.6.20/sound/nomadik_stw5095.c        2008-12-04 10:41:34.474339000 +0530
-@@ -2577,13 +2577,65 @@ t_codec_error nomadik_acodec_powerup(voi
+---
+ sound/nomadik_stw5095.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 53 insertions(+), 1 deletion(-)
+
+--- linux-2.6.20.orig/sound/nomadik_stw5095.c
++++ linux-2.6.20/sound/nomadik_stw5095.c
+@@ -2575,17 +2575,69 @@ t_codec_error nomadik_acodec_powerdown(_
+ t_codec_error nomadik_acodec_powerup(void)
  {
        t_codec_error error_status = CODEC_OK;
  
@@ -16,7 +22,7 @@
 +      error_status = codec_stw5095_update_cr0();
 +      if (CODEC_OK != error_status)
 +              return (error_status);
-+      
++
 +      //CR2 conf
 +      codec_stw5095_i2cwrite(CODEC_STW5095_CR2, 0x0);
 +      //CR19 conf
@@ -34,7 +40,7 @@
 +      //CR0 conf
        g_codec_system_context.codec_configuration.cr0_powerup =
            CODEC_STW5095_CR0_POWERUP_ON;
-+      
++
        error_status = codec_stw5095_update_cr0();
 +      if (CODEC_OK != error_status)
 +              return (error_status);
@@ -67,3 +73,5 @@
        return (error_status);
  }
  
+ /**
+ * nomadik_acodec_enable_bypassmode
index c6d4b89..b48134c 100644 (file)
@@ -1,6 +1,12 @@
---- linux-2.6.20/sound/nomadik_stw5095.c       2008-11-26 18:36:04.000000000 +0530
-+++ ../new/linux-2.6.20/sound/nomadik_stw5095.c        2008-12-02 19:24:57.059205000 +0530
-@@ -1993,6 +1993,16 @@ t_codec_error nomadik_acodec_enable_audi
+---
+ sound/nomadik_stw5095.c |   42 +++++++++++++++++++++++++++++++-----------
+ 1 file changed, 31 insertions(+), 11 deletions(-)
+
+--- linux-2.6.20.orig/sound/nomadik_stw5095.c
++++ linux-2.6.20/sound/nomadik_stw5095.c
+@@ -1991,10 +1991,20 @@ t_codec_error nomadik_acodec_enable_audi
+                       return CODEC_ERROR;
+               }
  
        break;
        case 0:
                codec_error = nomadik_acodec_select_output(CODEC_DEST_LOUDSPEAKER,user);
                if (CODEC_OK != codec_error) {
                        printk("AUDIOCODEC: ERROR: select output failed\n");
-@@ -2222,6 +2232,16 @@ t_codec_error nomadik_acodec_enable_voic
+                       return CODEC_ERROR;
+               }
+@@ -2220,10 +2230,20 @@ t_codec_error nomadik_acodec_enable_voic
+                       return CODEC_ERROR;
+               }
  
        break;
        case 0:
                codec_error = nomadik_acodec_select_output(CODEC_DEST_LOUDSPEAKER,user);
                if (CODEC_OK != codec_error) {
                        printk("AUDIOCODEC: ERROR: select output failed\n");
-@@ -2525,11 +2545,22 @@ t_codec_error nomadik_acodec_set_volume(
+                       return CODEC_ERROR;
+               }
+@@ -2523,15 +2543,26 @@ t_codec_error nomadik_acodec_set_volume(
+ * will be achieved in power management
+ */
  
  t_codec_error nomadik_acodec_powerdown(__u8 flag)
  {
  
        DEBUG(1, "leaving nomadik_acodec_powerdown() \n");
        return (error_status);
-@@ -3345,17 +3376,6 @@ static void codec_callback1(void *user)
+ }
+@@ -3343,21 +3374,10 @@ static void codec_callback1(void *user)
+ }
+ /*initialize the 5095 codec's amplifier */
  void codec_hd_amp_init(t_acodec_user user)
  {
        int err = 0;
@@ -75,3 +93,5 @@
        /**/
        err = STMPE2401_SetGpioAltFunction(STMPE0,EGPIO_PIN_7,STMPE2401_PRIMARY_FUNCTION);
        if (err != STMPE2401_OK)
+                 printk("Couldn't set STMPE0 %d as  primary function\n",EGPIO_PIN_7);
index d46c623..21680fb 100644 (file)
@@ -6,7 +6,7 @@ DEFAULT_PREFERENCE_at91sam9261ek = "20"
 DEFAULT_PREFERENCE_at91sam9260ek = "20"
 DEFAULT_PREFERENCE_nhk15 = "1"
 
-PR = "r10"
+PR = "r11"
 
 SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \
            ${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/patch-${PV}.21.bz2;patch=1 \
@@ -37,7 +37,6 @@ SRC_URI_append_nhk15 = " \
                file://linux-2.6.20_01_dec_2.patch;patch=1 \
                file://patch_classdamp_pm_v_audio_codec_patch.patch;patch=1 \
                file://patch_audiocodec_glitch.patch;patch=1 \
-                file://0001-kbuild-include-limits.h-in-sumversion.c-for-path_max.patch;patch=1 \
                file://hrw-saa-fix.diff;patch=1 \
                file://hrw-make-create-kconfig-executable.patch;patch=1 \
 "