From 0128a20973f6dc22bbb180b6b4736c3bbf390890 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Thu, 11 Feb 2010 10:59:37 +0100 Subject: linux 2.6.20: refreshed NHK-15 patches to build after stable update Signed-off-by: Marcin Juszkiewicz --- ...ude-limits.h-in-sumversion.c-for-path_max.patch | 29 - .../nhk15/audio_codec_patch_base_v5.6.0.patch | 53 +- .../nhk15/hrw-make-create-kconfig-executable.patch | 2 +- .../linux-2.6.20/nhk15/linux-2.6.20_01_dec_2.patch | 1203 +- .../nhk15/nomadik_baseline_linux_2620.patch | 71835 ++++++++++--------- .../nhk15/patch_audiocodec_glitch.patch | 18 +- .../patch_classdamp_pm_v_audio_codec_patch.patch | 32 +- recipes/linux/linux_2.6.20.bb | 3 +- 8 files changed, 37336 insertions(+), 35839 deletions(-) delete mode 100644 recipes/linux/linux-2.6.20/nhk15/0001-kbuild-include-limits.h-in-sumversion.c-for-path_max.patch 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 index 4871601c97..0000000000 --- a/recipes/linux/linux-2.6.20/nhk15/0001-kbuild-include-limits.h-in-sumversion.c-for-path_max.patch +++ /dev/null @@ -1,29 +0,0 @@ -From fc31c7716355a226b8ed4e16f4581e5c8fa53570 Mon Sep 17 00:00:00 2001 -From: Mike Frysinger -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 -Signed-off-by: Sam Ravnborg ---- - 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 - #include - #include -+#include - #include "modpost.h" - - /* --- -1.6.3.3 - diff --git a/recipes/linux/linux-2.6.20/nhk15/audio_codec_patch_base_v5.6.0.patch b/recipes/linux/linux-2.6.20/nhk15/audio_codec_patch_base_v5.6.0.patch index 1a7bd9e836..5b9c187fbc 100644 --- a/recipes/linux/linux-2.6.20/nhk15/audio_codec_patch_base_v5.6.0.patch +++ b/recipes/linux/linux-2.6.20/nhk15/audio_codec_patch_base_v5.6.0.patch @@ -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); diff --git a/recipes/linux/linux-2.6.20/nhk15/hrw-make-create-kconfig-executable.patch b/recipes/linux/linux-2.6.20/nhk15/hrw-make-create-kconfig-executable.patch index 7a2ccae78e..8cb13ba2f0 100644 --- a/recipes/linux/linux-2.6.20/nhk15/hrw-make-create-kconfig-executable.patch +++ b/recipes/linux/linux-2.6.20/nhk15/hrw-make-create-kconfig-executable.patch @@ -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 diff --git a/recipes/linux/linux-2.6.20/nhk15/linux-2.6.20_01_dec_2.patch b/recipes/linux/linux-2.6.20/nhk15/linux-2.6.20_01_dec_2.patch index 4876337dfd..62be30a268 100644 --- a/recipes/linux/linux-2.6.20/nhk15/linux-2.6.20_01_dec_2.patch +++ b/recipes/linux/linux-2.6.20/nhk15/linux-2.6.20_01_dec_2.patch @@ -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 + #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); diff --git a/recipes/linux/linux-2.6.20/nhk15/nomadik_baseline_linux_2620.patch b/recipes/linux/linux-2.6.20/nhk15/nomadik_baseline_linux_2620.patch index 40c9c43ac2..7ee8bb8af6 100644 --- a/recipes/linux/linux-2.6.20/nhk15/nomadik_baseline_linux_2620.patch +++ b/recipes/linux/linux-2.6.20/nhk15/nomadik_baseline_linux_2620.patch @@ -1,1314 +1,2456 @@ -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 @@ ++ ++ + -+# -+# Code maturity level options -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_LOCK_KERNEL=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 ++ ++ ++ KGDB Internals + -+# -+# 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 ++ ++ ++ Tom ++ Rini ++ ++
++ trini@kernel.crashing.org ++
++
++
++
+ -+# -+# 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 ++ ++ ++ Amit S. ++ Kale ++ ++
++ amitkale@linsyssoft.com ++
++
++
++
+ -+# -+# Block layer -+# -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set ++ ++ 2004-2005 ++ MontaVista Software, Inc. ++ ++ ++ 2004 ++ Amit S. Kale ++ + -+# -+# 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" ++ ++ ++ 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. ++ + -+# -+# 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 ++ ++
+ -+# -+# 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 ++ ++ ++ Introduction ++ ++ 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. ++ ++ ++ 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. ++ ++ ++ ++ Compiling a kernel ++ ++ To enable CONFIG_KGDB, look under the "Kernel debugging" ++ and then select "KGDB: kernel debugging with remote gdb". ++ ++ ++ The first choice for I/O is CONFIG_KGDB_ONLY_MODULES. ++ 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. ++ ++ The first of these is CONFIG_KGDB_8250_NOMODULE. ++ This has sub-options such as CONFIG_KGDB_SIMPLE_SERIAL ++ which toggles choosing the serial port by ttyS number or by specifying ++ a port and IRQ number. ++ ++ ++ The second of these choices on most systems for I/O is ++ CONFIG_KGDBOE. This requires that the machine to be ++ debugged has an ethernet card which supports the netpoll API, such as ++ the cards supported by CONFIG_E100. There are no ++ sub-options for this, but a kernel command line option is required. ++ ++ ++ ++ Booting the kernel ++ ++ The Kernel command line option kgdbwait makes kgdb ++ wait for gdb connection during booting of a kernel. If the ++ CONFIG_KGDB_8250 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 CONFIG_KGDB_8250 and ++ CONFIG_KGDB_SIMPLE_SERIAL then you must pass the option ++ kgdb8250=<io or mmio>,<address>,<baud ++ rate>,<irq> before kgdbwait. ++ The values io or mmio refer to ++ if the address being passed next needs to be memory mapped ++ (mmio) or not. The address must ++ be passed in hex and is the hardware address and will be remapped if ++ passed as mmio. The value ++ baud rate and irq are base-10. ++ The supported values for baud rate are ++ 9600, 19200, ++ 38400, 57600, and ++ 115200. ++ ++ ++ To have KGDB stop the kernel and wait, with the compiled values for the ++ serial driver, pass in: kgdbwait. ++ ++ ++ To specify the values of the serial port at boot: ++ kgdb8250=io,3f8,115200,3. ++ On IA64 this could also be: ++ kgdb8250=mmio,0xff5e0000,115200,74 ++ And to have KGDB also stop the kernel and wait for GDB to connect, pass in ++ kgdbwait after this arguement. ++ ++ ++ To configure the CONFIG_KGDBOE driver, pass in ++ kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr] ++ where: ++ ++ src-port (optional): source for UDP packets (defaults to 6443) ++ src-ip: source IP to use (interface address) ++ dev (optional): network interface (eth0) ++ tgt-port (optional): port GDB will use (defaults to 6442) ++ tgt-ip: IP address GDB will be connecting from ++ tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast) ++ ++ ++ ++ The CONFIG_KGDBOE driver can be reconfigured at run ++ time, if CONFIG_SYSFS and ++ CONFIG_MODULES by echo'ing a new config string to ++ /sys/module/kgdboe/parameter/kgdboe. The ++ driver can be unconfigured with the special string ++ not_configured. ++ ++ ++ ++ Connecting gdb ++ ++ 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. ++ ++ ++ Example (serial): ++ ++ ++ % gdb ./vmlinux ++ (gdb) set remotebaud 115200 ++ (gdb) target remote /dev/ttyS0 ++ ++ ++ Example (ethernet): ++ ++ ++ % gdb ./vmlinux ++ (gdb) target remote udp:192.168.2.2:6443 ++ ++ ++ Once connected, you can debug a kernel the way you would debug an ++ application program. ++ ++ ++ ++ The common backend (required) ++ ++ There are a few flags which must be set on every architecture in ++ their <asm/kgdb.h> file. These are: ++ ++ ++ ++ NUMREGBYTES: The size in bytes of all of the registers, so ++ that we can ensure they will all fit into a packet. ++ ++ ++ BUFMAX: The size in bytes of the buffer GDB will read into. ++ This must be larger than NUMREGBYTES. ++ ++ ++ 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. ++ ++ ++ ++ ++ ++ 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. ++ ++!Iinclude/linux/kgdb.h ++ ++ ++ The common backend (optional) ++ ++ 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. ++ ++!Ikernel/kgdb.c ++ ++ ++ Driver-Specific Functions ++ ++ 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. ++ ++!Idrivers/serial/8250_kgdb.c ++ ++
+--- /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 .c/h ++ (ex. gpio.h, msp.c) ++4. all Nomadik platform specific files are named as _.c/h ++ (ex. ndk10_devices.c, ndk15_devices.h) ++5. all Nomadik soc specific files are named as _.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 _devices.c through device specific interface. ++3. A Nomadik chip specific code for all supported driver will be refered from a ++ single file _devices.c through device specific interface. ++4. Each device specific header file _devices.h and ++ _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 ++ ++5. Each header file described here should have relevent declaration related to ++ the scope of its usage. ex. _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/_devices.c ++ inclue/asm-arm/arch-nomadik/_devices.h ++ arch/arch/mach-nomadik/_devices.c ++ inclue/asm-arm/arch-nomadik/_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/_Kconfig ++ arch/arch/mach-nomadik/_devices.c ++ inclue/asm-arm/arch0-nomadik/_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/_Kconfig file for board ++ configuration, 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 _Kconfig files and Kconfig_nomadik file. ++ 1. _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/_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/_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=://ramdisk ++ip=:::255.255.255.0:nomadik:: console=ttyAMA1 mac= 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 _DEBUG ++ * CFLAGS += -_DEBUG=$(_DEBUG) ++ * endif ++ * ++ * (b) Same _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 _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 _DEBUG=1 _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 + -+# -+# 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/_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 ++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/_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=:,tcp ++ ip=:::255.255.255.0::: ++ 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 _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 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 _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 /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 ++ 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 ++ * 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 . ++ ++ 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 . ++# ++# 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 - #include - #include - #include -@@ -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 -+ * Deepak Saxena -+ */ -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++# ++# 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++# ++# 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 -+ * -+ * 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 ++# ++# 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++# ++# 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 -+#include -+#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 + #include + #include + #include + #include + #include +@@ -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 ++ * ++ * 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 + -+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 ++ * Deepak Saxena + */ -+#include ++//#include +#include +#include -+#include -+#include ++#include +#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include +#include ++#include + -+#include ++#include +#include -+#include -+#include -+#include -+ -+#include -+ -+#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 ++#include ++#include ++#include ++#include ++#include + -+/* -+ * 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 \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/_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 -+#include ++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 -+ */ -+#define DMA_VER "2.1.0" ++# Auto board configuration/dependency resolution ++#include $(TOPDIR)/.config + -+#include /* module functions */ -+#include -+#include -+#include -+#include /* For wait queues */ -+#include -+#include -+#include /* spinlocks */ -+#include /* err nos */ -+#include /* wait macros */ -+#include /* GFP flags */ -+#include /* Amba device register */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* for cli etc */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ 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 ++#include ++#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<eicr |= 1UL<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<eicr |= 1UL<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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ nmdk_dbg_ftrace(); -+ dmaconfig_config(dma) = 0; ++#include ++#include ++#include ++#include ++#include + -+ 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 + -+/** -+ * 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 \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/_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 ++#include + -+ 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ /* 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ 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 "); -+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 -+ * Reference : Documentation/arm/STM-Nomadik/irq_usrguide.txt -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ 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<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<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<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<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<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<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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++wait_till_normal_mode: ++ ldr r0,[r8, #0x0] ++ and r0,r0,#0x78 ++ cmp r0, #0x20 ++ bne wait_till_normal_mode + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include + ++#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 ++ */ ++#define DMA_VER "2.1.0" + -+ifdef SSP_DEBUG -+NMDKDBG_FLAGS += -DSSP_DEBUG=$(SSP_DEBUG) -+endif ++#include /* module functions */ ++#include ++#include ++#include ++#include /* For wait queues */ ++#include ++#include ++#include /* spinlocks */ ++#include /* err nos */ ++#include /* wait macros */ ++#include /* GFP flags */ ++#include /* Amba device register */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for cli etc */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#if (defined(CONFIG_NOMADIK_SPI) || defined(CONFIG_NOMADIK_SPI_MODULE)) -+#include -+#include -+#endif -+ -+#include -+ -+#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<eicr |= 1UL<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<eicr |= 1UL<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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 ++ * Reference : Documentation/arm/STM-Nomadik/irq_usrguide.txt + */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#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<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<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<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<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<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<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 -+ * -+ * 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 ++#include +#include +#include -+#include -+#include -+#include -+#include ++#include +#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#include -+#include +#include +#include -+ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include +#include -+#include -+#include ++#include + -+#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+/*************************************************************** -+ * 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 ++#include ++#include ++#include + -+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 ++#include ++#include ++#include ++#include + -+ 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 ++#include ++#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 + -+ 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_MTD -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+#include ++ /* 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_MTD -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+#include -+ -+#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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include + -+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 ++#include ++#include ++#include ++ ++#include ++#include ++#include + ++#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 +#include @@ -16303,6 +16344,166 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/ndk15_devices.c ../new/linux-2.6 +#endif +#include + ++/* ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_MTD ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++#include ++ ++#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 +#include @@ -17480,11 +18737,6 @@ diff -Nauprw linux-2.6.20/arch/arm/mach-nomadik/nhk15_devices.c ../new/linux-2.6 +#include +#endif +#include -+#include -+#include -+ -+#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<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;iboard->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;iboard->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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_MTD ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++#include ++#include ++#include + -+#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<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;iboard->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 "); +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, "); +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 -+#include - #include - - 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 ++#include + #include + + 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 #include -@@ -33,6 +37,7 @@ + #include + #include + #include #include #include #include @@ -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 _DEBUG -+ * CFLAGS += -_DEBUG=$(_DEBUG) -+ * endif -+ * -+ * (b) Same _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 _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 _DEBUG=1 _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 + # 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 ++ Copyright (c) 2008 Nicholas Angelo Crespi + -+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 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ -------------------- -+ 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/_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 -+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/_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=:,tcp -+ ip=:::255.255.255.0::: -+ 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 "); ++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 . + + 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 _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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "i2c-nomadik.h" ++#include ++#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 .c/h -+ (ex. gpio.h, msp.c) -+4. all Nomadik platform specific files are named as _.c/h -+ (ex. ndk10_devices.c, ndk15_devices.h) -+5. all Nomadik soc specific files are named as _.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 _devices.c through device specific interface. -+3. A Nomadik chip specific code for all supported driver will be refered from a -+ single file _devices.c through device specific interface. -+4. Each device specific header file _devices.h and -+ _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 -+ -+5. Each header file described here should have relevent declaration related to -+ the scope of its usage. ex. _devices.h should only have -+ platforms specific declration. ++}; ++#endif + -+Any Nomadik target can be supported by following set of files:- -+ arch/arch/mach-nomadik/_devices.c -+ inclue/asm-arm/arch-nomadik/_devices.h -+ arch/arch/mach-nomadik/_devices.c -+ inclue/asm-arm/arch-nomadik/_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/_Kconfig -+ arch/arch/mach-nomadik/_devices.c -+ inclue/asm-arm/arch0-nomadik/_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/_Kconfig file for board -+ configuration, 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 _Kconfig files and Kconfig_nomadik file. -+ 1. _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/_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/_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=://ramdisk -+ip=:::255.255.255.0:nomadik:: console=ttyAMA1 mac= 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 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 _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 /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 -+ 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 -+ * 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 @@ -+ -+ ++ if (i2c_initialize(priv)) { ++ up(&nomadik_i2c[bus_id].lock); ++ return -EINVAL; ++ } + -+ -+ -+ KGDB Internals ++ if (verify_parameters(priv)) { ++ error("Error in parameters\n"); ++ up(&nomadik_i2c[bus_id].lock); ++ return -EINVAL; ++ } + -+ -+ -+ Tom -+ Rini -+ -+
-+ trini@kernel.crashing.org -+
-+
-+
-+
++ 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) { + -+ -+ -+ Amit S. -+ Kale -+ -+
-+ amitkale@linsyssoft.com -+
-+
-+
-+
++ 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); + -+ -+ 2004-2005 -+ MontaVista Software, Inc. -+ -+ -+ 2004 -+ Amit S. Kale -+ ++ } 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) { + -+ -+ -+ 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. -+ ++ 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; ++} + -+ -+ -+ Introduction -+ -+ 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. -+ -+ -+ 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. -+ -+ -+ -+ Compiling a kernel -+ -+ To enable CONFIG_KGDB, look under the "Kernel debugging" -+ and then select "KGDB: kernel debugging with remote gdb". -+ -+ -+ The first choice for I/O is CONFIG_KGDB_ONLY_MODULES. -+ 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. -+ -+ The first of these is CONFIG_KGDB_8250_NOMODULE. -+ This has sub-options such as CONFIG_KGDB_SIMPLE_SERIAL -+ which toggles choosing the serial port by ttyS number or by specifying -+ a port and IRQ number. -+ -+ -+ The second of these choices on most systems for I/O is -+ CONFIG_KGDBOE. This requires that the machine to be -+ debugged has an ethernet card which supports the netpoll API, such as -+ the cards supported by CONFIG_E100. There are no -+ sub-options for this, but a kernel command line option is required. -+ -+ -+ -+ Booting the kernel -+ -+ The Kernel command line option kgdbwait makes kgdb -+ wait for gdb connection during booting of a kernel. If the -+ CONFIG_KGDB_8250 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 CONFIG_KGDB_8250 and -+ CONFIG_KGDB_SIMPLE_SERIAL then you must pass the option -+ kgdb8250=<io or mmio>,<address>,<baud -+ rate>,<irq> before kgdbwait. -+ The values io or mmio refer to -+ if the address being passed next needs to be memory mapped -+ (mmio) or not. The address must -+ be passed in hex and is the hardware address and will be remapped if -+ passed as mmio. The value -+ baud rate and irq are base-10. -+ The supported values for baud rate are -+ 9600, 19200, -+ 38400, 57600, and -+ 115200. -+ -+ -+ To have KGDB stop the kernel and wait, with the compiled values for the -+ serial driver, pass in: kgdbwait. -+ -+ -+ To specify the values of the serial port at boot: -+ kgdb8250=io,3f8,115200,3. -+ On IA64 this could also be: -+ kgdb8250=mmio,0xff5e0000,115200,74 -+ And to have KGDB also stop the kernel and wait for GDB to connect, pass in -+ kgdbwait after this arguement. -+ -+ -+ To configure the CONFIG_KGDBOE driver, pass in -+ kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr] -+ where: -+ -+ src-port (optional): source for UDP packets (defaults to 6443) -+ src-ip: source IP to use (interface address) -+ dev (optional): network interface (eth0) -+ tgt-port (optional): port GDB will use (defaults to 6442) -+ tgt-ip: IP address GDB will be connecting from -+ tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast) -+ -+ -+ -+ The CONFIG_KGDBOE driver can be reconfigured at run -+ time, if CONFIG_SYSFS and -+ CONFIG_MODULES by echo'ing a new config string to -+ /sys/module/kgdboe/parameter/kgdboe. The -+ driver can be unconfigured with the special string -+ not_configured. -+ -+ -+ -+ Connecting gdb -+ -+ 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. -+ -+ -+ Example (serial): -+ -+ -+ % gdb ./vmlinux -+ (gdb) set remotebaud 115200 -+ (gdb) target remote /dev/ttyS0 -+ -+ -+ Example (ethernet): -+ -+ -+ % gdb ./vmlinux -+ (gdb) target remote udp:192.168.2.2:6443 -+ -+ -+ Once connected, you can debug a kernel the way you would debug an -+ application program. -+ -+ -+ -+ The common backend (required) -+ -+ There are a few flags which must be set on every architecture in -+ their <asm/kgdb.h> file. These are: -+ -+ -+ -+ NUMREGBYTES: The size in bytes of all of the registers, so -+ that we can ensure they will all fit into a packet. -+ -+ -+ BUFMAX: The size in bytes of the buffer GDB will read into. -+ This must be larger than NUMREGBYTES. -+ -+ -+ 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. -+ -+ -+ -+ -+ -+ 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. -+ -+!Iinclude/linux/kgdb.h -+ -+ -+ The common backend (optional) -+ -+ 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. -+ -+!Ikernel/kgdb.c -+ -+ -+ Driver-Specific Functions -+ -+ 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. -+ -+!Idrivers/serial/8250_kgdb.c -+ -+
-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 ++ 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 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ 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 ++#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 ++#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 "); -+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 ++ *----------------------------------------------------------------------------- + */ + ++ +#include +#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ +#include "i2c-nomadik.h" -+#include -+#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 + -+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 -+#endif -+ -+#ifndef I2C_NOMADIC_HEADER -+#include -+#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 -+ *----------------------------------------------------------------------------- -+ */ -+ -+ -+#include -+#include -+ -+#include "i2c-nomadik.h" -+#include -+ -+#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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 , 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 . */ -+/*---------------------------------------------------------------------------*/ -+ -+/*--------------------------------------------------------------------------* -+ * 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; iparams[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; iparams[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; iparams[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; iblock_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; iblock_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; iblock_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; iblock_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 . */ ++/*---------------------------------------------------------------------------*/ ++ ++/*--------------------------------------------------------------------------* ++ * 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; iparams[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; iparams[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; iparams[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; iblock_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; iblock_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; iblock_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; iblock_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 . */ -+/*---------------------------------------------------------------------------*/ -+ -+#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 . */ ++/*---------------------------------------------------------------------------*/ ++ ++#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 . */ ++/*---------------------------------------------------------------------------*/ ++ ++#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 . */ -+/*---------------------------------------------------------------------------*/ -+ -+#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 . */ -+/*---------------------------------------------------------------------------*/ -+ -+#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 . */ ++/*---------------------------------------------------------------------------*/ ++ ++#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 . */ ++/*---------------------------------------------------------------------------*/ +\ 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 . */ -+/*---------------------------------------------------------------------------*/ -\ 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 . */ -+/*---------------------------------------------------------------------------*/ -+ -+#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 . */ ++/*---------------------------------------------------------------------------*/ ++ ++#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 . */ +/*---------------------------------------------------------------------------*/ + -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 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ @@ -144190,9 +144859,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.c ../new/linux-2.6 + +module_init(nomadik_ogles_init); +module_exit(nomadik_ogles_exit); -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 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ @@ -144259,9 +144927,8 @@ diff -Nauprw linux-2.6.20/drivers/media/nomadik_mm/opengl/ogl.h ../new/linux-2.6 +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jayarami reddy "); +MODULE_DESCRIPTION(" This module is a OGLES module !!"); -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 @@ +/*---------------------------------------------------------------------------*/ +/* © copyright STMicroelectronics, 2007. All rights reserved. For */ @@ -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 !!"); + +#endif //OGL_IOCTL_H -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 . */ +/*--------------------------------------------------------------------------------------------------*/ + -+#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 "); + + -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 "); + + -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 + . + + 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 @@ +/* + * Overview: @@ -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); +module_exit(nomadik_stcharg_exit); + -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 +#include + -+#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 and + */ + 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 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<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 +#include + -+#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 . @@ -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 +- . ++ + ++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 + #include #include #include #include @@ -185504,7 +186260,11 @@ diff -Nauprw linux-2.6.20/drivers/mtd/onenand/generic.c ../new/linux-2.6.20/driv #include #include -@@ -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 -- . -+ - -+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 "); 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 -@@ -17,8 +22,8 @@ + #include #include #include @@ -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 -+#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 "); ++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 ++ * and Scott Foehner ++ * ++ * Maintainers: Amit S. Kale and ++ * Tom Rini ++ * ++ * 2004 (c) Amit S. Kale ++ * 2004-2005 (c) MontaVista Software, Inc. ++ * 2005 (c) Wind River Systems, Inc. ++ * ++ * Contributors at various stages not listed above: ++ * San Mehat , Robert Walsh , ++ * wangdi , Matt Mackall , ++ * Pavel Machek , Jason Wessel ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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]@/\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]@/\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 + #include + #include + #include + #include +@@ -88,10 +88,12 @@ static const char version[] = + + #include + + #include "smc91x.h" + ++#include ++ + #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 ++ ++#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 + #include + + #include + #include ++#include ++#include + +-#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 ++ * Vaibhav Agarwal ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/***************************************************************************/ ++ ++#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 : Vaibhav Agarwal 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 + -+#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 + -+ default: -+ break; -+ } ++#include ++#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: ++ *
    ++ *
  • A DMA controller will be tied to an Inventra USB core in the ++ * way specified in the Inventra core product specification. ++ *
  • A DMA controller's base address in the memory map correlates ++ * somehow to the Inventra USB core it serves. ++ *
++ * The responsibilities of an implementation include: ++ *
    ++ *
  • 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) ++ *
  • Handling the details of moving multiple USB packets ++ * in cooperation with the Inventra USB core. ++ *
  • Knowing the correlation between channels and the ++ * Inventra core's local endpoint resources and data direction, ++ * and maintaining a list of allocated/available channels. ++ *
  • Updating channel status on interrupts, ++ * whether shared with the Inventra core or separate. ++ *
  • If the DMA interrupt is shared with the Inventra core, ++ * handling it when called, and reporting whether it was the ++ * source of interrupt. ++ *
++ */ ++ ++/*************************** 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 ++#include ++#include ++#include + -+ 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 ++#include ++#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 "); -+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 -+ * and Scott Foehner -+ * -+ * Maintainers: Amit S. Kale and -+ * Tom Rini ++/** ++ * Forward a request to the driver. + * -+ * 2004 (c) Amit S. Kale -+ * 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 , Robert Walsh , -+ * wangdi , Matt Mackall , -+ * Pavel Machek , Jason Wessel ++ * 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 -+#include -+#include -+#include -+#include -+#include + -+#include ++ 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]@/\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]@/\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 - #include - #include -@@ -90,6 +90,8 @@ static const char version[] = - - #include "smc91x.h" - -+#include ++ 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 ++ 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 - #include -+#include -+#include - --#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 -+ * Vaibhav Agarwal -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include + ++#include "musbdefs.h" +#include -+#include -+#include -+#include + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#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 ++#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 + -+ 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 ++#include ++#include ++#include + -+ nmdk_dbg_ftrace(); ++#include + -+#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<= 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 : Vaibhav Agarwal 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 ++#define MUSB_EPD_AUTOCONFIG 0 + -+#include -+#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; bEndaLocalEnd[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: -+ *
    -+ *
  • A DMA controller will be tied to an Inventra USB core in the -+ * way specified in the Inventra core product specification. -+ *
  • A DMA controller's base address in the memory map correlates -+ * somehow to the Inventra USB core it serves. -+ *
-+ * The responsibilities of an implementation include: -+ *
    -+ *
  • 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) -+ *
  • Handling the details of moving multiple USB packets -+ * in cooperation with the Inventra USB core. -+ *
  • Knowing the correlation between channels and the -+ * Inventra core's local endpoint resources and data direction, -+ * and maintaining a list of allocated/available channels. -+ *
  • Updating channel status on interrupts, -+ * whether shared with the Inventra core or separate. -+ *
  • If the DMA interrupt is shared with the Inventra core, -+ * handling it when called, and reporting whether it was the -+ * source of interrupt. -+ *
-+ */ ++ 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 -+#include -+#include -+#include -+ -+#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 -+#include -+#include "musbdefs.h" -+#include "musb_gadgetdefs.h" ++#include ++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(¬ify_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(¬ify_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 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#ifdef CONFIG_USB_DEBUG ++ #define DEBUG ++#else ++ #undef DEBUG ++#endif ++ ++#include + +#include "musbdefs.h" -+#include ++#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 ++#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; bEndaLocalEnd[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 ++ 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 -+#include -+#include -+#include ++ /* see if we are done */ ++ bDone = (pEnd->dwOffset >= pUrb->transfer_buffer_length) ++ || (wRxCount < pEnd->wPacketSize); + -+#include ++ 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<>= 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 -+#include -+#include -+#include ++ /* 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 -+#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; bEndaLocalEnd[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 -+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(¬ify_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(¬ify_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 ++#include + -+#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 ++ ++#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; ibEndCount; 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 ++ * 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 @@ -195420,7 +198744,6 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/dr +#include +#include +#include -+#include +#include +#include +#include @@ -195428,2875 +198751,2212 @@ diff -Nauprw linux-2.6.20/drivers/usb/nomadik/musb_host.c ../new/linux-2.6.20/dr +#include + +#ifdef CONFIG_USB_DEBUG -+ #define DEBUG ++#define DEBUG +#else -+ #undef DEBUG ++#undef DEBUG +#endif + -+#include + +#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 ++#include ++/********************** 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(¬ify_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; bEndaLocalEnd[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(¬ify_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(¬ify_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(¬ify_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(¬ify_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(¬ify_timer); ++notify_timer.expires = jiffies + msecs_to_jiffies(1000); ++notify_timer.function = funct_host_notify_timer; ++notify_timer.data = (unsigned long)pThis; ++add_timer(¬ify_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(¬ify_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(¬ify_timer, jiffies + msecs_to_jiffies(1000)); ++ } ++ else if (MUSB_IS_DEV(pThis)) { ++ del_timer(¬ify_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(¬ify_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(¬ify_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(¬ify_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 + -+#define MGC_MAX_USB_ENDS 16 ++#include ++#include + -+#define MGC_END0_FIFOSIZE 64 /* this is non-configurable */ ++#include ++#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 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 -+#include ++#if (MUSB_DEBUG>0) ++ /* read & write registers */ ++ case 'r': ++ case 'w': { ++ uint8_t index=0; ++ uint32_t value=0; ++ char command[64]; + -+#include ++ 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; ibEndCount; 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 ( offcount ) { ++ togo=count; ++ } ++ ++ while ( i++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 -+ * 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 +#include +#include +#include +#include +#include ++#include +#include -+#include -+#include ++#include ++#include + -+#include ++#include + -+#ifdef CONFIG_USB_DEBUG -+#define DEBUG ++#ifndef MUSB_LINUX_MV21 ++#include "../core/hcd.h" ++#define HAS_USB_TT_MULTI +#else -+#undef DEBUG ++#include +#endif + -+ +#include "musbdefs.h" -+#include "musb_host.h" -+#include "../core/hcd.h" -+#include -+#include -+/********************** 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(¬ify_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(¬ify_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(¬ify_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(¬ify_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(¬ify_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 ++#include ++#include + -+#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 ++#include ++#include ++#include + -+#ifdef MUSB_HOST -+ MGC_InitLocalEndPoints(pThis); ++#ifdef MUSB_CONFIG_PROC_FS ++#include +#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(¬ify_timer); -+notify_timer.expires = jiffies + msecs_to_jiffies(1000); -+notify_timer.function = funct_host_notify_timer; -+notify_timer.data = (unsigned long)pThis; -+add_timer(¬ify_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(¬ify_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(¬ify_timer, jiffies + msecs_to_jiffies(1000)); -+ } -+ else if (MUSB_IS_DEV(pThis)) { -+ del_timer(¬ify_timer); -+ } -+ else if (MUSB_IS_HST(pThis)) { -+ -+ del_timer(¬ify_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(¬ify_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(¬ify_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 -+ -+#include -+#include ++ 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 -+#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 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 ( offcount ) { -+ togo=count; -+ } -+ -+ while ( i++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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++/* ++ * HDRC-specific definitions ++ * $Revision: 1.8 $ ++ */ + -+#include ++#define MGC_MAX_USB_ENDS 16 + -+#ifndef MUSB_LINUX_MV21 -+#include "../core/hcd.h" -+#define HAS_USB_TT_MULTI -+#else -+#include -+#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 -+#include -+#include -+ -+#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 <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 <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 ( wcountlock); ++ ++#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 || wcountmaxpacket ) { ++ if ( reqptr->actual==reqptr->length || wcountmaxpacket ) { + 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<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 @@ -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 #include -@@ -24,18 +28,28 @@ + #include + #include +@@ -22,22 +26,32 @@ + #include + #include #include #include #include @@ -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, ®s); 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 . + * -+ * 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 . + * -+ * 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 . + * -+ * 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 . + * -+ * 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 . + * -+ * 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 . + 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 ++ . ++ ++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 -+ . -+ -+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 ++ * ++ * 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 -+ * -+ * 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 -+ * -+ * 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 -+ * -+ * 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 ++ * ++ * 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 ++ * ++ * 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 ++ ++ .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 -+ -+ .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 + -+#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 + +#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 -+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 -+ -+#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 ++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 ++ ++#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 @@ +/* + * linux/include/asm-arm/arch-nomadik/ndk10_devices.h @@ -233274,183 +234365,8 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk10_devices.h ../new/li + +#endif /*__ASSEMBLY__*/ +#endif /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/ -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 -+ -+/* -+ * 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 @@ +/* + * linux/include/asm-arm/arch-nomadik/ndk15_devices.h @@ -233700,9 +234616,181 @@ diff -Nauprw linux-2.6.20/include/asm-arm/arch-nomadik/ndk15_devices.h ../new/li + +#endif /*__ASSEMBLY__*/ +#endif /*__ASM_ARM_ARCH_NDK15_DEVICES_H*/ -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 ++ ++/* ++ * 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 +#include + -+/* ++/* + * 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 + +/*--------------------------------------------------------------------- -+ * 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 ++/* ++ * 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 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 (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 -+/* -+ * 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 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 (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 + * * Copyright (c) 2000-2005 * Thomas Gleixner * @@ -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 + #include #include #include #include @@ -242622,7 +243906,11 @@ diff -Nauprw linux-2.6.20/kernel/sched.c ../new/linux-2.6.20/kernel/sched.c #include #include -@@ -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 + #include #include #include #include @@ -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 + #include #include #include #include @@ -242666,7 +243964,11 @@ diff -Nauprw linux-2.6.20/kernel/timer.c ../new/linux-2.6.20/kernel/timer.c #include #include -@@ -1207,8 +1208,15 @@ static inline void update_times(unsigned + #include + #include +@@ -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 -- */ -- --#include --#include --#include --#include -- --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 +#include @@ -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 + * + * + */ -+ ++ +#include +#include +#include @@ -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 +#include @@ -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 @@ -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 + * diff --git a/recipes/linux/linux-2.6.20/nhk15/patch_audiocodec_glitch.patch b/recipes/linux/linux-2.6.20/nhk15/patch_audiocodec_glitch.patch index 45b3a325f6..8c1d3bbd47 100644 --- a/recipes/linux/linux-2.6.20/nhk15/patch_audiocodec_glitch.patch +++ b/recipes/linux/linux-2.6.20/nhk15/patch_audiocodec_glitch.patch @@ -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 diff --git a/recipes/linux/linux-2.6.20/nhk15/patch_classdamp_pm_v_audio_codec_patch.patch b/recipes/linux/linux-2.6.20/nhk15/patch_classdamp_pm_v_audio_codec_patch.patch index c6d4b89318..b48134cde1 100644 --- a/recipes/linux/linux-2.6.20/nhk15/patch_classdamp_pm_v_audio_codec_patch.patch +++ b/recipes/linux/linux-2.6.20/nhk15/patch_classdamp_pm_v_audio_codec_patch.patch @@ -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: @@ -17,7 +23,11 @@ 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: @@ -34,7 +44,11 @@ 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) { @@ -57,7 +71,11 @@ 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); + diff --git a/recipes/linux/linux_2.6.20.bb b/recipes/linux/linux_2.6.20.bb index d46c623e6b..21680fbda7 100644 --- a/recipes/linux/linux_2.6.20.bb +++ b/recipes/linux/linux_2.6.20.bb @@ -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 \ " -- cgit v1.2.3